`, styleAttr)
+ }
+
+ return ``
+ },
+ end: func(code bool) string {
+ if code {
+ return ``
+ }
+
+ return ``
+ },
+ }
+ }
+}
+
+// WithPreWrapper allows control of the surrounding pre tags.
+func WithPreWrapper(wrapper PreWrapper) Option {
+ return func(f *Formatter) {
+ f.preWrapper = wrapper
+ }
+}
+
+// WrapLongLines wraps long lines.
+func WrapLongLines(b bool) Option {
+ return func(f *Formatter) {
+ f.wrapLongLines = b
+ }
+}
+
+// WithLineNumbers formats output with line numbers.
+func WithLineNumbers(b bool) Option {
+ return func(f *Formatter) {
+ f.lineNumbers = b
+ }
+}
+
+// LineNumbersInTable will, when combined with WithLineNumbers, separate the line numbers
+// and code in table td's, which make them copy-and-paste friendly.
+func LineNumbersInTable(b bool) Option {
+ return func(f *Formatter) {
+ f.lineNumbersInTable = b
+ }
+}
+
+// WithLinkableLineNumbers decorates the line numbers HTML elements with an "id"
+// attribute so they can be linked.
+func WithLinkableLineNumbers(b bool, prefix string) Option {
+ return func(f *Formatter) {
+ f.linkableLineNumbers = b
+ f.lineNumbersIDPrefix = prefix
+ }
+}
+
+// HighlightLines higlights the given line ranges with the Highlight style.
+//
+// A range is the beginning and ending of a range as 1-based line numbers, inclusive.
+func HighlightLines(ranges [][2]int) Option {
+ return func(f *Formatter) {
+ f.highlightRanges = ranges
+ sort.Sort(f.highlightRanges)
+ }
+}
+
+// BaseLineNumber sets the initial number to start line numbering at. Defaults to 1.
+func BaseLineNumber(n int) Option {
+ return func(f *Formatter) {
+ f.baseLineNumber = n
+ }
+}
+
+// New HTML formatter.
+func New(options ...Option) *Formatter {
+ f := &Formatter{
+ baseLineNumber: 1,
+ preWrapper: defaultPreWrapper,
+ }
+ f.styleCache = newStyleCache(f)
+ for _, option := range options {
+ option(f)
+ }
+ return f
+}
+
+// PreWrapper defines the operations supported in WithPreWrapper.
+type PreWrapper interface {
+ // Start is called to write a start element. + // The code flag tells whether this block surrounds + // highlighted code. This will be false when surrounding + // line numbers. + Start(code bool, styleAttr string) string + + // End is called to write the endelement. + End(code bool) string +} + +type preWrapper struct { + start func(code bool, styleAttr string) string + end func(code bool) string +} + +func (p preWrapper) Start(code bool, styleAttr string) string { + return p.start(code, styleAttr) +} + +func (p preWrapper) End(code bool) string { + return p.end(code) +} + +var ( + nopPreWrapper = preWrapper{ + start: func(code bool, styleAttr string) string { return "" }, + end: func(code bool) string { return "" }, + } + defaultPreWrapper = preWrapper{ + start: func(code bool, styleAttr string) string { + if code { + return fmt.Sprintf(`
`, styleAttr)
+ }
+
+ return fmt.Sprintf(``, styleAttr)
+ },
+ end: func(code bool) string {
+ if code {
+ return ``
+ }
+
+ return ``
+ },
+ }
+)
+
+// Formatter that generates HTML.
+type Formatter struct {
+ styleCache *styleCache
+ standalone bool
+ prefix string
+ Classes bool // Exported field to detect when classes are being used
+ allClasses bool
+ customCSS map[chroma.TokenType]string
+ preWrapper PreWrapper
+ inlineCode bool
+ preventSurroundingPre bool
+ tabWidth int
+ wrapLongLines bool
+ lineNumbers bool
+ lineNumbersInTable bool
+ linkableLineNumbers bool
+ lineNumbersIDPrefix string
+ highlightRanges highlightRanges
+ baseLineNumber int
+}
+
+type highlightRanges [][2]int
+
+func (h highlightRanges) Len() int { return len(h) }
+func (h highlightRanges) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
+func (h highlightRanges) Less(i, j int) bool { return h[i][0] < h[j][0] }
+
+func (f *Formatter) Format(w io.Writer, style *chroma.Style, iterator chroma.Iterator) (err error) {
+ return f.writeHTML(w, style, iterator.Tokens())
+}
+
+// We deliberately don't use html/template here because it is two orders of magnitude slower (benchmarked).
+//
+// OTOH we need to be super careful about correct escaping...
+func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.Token) (err error) { // nolint: gocyclo
+ css := f.styleCache.get(style, true)
+ if f.standalone {
+ fmt.Fprint(w, "\n")
+ if f.Classes {
+ fmt.Fprint(w, "")
+ }
+ fmt.Fprintf(w, "\n", f.styleAttr(css, chroma.Background))
+ }
+
+ wrapInTable := f.lineNumbers && f.lineNumbersInTable
+
+ lines := chroma.SplitTokensIntoLines(tokens)
+ lineDigits := len(strconv.Itoa(f.baseLineNumber + len(lines) - 1))
+ highlightIndex := 0
+
+ if wrapInTable {
+ // List line numbers in its own | \n", f.styleAttr(css, chroma.LineTableTD)) + fmt.Fprintf(w, "%s", f.preWrapper.Start(false, f.styleAttr(css, chroma.PreWrapper))) + for index := range lines { + line := f.baseLineNumber + index + highlight, next := f.shouldHighlight(highlightIndex, line) + if next { + highlightIndex++ + } + if highlight { + fmt.Fprintf(w, "", f.styleAttr(css, chroma.LineHighlight)) + } + + fmt.Fprintf(w, "%s\n", f.styleAttr(css, chroma.LineNumbersTable), f.lineIDAttribute(line), f.lineTitleWithLinkIfNeeded(css, lineDigits, line)) + + if highlight { + fmt.Fprintf(w, "") + } + } + fmt.Fprint(w, f.preWrapper.End(false)) + fmt.Fprint(w, " | \n") + fmt.Fprintf(w, "\n", f.styleAttr(css, chroma.LineTableTD, "width:100%")) + } + + fmt.Fprintf(w, "%s", f.preWrapper.Start(true, f.styleAttr(css, chroma.PreWrapper))) + + highlightIndex = 0 + for index, tokens := range lines { + // 1-based line number. + line := f.baseLineNumber + index + highlight, next := f.shouldHighlight(highlightIndex, line) + if next { + highlightIndex++ + } + + if !(f.preventSurroundingPre || f.inlineCode) { + // Start of Line + fmt.Fprint(w, ``) + } else { + fmt.Fprintf(w, "%s>", f.styleAttr(css, chroma.Line)) + } + + // Line number + if f.lineNumbers && !wrapInTable { + fmt.Fprintf(w, "%s", f.styleAttr(css, chroma.LineNumbers), f.lineIDAttribute(line), f.lineTitleWithLinkIfNeeded(css, lineDigits, line)) + } + + fmt.Fprintf(w, ``, f.styleAttr(css, chroma.CodeLine)) + } + + for _, token := range tokens { + html := html.EscapeString(token.String()) + attr := f.styleAttr(css, token.Type) + if attr != "" { + html = fmt.Sprintf("%s", attr, html) + } + fmt.Fprint(w, html) + } + + if !(f.preventSurroundingPre || f.inlineCode) { + fmt.Fprint(w, ``) // End of CodeLine + + fmt.Fprint(w, ``) // End of Line + } + } + fmt.Fprintf(w, "%s", f.preWrapper.End(true)) + + if wrapInTable { + fmt.Fprint(w, " |
, B, ...
+ {
+ `(?[CBIUDTKRPAELZVMSXN])(?<+|«)`,
+ ByGroups(Keyword, Punctuation),
+ findBrackets(rakuPodFormatter),
+ },
+ },
+ "pod-formatter": {
+ // Placeholder rule, will be replaced by mutators. DO NOT REMOVE!
+ {`>`, Punctuation, Pop(1)},
+ Include("pre-pod-formatter"),
+ // Placeholder rule, will be replaced by mutators. DO NOT REMOVE!
+ {`.+?`, StringOther, nil},
+ },
+ "variable": {
+ {variablePattern, NameVariable, Push("name-adverb")},
+ {globalVariablePattern, NameVariableGlobal, Push("name-adverb")},
+ {`[$@]<[^>]+>`, NameVariable, nil},
+ {`\$[/!¢]`, NameVariable, nil},
+ {`[$@%]`, NameVariable, nil},
+ },
+ "single-quote": {
+ {`(?>(?!\s*(?:\d+|\.(?:Int|Numeric)|[$@%]\*?[\w':-]+|\s+\[))`, Punctuation, Pop(1)},
+ Include("ww"),
+ },
+ "«": {
+ {`»(?!\s*(?:\d+|\.(?:Int|Numeric)|[$@%]\*?[\w':-]+|\s+\[))`, Punctuation, Pop(1)},
+ Include("ww"),
+ },
+ "ww": {
+ Include("single-quote"),
+ Include("qq"),
+ },
+ "qq": {
+ Include("qq-variable"),
+ Include("closure"),
+ Include(`escape-char`),
+ Include("escape-hexadecimal"),
+ Include("escape-c-name"),
+ Include("escape-qq"),
+ {`.+?`, StringDouble, nil},
+ },
+ "qq-variable": {
+ {
+ `(?\.)(?` + namePattern + `)` + colonPairLookahead + `\()`,
+ ByGroupNames(map[string]Emitter{
+ `operator`: Operator,
+ `method_name`: NameFunction,
+ }),
+ Push(`name-adverb`),
+ },
+ // Function/Signature
+ {
+ `\(`, Punctuation, replaceRule(
+ ruleReplacingConfig{
+ delimiter: []rune(`)`),
+ tokenType: Punctuation,
+ stateName: `root`,
+ pushState: true,
+ }),
+ },
+ Default(Pop(1)),
+ },
+ "Q": {
+ Include("escape-qq"),
+ {`.+?`, String, nil},
+ },
+ "Q-closure": {
+ Include("escape-qq"),
+ Include("closure"),
+ {`.+?`, String, nil},
+ },
+ "Q-variable": {
+ Include("escape-qq"),
+ Include("qq-variable"),
+ {`.+?`, String, nil},
+ },
+ "closure": {
+ {`(? -1 {
+ idx = utf8.RuneCountInString(text[:idx])
+
+ // Search again if the substr is escaped with backslash
+ if (idx > 1 && strFromPos[idx-1] == '\\' && strFromPos[idx-2] != '\\') ||
+ (idx == 1 && strFromPos[idx-1] == '\\') {
+ idx = indexAt(str[pos:], substr, idx+1)
+
+ idx = utf8.RuneCountInString(text[:idx])
+
+ if idx < 0 {
+ return idx
+ }
+ }
+ idx += pos
+ }
+
+ return idx
+}
+
+// Tells if an array of string contains a string
+func contains(s []string, e string) bool {
+ for _, value := range s {
+ if value == e {
+ return true
+ }
+ }
+ return false
+}
+
+type rulePosition int
+
+const (
+ topRule rulePosition = 0
+ bottomRule = -1
+)
+
+type ruleMakingConfig struct {
+ delimiter []rune
+ pattern string
+ tokenType Emitter
+ mutator Mutator
+ numberOfDelimiterChars int
+}
+
+type ruleReplacingConfig struct {
+ delimiter []rune
+ pattern string
+ tokenType Emitter
+ numberOfDelimiterChars int
+ mutator Mutator
+ appendMutator Mutator
+ rulePosition rulePosition
+ stateName string
+ pop bool
+ popState bool
+ pushState bool
+}
+
+// Pops rule from state-stack and replaces the rule with the previous rule
+func popRule(rule ruleReplacingConfig) MutatorFunc {
+ return func(state *LexerState) error {
+ stackName := genStackName(rule.stateName, rule.rulePosition)
+
+ stack, ok := state.Get(stackName).([]ruleReplacingConfig)
+
+ if ok && len(stack) > 0 {
+ // Pop from stack
+ stack = stack[:len(stack)-1]
+ lastRule := stack[len(stack)-1]
+ lastRule.pushState = false
+ lastRule.popState = false
+ lastRule.pop = true
+ state.Set(stackName, stack)
+
+ // Call replaceRule to use the last rule
+ err := replaceRule(lastRule)(state)
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ return nil
+ }
+}
+
+// Replaces a state's rule based on the rule config and position
+func replaceRule(rule ruleReplacingConfig) MutatorFunc {
+ return func(state *LexerState) error {
+ stateName := rule.stateName
+ stackName := genStackName(rule.stateName, rule.rulePosition)
+
+ stack, ok := state.Get(stackName).([]ruleReplacingConfig)
+ if !ok {
+ stack = []ruleReplacingConfig{}
+ }
+
+ // If state-stack is empty fill it with the placeholder rule
+ if len(stack) == 0 {
+ stack = []ruleReplacingConfig{
+ {
+ // Placeholder, will be overwritten by mutators, DO NOT REMOVE!
+ pattern: `\A\z`,
+ tokenType: nil,
+ mutator: nil,
+ stateName: stateName,
+ rulePosition: rule.rulePosition,
+ },
+ }
+ state.Set(stackName, stack)
+ }
+
+ var mutator Mutator
+ mutators := []Mutator{}
+
+ switch {
+ case rule.rulePosition == topRule && rule.mutator == nil:
+ // Default mutator for top rule
+ mutators = []Mutator{Pop(1), popRule(rule)}
+ case rule.rulePosition == topRule && rule.mutator != nil:
+ // Default mutator for top rule, when rule.mutator is set
+ mutators = []Mutator{rule.mutator, popRule(rule)}
+ case rule.mutator != nil:
+ mutators = []Mutator{rule.mutator}
+ }
+
+ if rule.appendMutator != nil {
+ mutators = append(mutators, rule.appendMutator)
+ }
+
+ if len(mutators) > 0 {
+ mutator = Mutators(mutators...)
+ } else {
+ mutator = nil
+ }
+
+ ruleConfig := ruleMakingConfig{
+ pattern: rule.pattern,
+ delimiter: rule.delimiter,
+ numberOfDelimiterChars: rule.numberOfDelimiterChars,
+ tokenType: rule.tokenType,
+ mutator: mutator,
+ }
+
+ cRule := makeRule(ruleConfig)
+
+ switch rule.rulePosition {
+ case topRule:
+ state.Rules[stateName][0] = cRule
+ case bottomRule:
+ state.Rules[stateName][len(state.Rules[stateName])-1] = cRule
+ }
+
+ // Pop state name from stack if asked. State should be popped first before Pushing
+ if rule.popState {
+ err := Pop(1).Mutate(state)
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ // Push state name to stack if asked
+ if rule.pushState {
+ err := Push(stateName).Mutate(state)
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ if !rule.pop {
+ state.Set(stackName, append(stack, rule))
+ }
+
+ return nil
+ }
+}
+
+// Generates rule replacing stack using state name and rule position
+func genStackName(stateName string, rulePosition rulePosition) (stackName string) {
+ switch rulePosition {
+ case topRule:
+ stackName = stateName + `-top-stack`
+ case bottomRule:
+ stackName = stateName + `-bottom-stack`
+ }
+ return
+}
+
+// Makes a compiled rule and returns it
+func makeRule(config ruleMakingConfig) *CompiledRule {
+ var rePattern string
+
+ if len(config.delimiter) > 0 {
+ delimiter := string(config.delimiter)
+
+ if config.numberOfDelimiterChars > 1 {
+ delimiter = strings.Repeat(delimiter, config.numberOfDelimiterChars)
+ }
+
+ rePattern = `(? 1 {
+ lang = langMatch[1]
+ }
+
+ // Tokenise code based on lang property
+ sublexer := Get(lang)
+ if sublexer != nil {
+ iterator, err := sublexer.Tokenise(nil, state.NamedGroups[`value`])
+
+ if err != nil {
+ panic(err)
+ } else {
+ iterators = append(iterators, iterator)
+ }
+ } else {
+ iterators = append(iterators, Literator(tokens[4]))
+ }
+
+ // Append the rest of the tokens
+ iterators = append(iterators, Literator(tokens[5:]...))
+
+ return Concaterator(iterators...)
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/rst.go b/vendor/github.com/alecthomas/chroma/v2/lexers/rst.go
new file mode 100644
index 0000000..66ec03c
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/rst.go
@@ -0,0 +1,89 @@
+package lexers
+
+import (
+ "strings"
+
+ . "github.com/alecthomas/chroma/v2" // nolint
+)
+
+// Restructuredtext lexer.
+var Restructuredtext = Register(MustNewLexer(
+ &Config{
+ Name: "reStructuredText",
+ Aliases: []string{"rst", "rest", "restructuredtext"},
+ Filenames: []string{"*.rst", "*.rest"},
+ MimeTypes: []string{"text/x-rst", "text/prs.fallenstein.rst"},
+ },
+ restructuredtextRules,
+))
+
+func restructuredtextRules() Rules {
+ return Rules{
+ "root": {
+ {"^(=+|-+|`+|:+|\\.+|\\'+|\"+|~+|\\^+|_+|\\*+|\\++|#+)([ \\t]*\\n)(.+)(\\n)(\\1)(\\n)", ByGroups(GenericHeading, Text, GenericHeading, Text, GenericHeading, Text), nil},
+ {"^(\\S.*)(\\n)(={3,}|-{3,}|`{3,}|:{3,}|\\.{3,}|\\'{3,}|\"{3,}|~{3,}|\\^{3,}|_{3,}|\\*{3,}|\\+{3,}|#{3,})(\\n)", ByGroups(GenericHeading, Text, GenericHeading, Text), nil},
+ {`^(\s*)([-*+])( .+\n(?:\1 .+\n)*)`, ByGroups(Text, LiteralNumber, UsingSelf("inline")), nil},
+ {`^(\s*)([0-9#ivxlcmIVXLCM]+\.)( .+\n(?:\1 .+\n)*)`, ByGroups(Text, LiteralNumber, UsingSelf("inline")), nil},
+ {`^(\s*)(\(?[0-9#ivxlcmIVXLCM]+\))( .+\n(?:\1 .+\n)*)`, ByGroups(Text, LiteralNumber, UsingSelf("inline")), nil},
+ {`^(\s*)([A-Z]+\.)( .+\n(?:\1 .+\n)+)`, ByGroups(Text, LiteralNumber, UsingSelf("inline")), nil},
+ {`^(\s*)(\(?[A-Za-z]+\))( .+\n(?:\1 .+\n)+)`, ByGroups(Text, LiteralNumber, UsingSelf("inline")), nil},
+ {`^(\s*)(\|)( .+\n(?:\| .+\n)*)`, ByGroups(Text, Operator, UsingSelf("inline")), nil},
+ {`^( *\.\.)(\s*)((?:source)?code(?:-block)?)(::)([ \t]*)([^\n]+)(\n[ \t]*\n)([ \t]+)(.*)(\n)((?:(?:\8.*|)\n)+)`, EmitterFunc(rstCodeBlock), nil},
+ {`^( *\.\.)(\s*)([\w:-]+?)(::)(?:([ \t]*)(.*))`, ByGroups(Punctuation, Text, OperatorWord, Punctuation, Text, UsingSelf("inline")), nil},
+ {`^( *\.\.)(\s*)(_(?:[^:\\]|\\.)+:)(.*?)$`, ByGroups(Punctuation, Text, NameTag, UsingSelf("inline")), nil},
+ {`^( *\.\.)(\s*)(\[.+\])(.*?)$`, ByGroups(Punctuation, Text, NameTag, UsingSelf("inline")), nil},
+ {`^( *\.\.)(\s*)(\|.+\|)(\s*)([\w:-]+?)(::)(?:([ \t]*)(.*))`, ByGroups(Punctuation, Text, NameTag, Text, OperatorWord, Punctuation, Text, UsingSelf("inline")), nil},
+ {`^ *\.\..*(\n( +.*\n|\n)+)?`, CommentPreproc, nil},
+ {`^( *)(:[a-zA-Z-]+:)(\s*)$`, ByGroups(Text, NameClass, Text), nil},
+ {`^( *)(:.*?:)([ \t]+)(.*?)$`, ByGroups(Text, NameClass, Text, NameFunction), nil},
+ {`^(\S.*(?)(`__?)", ByGroups(LiteralString, LiteralStringInterpol, LiteralString), nil},
+ {"`.+?`__?", LiteralString, nil},
+ {"(`.+?`)(:[a-zA-Z0-9:-]+?:)?", ByGroups(NameVariable, NameAttribute), nil},
+ {"(:[a-zA-Z0-9:-]+?:)(`.+?`)", ByGroups(NameAttribute, NameVariable), nil},
+ {`\*\*.+?\*\*`, GenericStrong, nil},
+ {`\*.+?\*`, GenericEmph, nil},
+ {`\[.*?\]_`, LiteralString, nil},
+ {`<.+?>`, NameTag, nil},
+ {"[^\\\\\\n\\[*`:]+", Text, nil},
+ {`.`, Text, nil},
+ },
+ "literal": {
+ {"[^`]+", LiteralString, nil},
+ {"``((?=$)|(?=[-/:.,; \\n\\x00\\\u2010\\\u2011\\\u2012\\\u2013\\\u2014\\\u00a0\\'\\\"\\)\\]\\}\\>\\\u2019\\\u201d\\\u00bb\\!\\?]))", LiteralString, Pop(1)},
+ {"`", LiteralString, nil},
+ },
+ }
+}
+
+func rstCodeBlock(groups []string, state *LexerState) Iterator {
+ iterators := []Iterator{}
+ tokens := []Token{
+ {Punctuation, groups[1]},
+ {Text, groups[2]},
+ {OperatorWord, groups[3]},
+ {Punctuation, groups[4]},
+ {Text, groups[5]},
+ {Keyword, groups[6]},
+ {Text, groups[7]},
+ }
+ code := strings.Join(groups[8:], "")
+ lexer := Get(groups[6])
+ if lexer == nil {
+ tokens = append(tokens, Token{String, code})
+ iterators = append(iterators, Literator(tokens...))
+ } else {
+ sub, err := lexer.Tokenise(nil, code)
+ if err != nil {
+ panic(err)
+ }
+ iterators = append(iterators, Literator(tokens...), sub)
+ }
+ return Concaterator(iterators...)
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/svelte.go b/vendor/github.com/alecthomas/chroma/v2/lexers/svelte.go
new file mode 100644
index 0000000..39211c4
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/svelte.go
@@ -0,0 +1,70 @@
+package lexers
+
+import (
+ . "github.com/alecthomas/chroma/v2" // nolint
+)
+
+// Svelte lexer.
+var Svelte = Register(DelegatingLexer(HTML, MustNewLexer(
+ &Config{
+ Name: "Svelte",
+ Aliases: []string{"svelte"},
+ Filenames: []string{"*.svelte"},
+ MimeTypes: []string{"application/x-svelte"},
+ DotAll: true,
+ },
+ svelteRules,
+)))
+
+func svelteRules() Rules {
+ return Rules{
+ "root": {
+ // Let HTML handle the comments, including comments containing script and style tags
+ {``, Other, Pop(1)},
+ {`.+?`, Other, nil},
+ },
+ "templates": {
+ {`}`, Punctuation, Pop(1)},
+ // Let TypeScript handle strings and the curly braces inside them
+ {`(?]*>`, Using("TypoScriptHTMLData"), nil},
+ {`&[^;\n]*;`, LiteralString, nil},
+ {`(_CSS_DEFAULT_STYLE)(\s*)(\()(?s)(.*(?=\n\)))`, ByGroups(NameClass, Text, LiteralStringSymbol, Using("TypoScriptCSSData")), nil},
+ },
+ "literal": {
+ {`0x[0-9A-Fa-f]+t?`, LiteralNumberHex, nil},
+ {`[0-9]+`, LiteralNumberInteger, nil},
+ {`(###\w+###)`, NameConstant, nil},
+ },
+ "label": {
+ {`(EXT|FILE|LLL):[^}\n"]*`, LiteralString, nil},
+ {`(?![^\w\-])([\w\-]+(?:/[\w\-]+)+/?)(\S*\n)`, ByGroups(LiteralString, LiteralString), nil},
+ },
+ "punctuation": {
+ {`[,.]`, Punctuation, nil},
+ },
+ "operator": {
+ {`[<>,:=.*%+|]`, Operator, nil},
+ },
+ "structure": {
+ {`[{}()\[\]\\]`, LiteralStringSymbol, nil},
+ },
+ "constant": {
+ {`(\{)(\$)((?:[\w\-]+\.)*)([\w\-]+)(\})`, ByGroups(LiteralStringSymbol, Operator, NameConstant, NameConstant, LiteralStringSymbol), nil},
+ {`(\{)([\w\-]+)(\s*:\s*)([\w\-]+)(\})`, ByGroups(LiteralStringSymbol, NameConstant, Operator, NameConstant, LiteralStringSymbol), nil},
+ {`(#[a-fA-F0-9]{6}\b|#[a-fA-F0-9]{3}\b)`, LiteralStringChar, nil},
+ },
+ "comment": {
+ {`(? lexers.txt
+
+kotlin:
+ invalid unicode escape sequences
+ FIXED: Have to disable wide Unicode characters in unistring.py
+
+pygments.lexers.ambient.AmbientTalkLexer
+pygments.lexers.ampl.AmplLexer
+pygments.lexers.actionscript.ActionScriptLexer
+pygments.lexers.actionscript.ActionScript3Lexer
+pygments.lexers.actionscript.MxmlLexer
+pygments.lexers.algebra.GAPLexer
+pygments.lexers.algebra.MathematicaLexer
+pygments.lexers.algebra.MuPADLexer
+pygments.lexers.algebra.BCLexer
+pygments.lexers.apl.APLLexer
+pygments.lexers.bibtex.BibTeXLexer
+pygments.lexers.bibtex.BSTLexer
+pygments.lexers.basic.BlitzMaxLexer
+pygments.lexers.basic.BlitzBasicLexer
+pygments.lexers.basic.MonkeyLexer
+pygments.lexers.basic.CbmBasicV2Lexer
+pygments.lexers.basic.QBasicLexer
+pygments.lexers.automation.AutohotkeyLexer
+pygments.lexers.automation.AutoItLexer
+pygments.lexers.archetype.AtomsLexer
+pygments.lexers.c_like.ClayLexer
+pygments.lexers.c_like.ValaLexer
+pygments.lexers.asm.GasLexer
+pygments.lexers.asm.ObjdumpLexer
+pygments.lexers.asm.HsailLexer
+pygments.lexers.asm.LlvmLexer
+pygments.lexers.asm.NasmLexer
+pygments.lexers.asm.TasmLexer
+pygments.lexers.asm.Ca65Lexer
+pygments.lexers.business.CobolLexer
+pygments.lexers.business.ABAPLexer
+pygments.lexers.business.OpenEdgeLexer
+pygments.lexers.business.GoodDataCLLexer
+pygments.lexers.business.MaqlLexer
+pygments.lexers.capnproto.CapnProtoLexer
+pygments.lexers.chapel.ChapelLexer
+pygments.lexers.clean.CleanLexer
+pygments.lexers.c_cpp.CFamilyLexer
+pygments.lexers.console.VCTreeStatusLexer
+pygments.lexers.console.PyPyLogLexer
+pygments.lexers.csound.CsoundLexer
+pygments.lexers.csound.CsoundDocumentLexer
+pygments.lexers.csound.CsoundDocumentLexer
+pygments.lexers.crystal.CrystalLexer
+pygments.lexers.dalvik.SmaliLexer
+pygments.lexers.css.CssLexer
+pygments.lexers.css.SassLexer
+pygments.lexers.css.ScssLexer
+pygments.lexers.configs.IniLexer
+pygments.lexers.configs.RegeditLexer
+pygments.lexers.configs.PropertiesLexer
+pygments.lexers.configs.KconfigLexer
+pygments.lexers.configs.Cfengine3Lexer
+pygments.lexers.configs.ApacheConfLexer
+pygments.lexers.configs.SquidConfLexer
+pygments.lexers.configs.NginxConfLexer
+pygments.lexers.configs.LighttpdConfLexer
+pygments.lexers.configs.DockerLexer
+pygments.lexers.configs.TerraformLexer
+pygments.lexers.configs.TermcapLexer
+pygments.lexers.configs.TerminfoLexer
+pygments.lexers.configs.PkgConfigLexer
+pygments.lexers.configs.PacmanConfLexer
+pygments.lexers.data.YamlLexer
+pygments.lexers.data.JsonLexer
+pygments.lexers.diff.DiffLexer
+pygments.lexers.diff.DarcsPatchLexer
+pygments.lexers.diff.WDiffLexer
+pygments.lexers.dotnet.CSharpLexer
+pygments.lexers.dotnet.NemerleLexer
+pygments.lexers.dotnet.BooLexer
+pygments.lexers.dotnet.VbNetLexer
+pygments.lexers.dotnet.GenericAspxLexer
+pygments.lexers.dotnet.FSharpLexer
+pygments.lexers.dylan.DylanLexer
+pygments.lexers.dylan.DylanLidLexer
+pygments.lexers.ecl.ECLLexer
+pygments.lexers.eiffel.EiffelLexer
+pygments.lexers.dsls.ProtoBufLexer
+pygments.lexers.dsls.ThriftLexer
+pygments.lexers.dsls.BroLexer
+pygments.lexers.dsls.PuppetLexer
+pygments.lexers.dsls.RslLexer
+pygments.lexers.dsls.MscgenLexer
+pygments.lexers.dsls.VGLLexer
+pygments.lexers.dsls.AlloyLexer
+pygments.lexers.dsls.PanLexer
+pygments.lexers.dsls.CrmshLexer
+pygments.lexers.dsls.FlatlineLexer
+pygments.lexers.dsls.SnowballLexer
+pygments.lexers.elm.ElmLexer
+pygments.lexers.erlang.ErlangLexer
+pygments.lexers.erlang.ElixirLexer
+pygments.lexers.ezhil.EzhilLexer
+pygments.lexers.esoteric.BrainfuckLexer
+pygments.lexers.esoteric.BefungeLexer
+pygments.lexers.esoteric.CAmkESLexer
+pygments.lexers.esoteric.CapDLLexer
+pygments.lexers.esoteric.RedcodeLexer
+pygments.lexers.esoteric.AheuiLexer
+pygments.lexers.factor.FactorLexer
+pygments.lexers.fantom.FantomLexer
+pygments.lexers.felix.FelixLexer
+pygments.lexers.forth.ForthLexer
+pygments.lexers.fortran.FortranLexer
+pygments.lexers.fortran.FortranFixedLexer
+pygments.lexers.go.GoLexer
+pygments.lexers.foxpro.FoxProLexer
+pygments.lexers.graph.CypherLexer
+pygments.lexers.grammar_notation.BnfLexer
+pygments.lexers.grammar_notation.AbnfLexer
+pygments.lexers.grammar_notation.JsgfLexer
+pygments.lexers.graphics.GLShaderLexer
+pygments.lexers.graphics.PostScriptLexer
+pygments.lexers.graphics.AsymptoteLexer
+pygments.lexers.graphics.GnuplotLexer
+pygments.lexers.graphics.PovrayLexer
+pygments.lexers.hexdump.HexdumpLexer
+pygments.lexers.haskell.HaskellLexer
+pygments.lexers.haskell.IdrisLexer
+pygments.lexers.haskell.AgdaLexer
+pygments.lexers.haskell.CryptolLexer
+pygments.lexers.haskell.KokaLexer
+pygments.lexers.haxe.HaxeLexer
+pygments.lexers.haxe.HxmlLexer
+pygments.lexers.hdl.VerilogLexer
+pygments.lexers.hdl.SystemVerilogLexer
+pygments.lexers.hdl.VhdlLexer
+pygments.lexers.idl.IDLLexer
+pygments.lexers.inferno.LimboLexer
+pygments.lexers.igor.IgorLexer
+pygments.lexers.html.HtmlLexer
+pygments.lexers.html.DtdLexer
+pygments.lexers.html.XmlLexer
+pygments.lexers.html.HamlLexer
+pygments.lexers.html.ScamlLexer
+pygments.lexers.html.PugLexer
+pygments.lexers.installers.NSISLexer
+pygments.lexers.installers.RPMSpecLexer
+pygments.lexers.installers.SourcesListLexer
+pygments.lexers.installers.DebianControlLexer
+pygments.lexers.iolang.IoLexer
+pygments.lexers.julia.JuliaLexer
+pygments.lexers.int_fiction.Inform6Lexer
+pygments.lexers.int_fiction.Inform7Lexer
+pygments.lexers.int_fiction.Tads3Lexer
+pygments.lexers.make.BaseMakefileLexer
+pygments.lexers.make.CMakeLexer
+pygments.lexers.javascript.JavascriptLexer
+pygments.lexers.javascript.KalLexer
+pygments.lexers.javascript.LiveScriptLexer
+pygments.lexers.javascript.DartLexer
+pygments.lexers.javascript.TypeScriptLexer
+pygments.lexers.javascript.LassoLexer
+pygments.lexers.javascript.ObjectiveJLexer
+pygments.lexers.javascript.CoffeeScriptLexer
+pygments.lexers.javascript.MaskLexer
+pygments.lexers.javascript.EarlGreyLexer
+pygments.lexers.javascript.JuttleLexer
+pygments.lexers.jvm.JavaLexer
+pygments.lexers.jvm.ScalaLexer
+pygments.lexers.jvm.GosuLexer
+pygments.lexers.jvm.GroovyLexer
+pygments.lexers.jvm.IokeLexer
+pygments.lexers.jvm.ClojureLexer
+pygments.lexers.jvm.TeaLangLexer
+pygments.lexers.jvm.CeylonLexer
+pygments.lexers.jvm.KotlinLexer
+pygments.lexers.jvm.XtendLexer
+pygments.lexers.jvm.PigLexer
+pygments.lexers.jvm.GoloLexer
+pygments.lexers.jvm.JasminLexer
+pygments.lexers.markup.BBCodeLexer
+pygments.lexers.markup.MoinWikiLexer
+pygments.lexers.markup.RstLexer
+pygments.lexers.markup.TexLexer
+pygments.lexers.markup.GroffLexer
+pygments.lexers.markup.MozPreprocHashLexer
+pygments.lexers.markup.MarkdownLexer
+pygments.lexers.ml.SMLLexer
+pygments.lexers.ml.OcamlLexer
+pygments.lexers.ml.OpaLexer
+pygments.lexers.modeling.ModelicaLexer
+pygments.lexers.modeling.BugsLexer
+pygments.lexers.modeling.JagsLexer
+pygments.lexers.modeling.StanLexer
+pygments.lexers.matlab.MatlabLexer
+pygments.lexers.matlab.OctaveLexer
+pygments.lexers.matlab.ScilabLexer
+pygments.lexers.monte.MonteLexer
+pygments.lexers.lisp.SchemeLexer
+pygments.lexers.lisp.CommonLispLexer
+pygments.lexers.lisp.HyLexer
+pygments.lexers.lisp.RacketLexer
+pygments.lexers.lisp.NewLispLexer
+pygments.lexers.lisp.EmacsLispLexer
+pygments.lexers.lisp.ShenLexer
+pygments.lexers.lisp.XtlangLexer
+pygments.lexers.modula2.Modula2Lexer
+pygments.lexers.ncl.NCLLexer
+pygments.lexers.nim.NimLexer
+pygments.lexers.nit.NitLexer
+pygments.lexers.nix.NixLexer
+pygments.lexers.oberon.ComponentPascalLexer
+pygments.lexers.ooc.OocLexer
+pygments.lexers.objective.SwiftLexer
+pygments.lexers.parasail.ParaSailLexer
+pygments.lexers.pawn.SourcePawnLexer
+pygments.lexers.pawn.PawnLexer
+pygments.lexers.pascal.AdaLexer
+pygments.lexers.parsers.RagelLexer
+pygments.lexers.parsers.RagelEmbeddedLexer
+pygments.lexers.parsers.AntlrLexer
+pygments.lexers.parsers.TreetopBaseLexer
+pygments.lexers.parsers.EbnfLexer
+pygments.lexers.php.ZephirLexer
+pygments.lexers.php.PhpLexer
+pygments.lexers.perl.PerlLexer
+pygments.lexers.perl.Perl6Lexer
+pygments.lexers.praat.PraatLexer
+pygments.lexers.prolog.PrologLexer
+pygments.lexers.prolog.LogtalkLexer
+pygments.lexers.qvt.QVToLexer
+pygments.lexers.rdf.SparqlLexer
+pygments.lexers.rdf.TurtleLexer
+pygments.lexers.python.PythonLexer
+pygments.lexers.python.Python3Lexer
+pygments.lexers.python.PythonTracebackLexer
+pygments.lexers.python.Python3TracebackLexer
+pygments.lexers.python.CythonLexer
+pygments.lexers.python.DgLexer
+pygments.lexers.rebol.RebolLexer
+pygments.lexers.rebol.RedLexer
+pygments.lexers.resource.ResourceLexer
+pygments.lexers.rnc.RNCCompactLexer
+pygments.lexers.roboconf.RoboconfGraphLexer
+pygments.lexers.roboconf.RoboconfInstancesLexer
+pygments.lexers.rust.RustLexer
+pygments.lexers.ruby.RubyLexer
+pygments.lexers.ruby.FancyLexer
+pygments.lexers.sas.SASLexer
+pygments.lexers.smalltalk.SmalltalkLexer
+pygments.lexers.smalltalk.NewspeakLexer
+pygments.lexers.smv.NuSMVLexer
+pygments.lexers.shell.BashLexer
+pygments.lexers.shell.BatchLexer
+pygments.lexers.shell.TcshLexer
+pygments.lexers.shell.PowerShellLexer
+pygments.lexers.shell.FishShellLexer
+pygments.lexers.snobol.SnobolLexer
+pygments.lexers.scripting.LuaLexer
+pygments.lexers.scripting.ChaiscriptLexer
+pygments.lexers.scripting.LSLLexer
+pygments.lexers.scripting.AppleScriptLexer
+pygments.lexers.scripting.RexxLexer
+pygments.lexers.scripting.MOOCodeLexer
+pygments.lexers.scripting.HybrisLexer
+pygments.lexers.scripting.EasytrieveLexer
+pygments.lexers.scripting.JclLexer
+pygments.lexers.supercollider.SuperColliderLexer
+pygments.lexers.stata.StataLexer
+pygments.lexers.tcl.TclLexer
+pygments.lexers.sql.PostgresLexer
+pygments.lexers.sql.PlPgsqlLexer
+pygments.lexers.sql.PsqlRegexLexer
+pygments.lexers.sql.SqlLexer
+pygments.lexers.sql.TransactSqlLexer
+pygments.lexers.sql.MySqlLexer
+pygments.lexers.sql.RqlLexer
+pygments.lexers.testing.GherkinLexer
+pygments.lexers.testing.TAPLexer
+pygments.lexers.textedit.AwkLexer
+pygments.lexers.textedit.VimLexer
+pygments.lexers.textfmts.IrcLogsLexer
+pygments.lexers.textfmts.GettextLexer
+pygments.lexers.textfmts.HttpLexer
+pygments.lexers.textfmts.TodotxtLexer
+pygments.lexers.trafficscript.RtsLexer
+pygments.lexers.theorem.CoqLexer
+pygments.lexers.theorem.IsabelleLexer
+pygments.lexers.theorem.LeanLexer
+pygments.lexers.templates.SmartyLexer
+pygments.lexers.templates.VelocityLexer
+pygments.lexers.templates.DjangoLexer
+pygments.lexers.templates.MyghtyLexer
+pygments.lexers.templates.MasonLexer
+pygments.lexers.templates.MakoLexer
+pygments.lexers.templates.CheetahLexer
+pygments.lexers.templates.GenshiTextLexer
+pygments.lexers.templates.GenshiMarkupLexer
+pygments.lexers.templates.JspRootLexer
+pygments.lexers.templates.EvoqueLexer
+pygments.lexers.templates.ColdfusionLexer
+pygments.lexers.templates.ColdfusionMarkupLexer
+pygments.lexers.templates.TeaTemplateRootLexer
+pygments.lexers.templates.HandlebarsLexer
+pygments.lexers.templates.LiquidLexer
+pygments.lexers.templates.TwigLexer
+pygments.lexers.templates.Angular2Lexer
+pygments.lexers.urbi.UrbiscriptLexer
+pygments.lexers.typoscript.TypoScriptCssDataLexer
+pygments.lexers.typoscript.TypoScriptHtmlDataLexer
+pygments.lexers.typoscript.TypoScriptLexer
+pygments.lexers.varnish.VCLLexer
+pygments.lexers.verification.BoogieLexer
+pygments.lexers.verification.SilverLexer
+pygments.lexers.x10.X10Lexer
+pygments.lexers.whiley.WhileyLexer
+pygments.lexers.xorg.XorgLexer
+pygments.lexers.webmisc.DuelLexer
+pygments.lexers.webmisc.XQueryLexer
+pygments.lexers.webmisc.QmlLexer
+pygments.lexers.webmisc.CirruLexer
+pygments.lexers.webmisc.SlimLexer
diff --git a/vendor/github.com/alecthomas/chroma/v2/quick/quick.go b/vendor/github.com/alecthomas/chroma/v2/quick/quick.go
new file mode 100644
index 0000000..af701d9
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/quick/quick.go
@@ -0,0 +1,44 @@
+// Package quick provides simple, no-configuration source code highlighting.
+package quick
+
+import (
+ "io"
+
+ "github.com/alecthomas/chroma/v2"
+ "github.com/alecthomas/chroma/v2/formatters"
+ "github.com/alecthomas/chroma/v2/lexers"
+ "github.com/alecthomas/chroma/v2/styles"
+)
+
+// Highlight some text.
+//
+// Lexer, formatter and style may be empty, in which case a best-effort is made.
+func Highlight(w io.Writer, source, lexer, formatter, style string) error {
+ // Determine lexer.
+ l := lexers.Get(lexer)
+ if l == nil {
+ l = lexers.Analyse(source)
+ }
+ if l == nil {
+ l = lexers.Fallback
+ }
+ l = chroma.Coalesce(l)
+
+ // Determine formatter.
+ f := formatters.Get(formatter)
+ if f == nil {
+ f = formatters.Fallback
+ }
+
+ // Determine style.
+ s := styles.Get(style)
+ if s == nil {
+ s = styles.Fallback
+ }
+
+ it, err := l.Tokenise(nil, source)
+ if err != nil {
+ return err
+ }
+ return f.Format(w, s, it)
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/regexp.go b/vendor/github.com/alecthomas/chroma/v2/regexp.go
new file mode 100644
index 0000000..5796726
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/regexp.go
@@ -0,0 +1,489 @@
+package chroma
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "regexp"
+ "sort"
+ "strings"
+ "sync"
+ "time"
+ "unicode/utf8"
+
+ "github.com/dlclark/regexp2"
+)
+
+// A Rule is the fundamental matching unit of the Regex lexer state machine.
+type Rule struct {
+ Pattern string
+ Type Emitter
+ Mutator Mutator
+}
+
+// Words creates a regex that matches any of the given literal words.
+func Words(prefix, suffix string, words ...string) string {
+ sort.Slice(words, func(i, j int) bool {
+ return len(words[j]) < len(words[i])
+ })
+ for i, word := range words {
+ words[i] = regexp.QuoteMeta(word)
+ }
+ return prefix + `(` + strings.Join(words, `|`) + `)` + suffix
+}
+
+// Tokenise text using lexer, returning tokens as a slice.
+func Tokenise(lexer Lexer, options *TokeniseOptions, text string) ([]Token, error) {
+ var out []Token
+ it, err := lexer.Tokenise(options, text)
+ if err != nil {
+ return nil, err
+ }
+ for t := it(); t != EOF; t = it() {
+ out = append(out, t)
+ }
+ return out, nil
+}
+
+// Rules maps from state to a sequence of Rules.
+type Rules map[string][]Rule
+
+// Rename clones rules then a rule.
+func (r Rules) Rename(oldRule, newRule string) Rules {
+ r = r.Clone()
+ r[newRule] = r[oldRule]
+ delete(r, oldRule)
+ return r
+}
+
+// Clone returns a clone of the Rules.
+func (r Rules) Clone() Rules {
+ out := map[string][]Rule{}
+ for key, rules := range r {
+ out[key] = make([]Rule, len(rules))
+ copy(out[key], rules)
+ }
+ return out
+}
+
+// Merge creates a clone of "r" then merges "rules" into the clone.
+func (r Rules) Merge(rules Rules) Rules {
+ out := r.Clone()
+ for k, v := range rules.Clone() {
+ out[k] = v
+ }
+ return out
+}
+
+// MustNewLexer creates a new Lexer with deferred rules generation or panics.
+func MustNewLexer(config *Config, rules func() Rules) *RegexLexer {
+ lexer, err := NewLexer(config, rules)
+ if err != nil {
+ panic(err)
+ }
+ return lexer
+}
+
+// NewLexer creates a new regex-based Lexer.
+//
+// "rules" is a state machine transition map. Each key is a state. Values are sets of rules
+// that match input, optionally modify lexer state, and output tokens.
+func NewLexer(config *Config, rulesFunc func() Rules) (*RegexLexer, error) {
+ if config == nil {
+ config = &Config{}
+ }
+ for _, glob := range append(config.Filenames, config.AliasFilenames...) {
+ _, err := filepath.Match(glob, "")
+ if err != nil {
+ return nil, fmt.Errorf("%s: %q is not a valid glob: %w", config.Name, glob, err)
+ }
+ }
+ r := &RegexLexer{
+ config: config,
+ fetchRulesFunc: func() (Rules, error) { return rulesFunc(), nil },
+ }
+ // One-off code to generate XML lexers in the Chroma source tree.
+ // var nameCleanRe = regexp.MustCompile(`[^-+A-Za-z0-9_]`)
+ // name := strings.ToLower(nameCleanRe.ReplaceAllString(config.Name, "_"))
+ // data, err := Marshal(r)
+ // if err != nil {
+ // if errors.Is(err, ErrNotSerialisable) {
+ // fmt.Fprintf(os.Stderr, "warning: %q: %s\n", name, err)
+ // return r, nil
+ // }
+ // return nil, err
+ // }
+ // _, file, _, ok := runtime.Caller(2)
+ // if !ok {
+ // panic("??")
+ // }
+ // fmt.Println(file)
+ // if strings.Contains(file, "/lexers/") {
+ // dir := filepath.Join(filepath.Dir(file), "embedded")
+ // err = os.MkdirAll(dir, 0700)
+ // if err != nil {
+ // return nil, err
+ // }
+ // filename := filepath.Join(dir, name) + ".xml"
+ // fmt.Println(filename)
+ // err = ioutil.WriteFile(filename, data, 0600)
+ // if err != nil {
+ // return nil, err
+ // }
+ // }
+ return r, nil
+}
+
+// Trace enables debug tracing.
+func (r *RegexLexer) Trace(trace bool) *RegexLexer {
+ r.trace = trace
+ return r
+}
+
+// A CompiledRule is a Rule with a pre-compiled regex.
+//
+// Note that regular expressions are lazily compiled on first use of the lexer.
+type CompiledRule struct {
+ Rule
+ Regexp *regexp2.Regexp
+ flags string
+}
+
+// CompiledRules is a map of rule name to sequence of compiled rules in that rule.
+type CompiledRules map[string][]*CompiledRule
+
+// LexerState contains the state for a single lex.
+type LexerState struct {
+ Lexer *RegexLexer
+ Registry *LexerRegistry
+ Text []rune
+ Pos int
+ Rules CompiledRules
+ Stack []string
+ State string
+ Rule int
+ // Group matches.
+ Groups []string
+ // Named Group matches.
+ NamedGroups map[string]string
+ // Custum context for mutators.
+ MutatorContext map[interface{}]interface{}
+ iteratorStack []Iterator
+ options *TokeniseOptions
+ newlineAdded bool
+}
+
+// Set mutator context.
+func (l *LexerState) Set(key interface{}, value interface{}) {
+ l.MutatorContext[key] = value
+}
+
+// Get mutator context.
+func (l *LexerState) Get(key interface{}) interface{} {
+ return l.MutatorContext[key]
+}
+
+// Iterator returns the next Token from the lexer.
+func (l *LexerState) Iterator() Token { // nolint: gocognit
+ end := len(l.Text)
+ if l.newlineAdded {
+ end--
+ }
+ for l.Pos < end && len(l.Stack) > 0 {
+ // Exhaust the iterator stack, if any.
+ for len(l.iteratorStack) > 0 {
+ n := len(l.iteratorStack) - 1
+ t := l.iteratorStack[n]()
+ if t.Type == Ignore {
+ continue
+ }
+ if t == EOF {
+ l.iteratorStack = l.iteratorStack[:n]
+ continue
+ }
+ return t
+ }
+
+ l.State = l.Stack[len(l.Stack)-1]
+ if l.Lexer.trace {
+ fmt.Fprintf(os.Stderr, "%s: pos=%d, text=%q\n", l.State, l.Pos, string(l.Text[l.Pos:]))
+ }
+ selectedRule, ok := l.Rules[l.State]
+ if !ok {
+ panic("unknown state " + l.State)
+ }
+ ruleIndex, rule, groups, namedGroups := matchRules(l.Text, l.Pos, selectedRule)
+ // No match.
+ if groups == nil {
+ // From Pygments :\
+ //
+ // If the RegexLexer encounters a newline that is flagged as an error token, the stack is
+ // emptied and the lexer continues scanning in the 'root' state. This can help producing
+ // error-tolerant highlighting for erroneous input, e.g. when a single-line string is not
+ // closed.
+ if l.Text[l.Pos] == '\n' && l.State != l.options.State {
+ l.Stack = []string{l.options.State}
+ continue
+ }
+ l.Pos++
+ return Token{Error, string(l.Text[l.Pos-1 : l.Pos])}
+ }
+ l.Rule = ruleIndex
+ l.Groups = groups
+ l.NamedGroups = namedGroups
+ l.Pos += utf8.RuneCountInString(groups[0])
+ if rule.Mutator != nil {
+ if err := rule.Mutator.Mutate(l); err != nil {
+ panic(err)
+ }
+ }
+ if rule.Type != nil {
+ l.iteratorStack = append(l.iteratorStack, rule.Type.Emit(l.Groups, l))
+ }
+ }
+ // Exhaust the IteratorStack, if any.
+ // Duplicate code, but eh.
+ for len(l.iteratorStack) > 0 {
+ n := len(l.iteratorStack) - 1
+ t := l.iteratorStack[n]()
+ if t.Type == Ignore {
+ continue
+ }
+ if t == EOF {
+ l.iteratorStack = l.iteratorStack[:n]
+ continue
+ }
+ return t
+ }
+
+ // If we get to here and we still have text, return it as an error.
+ if l.Pos != len(l.Text) && len(l.Stack) == 0 {
+ value := string(l.Text[l.Pos:])
+ l.Pos = len(l.Text)
+ return Token{Type: Error, Value: value}
+ }
+ return EOF
+}
+
+// RegexLexer is the default lexer implementation used in Chroma.
+type RegexLexer struct {
+ registry *LexerRegistry // The LexerRegistry this Lexer is associated with, if any.
+ config *Config
+ analyser func(text string) float32
+ trace bool
+
+ mu sync.Mutex
+ compiled bool
+ rawRules Rules
+ rules map[string][]*CompiledRule
+ fetchRulesFunc func() (Rules, error)
+ compileOnce sync.Once
+}
+
+func (r *RegexLexer) String() string {
+ return r.config.Name
+}
+
+// Rules in the Lexer.
+func (r *RegexLexer) Rules() (Rules, error) {
+ if err := r.needRules(); err != nil {
+ return nil, err
+ }
+ return r.rawRules, nil
+}
+
+// SetRegistry the lexer will use to lookup other lexers if necessary.
+func (r *RegexLexer) SetRegistry(registry *LexerRegistry) Lexer {
+ r.registry = registry
+ return r
+}
+
+// SetAnalyser sets the analyser function used to perform content inspection.
+func (r *RegexLexer) SetAnalyser(analyser func(text string) float32) Lexer {
+ r.analyser = analyser
+ return r
+}
+
+// AnalyseText scores how likely a fragment of text is to match this lexer, between 0.0 and 1.0.
+func (r *RegexLexer) AnalyseText(text string) float32 {
+ if r.analyser != nil {
+ return r.analyser(text)
+ }
+ return 0
+}
+
+// SetConfig replaces the Config for this Lexer.
+func (r *RegexLexer) SetConfig(config *Config) *RegexLexer {
+ r.config = config
+ return r
+}
+
+// Config returns the Config for this Lexer.
+func (r *RegexLexer) Config() *Config {
+ return r.config
+}
+
+// Regex compilation is deferred until the lexer is used. This is to avoid significant init() time costs.
+func (r *RegexLexer) maybeCompile() (err error) {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+ if r.compiled {
+ return nil
+ }
+ for state, rules := range r.rules {
+ for i, rule := range rules {
+ if rule.Regexp == nil {
+ pattern := "(?:" + rule.Pattern + ")"
+ if rule.flags != "" {
+ pattern = "(?" + rule.flags + ")" + pattern
+ }
+ pattern = `\G` + pattern
+ rule.Regexp, err = regexp2.Compile(pattern, 0)
+ if err != nil {
+ return fmt.Errorf("failed to compile rule %s.%d: %s", state, i, err)
+ }
+ rule.Regexp.MatchTimeout = time.Millisecond * 250
+ }
+ }
+ }
+restart:
+ seen := map[LexerMutator]bool{}
+ for state := range r.rules {
+ for i := 0; i < len(r.rules[state]); i++ {
+ rule := r.rules[state][i]
+ if compile, ok := rule.Mutator.(LexerMutator); ok {
+ if seen[compile] {
+ return fmt.Errorf("saw mutator %T twice; this should not happen", compile)
+ }
+ seen[compile] = true
+ if err := compile.MutateLexer(r.rules, state, i); err != nil {
+ return err
+ }
+ // Process the rules again in case the mutator added/removed rules.
+ //
+ // This sounds bad, but shouldn't be significant in practice.
+ goto restart
+ }
+ }
+ }
+ r.compiled = true
+ return nil
+}
+
+func (r *RegexLexer) fetchRules() error {
+ rules, err := r.fetchRulesFunc()
+ if err != nil {
+ return fmt.Errorf("%s: failed to compile rules: %w", r.config.Name, err)
+ }
+ if _, ok := rules["root"]; !ok {
+ return fmt.Errorf("no \"root\" state")
+ }
+ compiledRules := map[string][]*CompiledRule{}
+ for state, rules := range rules {
+ compiledRules[state] = nil
+ for _, rule := range rules {
+ flags := ""
+ if !r.config.NotMultiline {
+ flags += "m"
+ }
+ if r.config.CaseInsensitive {
+ flags += "i"
+ }
+ if r.config.DotAll {
+ flags += "s"
+ }
+ compiledRules[state] = append(compiledRules[state], &CompiledRule{Rule: rule, flags: flags})
+ }
+ }
+
+ r.rawRules = rules
+ r.rules = compiledRules
+ return nil
+}
+
+func (r *RegexLexer) needRules() error {
+ var err error
+ if r.fetchRulesFunc != nil {
+ r.compileOnce.Do(func() {
+ err = r.fetchRules()
+ })
+ }
+ if err := r.maybeCompile(); err != nil {
+ return err
+ }
+ return err
+}
+
+// Tokenise text using lexer, returning an iterator.
+func (r *RegexLexer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) {
+ err := r.needRules()
+ if err != nil {
+ return nil, err
+ }
+ if options == nil {
+ options = defaultOptions
+ }
+ if options.EnsureLF {
+ text = ensureLF(text)
+ }
+ newlineAdded := false
+ if !options.Nested && r.config.EnsureNL && !strings.HasSuffix(text, "\n") {
+ text += "\n"
+ newlineAdded = true
+ }
+ state := &LexerState{
+ Registry: r.registry,
+ newlineAdded: newlineAdded,
+ options: options,
+ Lexer: r,
+ Text: []rune(text),
+ Stack: []string{options.State},
+ Rules: r.rules,
+ MutatorContext: map[interface{}]interface{}{},
+ }
+ return state.Iterator, nil
+}
+
+// MustRules is like Rules() but will panic on error.
+func (r *RegexLexer) MustRules() Rules {
+ rules, err := r.Rules()
+ if err != nil {
+ panic(err)
+ }
+ return rules
+}
+
+func matchRules(text []rune, pos int, rules []*CompiledRule) (int, *CompiledRule, []string, map[string]string) {
+ for i, rule := range rules {
+ match, err := rule.Regexp.FindRunesMatchStartingAt(text, pos)
+ if match != nil && err == nil && match.Index == pos {
+ groups := []string{}
+ namedGroups := make(map[string]string)
+ for _, g := range match.Groups() {
+ namedGroups[g.Name] = g.String()
+ groups = append(groups, g.String())
+ }
+ return i, rule, groups, namedGroups
+ }
+ }
+ return 0, &CompiledRule{}, nil, nil
+}
+
+// replace \r and \r\n with \n
+// same as strings.ReplaceAll but more efficient
+func ensureLF(text string) string {
+ buf := make([]byte, len(text))
+ var j int
+ for i := 0; i < len(text); i++ {
+ c := text[i]
+ if c == '\r' {
+ if i < len(text)-1 && text[i+1] == '\n' {
+ continue
+ }
+ c = '\n'
+ }
+ buf[j] = c
+ j++
+ }
+ return string(buf[:j])
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/registry.go b/vendor/github.com/alecthomas/chroma/v2/registry.go
new file mode 100644
index 0000000..4742e8c
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/registry.go
@@ -0,0 +1,210 @@
+package chroma
+
+import (
+ "path/filepath"
+ "sort"
+ "strings"
+)
+
+var (
+ ignoredSuffixes = [...]string{
+ // Editor backups
+ "~", ".bak", ".old", ".orig",
+ // Debian and derivatives apt/dpkg/ucf backups
+ ".dpkg-dist", ".dpkg-old", ".ucf-dist", ".ucf-new", ".ucf-old",
+ // Red Hat and derivatives rpm backups
+ ".rpmnew", ".rpmorig", ".rpmsave",
+ // Build system input/template files
+ ".in",
+ }
+)
+
+// LexerRegistry is a registry of Lexers.
+type LexerRegistry struct {
+ Lexers Lexers
+ byName map[string]Lexer
+ byAlias map[string]Lexer
+}
+
+// NewLexerRegistry creates a new LexerRegistry of Lexers.
+func NewLexerRegistry() *LexerRegistry {
+ return &LexerRegistry{
+ byName: map[string]Lexer{},
+ byAlias: map[string]Lexer{},
+ }
+}
+
+// Names of all lexers, optionally including aliases.
+func (l *LexerRegistry) Names(withAliases bool) []string {
+ out := []string{}
+ for _, lexer := range l.Lexers {
+ config := lexer.Config()
+ out = append(out, config.Name)
+ if withAliases {
+ out = append(out, config.Aliases...)
+ }
+ }
+ sort.Strings(out)
+ return out
+}
+
+// Get a Lexer by name, alias or file extension.
+func (l *LexerRegistry) Get(name string) Lexer {
+ if lexer := l.byName[name]; lexer != nil {
+ return lexer
+ }
+ if lexer := l.byAlias[name]; lexer != nil {
+ return lexer
+ }
+ if lexer := l.byName[strings.ToLower(name)]; lexer != nil {
+ return lexer
+ }
+ if lexer := l.byAlias[strings.ToLower(name)]; lexer != nil {
+ return lexer
+ }
+
+ candidates := PrioritisedLexers{}
+ // Try file extension.
+ if lexer := l.Match("filename." + name); lexer != nil {
+ candidates = append(candidates, lexer)
+ }
+ // Try exact filename.
+ if lexer := l.Match(name); lexer != nil {
+ candidates = append(candidates, lexer)
+ }
+ if len(candidates) == 0 {
+ return nil
+ }
+ sort.Sort(candidates)
+ return candidates[0]
+}
+
+// MatchMimeType attempts to find a lexer for the given MIME type.
+func (l *LexerRegistry) MatchMimeType(mimeType string) Lexer {
+ matched := PrioritisedLexers{}
+ for _, l := range l.Lexers {
+ for _, lmt := range l.Config().MimeTypes {
+ if mimeType == lmt {
+ matched = append(matched, l)
+ }
+ }
+ }
+ if len(matched) != 0 {
+ sort.Sort(matched)
+ return matched[0]
+ }
+ return nil
+}
+
+// Match returns the first lexer matching filename.
+//
+// Note that this iterates over all file patterns in all lexers, so is not fast.
+func (l *LexerRegistry) Match(filename string) Lexer {
+ filename = filepath.Base(filename)
+ matched := PrioritisedLexers{}
+ // First, try primary filename matches.
+ for _, lexer := range l.Lexers {
+ config := lexer.Config()
+ for _, glob := range config.Filenames {
+ ok, err := filepath.Match(glob, filename)
+ if err != nil { // nolint
+ panic(err)
+ } else if ok {
+ matched = append(matched, lexer)
+ } else {
+ for _, suf := range &ignoredSuffixes {
+ ok, err := filepath.Match(glob+suf, filename)
+ if err != nil {
+ panic(err)
+ } else if ok {
+ matched = append(matched, lexer)
+ break
+ }
+ }
+ }
+ }
+ }
+ if len(matched) > 0 {
+ sort.Sort(matched)
+ return matched[0]
+ }
+ matched = nil
+ // Next, try filename aliases.
+ for _, lexer := range l.Lexers {
+ config := lexer.Config()
+ for _, glob := range config.AliasFilenames {
+ ok, err := filepath.Match(glob, filename)
+ if err != nil { // nolint
+ panic(err)
+ } else if ok {
+ matched = append(matched, lexer)
+ } else {
+ for _, suf := range &ignoredSuffixes {
+ ok, err := filepath.Match(glob+suf, filename)
+ if err != nil {
+ panic(err)
+ } else if ok {
+ matched = append(matched, lexer)
+ break
+ }
+ }
+ }
+ }
+ }
+ if len(matched) > 0 {
+ sort.Sort(matched)
+ return matched[0]
+ }
+ return nil
+}
+
+// Analyse text content and return the "best" lexer..
+func (l *LexerRegistry) Analyse(text string) Lexer {
+ var picked Lexer
+ highest := float32(0.0)
+ for _, lexer := range l.Lexers {
+ if analyser, ok := lexer.(Analyser); ok {
+ weight := analyser.AnalyseText(text)
+ if weight > highest {
+ picked = lexer
+ highest = weight
+ }
+ }
+ }
+ return picked
+}
+
+// Register a Lexer with the LexerRegistry. If the lexer is already registered
+// it will be replaced.
+func (l *LexerRegistry) Register(lexer Lexer) Lexer {
+ lexer.SetRegistry(l)
+ config := lexer.Config()
+
+ l.byName[config.Name] = lexer
+ l.byName[strings.ToLower(config.Name)] = lexer
+
+ for _, alias := range config.Aliases {
+ l.byAlias[alias] = lexer
+ l.byAlias[strings.ToLower(alias)] = lexer
+ }
+
+ l.Lexers = add(l.Lexers, lexer)
+
+ return lexer
+}
+
+// add adds a lexer to a slice of lexers if it doesn't already exist, or if found will replace it.
+func add(lexers Lexers, lexer Lexer) Lexers {
+ for i, val := range lexers {
+ if val == nil {
+ continue
+ }
+
+ if val.Config().Name == lexer.Config().Name {
+ lexers[i] = lexer
+ return lexers
+ }
+ }
+
+ return append(lexers, lexer)
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/remap.go b/vendor/github.com/alecthomas/chroma/v2/remap.go
new file mode 100644
index 0000000..bcf5e66
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/remap.go
@@ -0,0 +1,94 @@
+package chroma
+
+type remappingLexer struct {
+ lexer Lexer
+ mapper func(Token) []Token
+}
+
+// RemappingLexer remaps a token to a set of, potentially empty, tokens.
+func RemappingLexer(lexer Lexer, mapper func(Token) []Token) Lexer {
+ return &remappingLexer{lexer, mapper}
+}
+
+func (r *remappingLexer) AnalyseText(text string) float32 {
+ return r.lexer.AnalyseText(text)
+}
+
+func (r *remappingLexer) SetAnalyser(analyser func(text string) float32) Lexer {
+ r.lexer.SetAnalyser(analyser)
+ return r
+}
+
+func (r *remappingLexer) SetRegistry(registry *LexerRegistry) Lexer {
+ r.lexer.SetRegistry(registry)
+ return r
+}
+
+func (r *remappingLexer) Config() *Config {
+ return r.lexer.Config()
+}
+
+func (r *remappingLexer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) {
+ it, err := r.lexer.Tokenise(options, text)
+ if err != nil {
+ return nil, err
+ }
+ var buffer []Token
+ return func() Token {
+ for {
+ if len(buffer) > 0 {
+ t := buffer[0]
+ buffer = buffer[1:]
+ return t
+ }
+ t := it()
+ if t == EOF {
+ return t
+ }
+ buffer = r.mapper(t)
+ }
+ }, nil
+}
+
+// TypeMapping defines type maps for the TypeRemappingLexer.
+type TypeMapping []struct {
+ From, To TokenType
+ Words []string
+}
+
+// TypeRemappingLexer remaps types of tokens coming from a parent Lexer.
+//
+// eg. Map "defvaralias" tokens of type NameVariable to NameFunction:
+//
+// mapping := TypeMapping{
+// {NameVariable, NameFunction, []string{"defvaralias"},
+// }
+// lexer = TypeRemappingLexer(lexer, mapping)
+func TypeRemappingLexer(lexer Lexer, mapping TypeMapping) Lexer {
+ // Lookup table for fast remapping.
+ lut := map[TokenType]map[string]TokenType{}
+ for _, rt := range mapping {
+ km, ok := lut[rt.From]
+ if !ok {
+ km = map[string]TokenType{}
+ lut[rt.From] = km
+ }
+ if len(rt.Words) == 0 {
+ km[""] = rt.To
+ } else {
+ for _, k := range rt.Words {
+ km[k] = rt.To
+ }
+ }
+ }
+ return RemappingLexer(lexer, func(t Token) []Token {
+ if k, ok := lut[t.Type]; ok {
+ if tt, ok := k[t.Value]; ok {
+ t.Type = tt
+ } else if tt, ok := k[""]; ok {
+ t.Type = tt
+ }
+ }
+ return []Token{t}
+ })
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/renovate.json5 b/vendor/github.com/alecthomas/chroma/v2/renovate.json5
new file mode 100644
index 0000000..77c7b01
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/renovate.json5
@@ -0,0 +1,18 @@
+{
+ $schema: "https://docs.renovatebot.com/renovate-schema.json",
+ extends: [
+ "config:recommended",
+ ":semanticCommits",
+ ":semanticCommitTypeAll(chore)",
+ ":semanticCommitScope(deps)",
+ "group:allNonMajor",
+ "schedule:earlyMondays", // Run once a week.
+ ],
+ packageRules: [
+ {
+ matchPackageNames: ["golangci-lint"],
+ matchManagers: ["hermit"],
+ enabled: false,
+ },
+ ],
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/serialise.go b/vendor/github.com/alecthomas/chroma/v2/serialise.go
new file mode 100644
index 0000000..645a5fa
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/serialise.go
@@ -0,0 +1,479 @@
+package chroma
+
+import (
+ "compress/gzip"
+ "encoding/xml"
+ "errors"
+ "fmt"
+ "io"
+ "io/fs"
+ "math"
+ "path/filepath"
+ "reflect"
+ "regexp"
+ "strings"
+
+ "github.com/dlclark/regexp2"
+)
+
+// Serialisation of Chroma rules to XML. The format is:
+//
+//
+//
+//
+// [<$EMITTER ...>]
+// [<$MUTATOR ...>]
+//
+//
+//
+//
+// eg. Include("String") would become:
+//
+//
+//
+//
+//
+// [null, null, {"kind": "include", "state": "String"}]
+//
+// eg. Rule{`\d+`, Text, nil} would become:
+//
+//
+//
+//
+//
+// eg. Rule{`"`, String, Push("String")}
+//
+//
+//
+//
+//
+//
+// eg. Rule{`(\w+)(\n)`, ByGroups(Keyword, Whitespace), nil},
+//
+//
+//
+//
+//
+var (
+ // ErrNotSerialisable is returned if a lexer contains Rules that cannot be serialised.
+ ErrNotSerialisable = fmt.Errorf("not serialisable")
+ emitterTemplates = func() map[string]SerialisableEmitter {
+ out := map[string]SerialisableEmitter{}
+ for _, emitter := range []SerialisableEmitter{
+ &byGroupsEmitter{},
+ &usingSelfEmitter{},
+ TokenType(0),
+ &usingEmitter{},
+ &usingByGroup{},
+ } {
+ out[emitter.EmitterKind()] = emitter
+ }
+ return out
+ }()
+ mutatorTemplates = func() map[string]SerialisableMutator {
+ out := map[string]SerialisableMutator{}
+ for _, mutator := range []SerialisableMutator{
+ &includeMutator{},
+ &combinedMutator{},
+ &multiMutator{},
+ &pushMutator{},
+ &popMutator{},
+ } {
+ out[mutator.MutatorKind()] = mutator
+ }
+ return out
+ }()
+)
+
+// fastUnmarshalConfig unmarshals only the Config from a serialised lexer.
+func fastUnmarshalConfig(from fs.FS, path string) (*Config, error) {
+ r, err := from.Open(path)
+ if err != nil {
+ return nil, err
+ }
+ defer r.Close()
+ dec := xml.NewDecoder(r)
+ for {
+ token, err := dec.Token()
+ if err != nil {
+ if errors.Is(err, io.EOF) {
+ return nil, fmt.Errorf("could not find element")
+ }
+ return nil, err
+ }
+ switch se := token.(type) {
+ case xml.StartElement:
+ if se.Name.Local != "config" {
+ break
+ }
+
+ var config Config
+ err = dec.DecodeElement(&config, &se)
+ if err != nil {
+ return nil, fmt.Errorf("%s: %w", path, err)
+ }
+ return &config, nil
+ }
+ }
+}
+
+// MustNewXMLLexer constructs a new RegexLexer from an XML file or panics.
+func MustNewXMLLexer(from fs.FS, path string) *RegexLexer {
+ lex, err := NewXMLLexer(from, path)
+ if err != nil {
+ panic(err)
+ }
+ return lex
+}
+
+// NewXMLLexer creates a new RegexLexer from a serialised RegexLexer.
+func NewXMLLexer(from fs.FS, path string) (*RegexLexer, error) {
+ config, err := fastUnmarshalConfig(from, path)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, glob := range append(config.Filenames, config.AliasFilenames...) {
+ _, err := filepath.Match(glob, "")
+ if err != nil {
+ return nil, fmt.Errorf("%s: %q is not a valid glob: %w", config.Name, glob, err)
+ }
+ }
+
+ var analyserFn func(string) float32
+
+ if config.Analyse != nil {
+ type regexAnalyse struct {
+ re *regexp2.Regexp
+ score float32
+ }
+
+ regexAnalysers := make([]regexAnalyse, 0, len(config.Analyse.Regexes))
+
+ for _, ra := range config.Analyse.Regexes {
+ re, err := regexp2.Compile(ra.Pattern, regexp2.None)
+ if err != nil {
+ return nil, fmt.Errorf("%s: %q is not a valid analyser regex: %w", config.Name, ra.Pattern, err)
+ }
+
+ regexAnalysers = append(regexAnalysers, regexAnalyse{re, ra.Score})
+ }
+
+ analyserFn = func(text string) float32 {
+ var score float32
+
+ for _, ra := range regexAnalysers {
+ ok, err := ra.re.MatchString(text)
+ if err != nil {
+ return 0
+ }
+
+ if ok && config.Analyse.First {
+ return float32(math.Min(float64(ra.score), 1.0))
+ }
+
+ if ok {
+ score += ra.score
+ }
+ }
+
+ return float32(math.Min(float64(score), 1.0))
+ }
+ }
+
+ return &RegexLexer{
+ config: config,
+ analyser: analyserFn,
+ fetchRulesFunc: func() (Rules, error) {
+ var lexer struct {
+ Config
+ Rules Rules `xml:"rules"`
+ }
+ // Try to open .xml fallback to .xml.gz
+ fr, err := from.Open(path)
+ if err != nil {
+ if errors.Is(err, fs.ErrNotExist) {
+ path += ".gz"
+ fr, err = from.Open(path)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ return nil, err
+ }
+ }
+ defer fr.Close()
+ var r io.Reader = fr
+ if strings.HasSuffix(path, ".gz") {
+ r, err = gzip.NewReader(r)
+ if err != nil {
+ return nil, fmt.Errorf("%s: %w", path, err)
+ }
+ }
+ err = xml.NewDecoder(r).Decode(&lexer)
+ if err != nil {
+ return nil, fmt.Errorf("%s: %w", path, err)
+ }
+ return lexer.Rules, nil
+ },
+ }, nil
+}
+
+// Marshal a RegexLexer to XML.
+func Marshal(l *RegexLexer) ([]byte, error) {
+ type lexer struct {
+ Config Config `xml:"config"`
+ Rules Rules `xml:"rules"`
+ }
+
+ rules, err := l.Rules()
+ if err != nil {
+ return nil, err
+ }
+ root := &lexer{
+ Config: *l.Config(),
+ Rules: rules,
+ }
+ data, err := xml.MarshalIndent(root, "", " ")
+ if err != nil {
+ return nil, err
+ }
+ re := regexp.MustCompile(`>[a-zA-Z]+>`)
+ data = re.ReplaceAll(data, []byte(`/>`))
+ return data, nil
+}
+
+// Unmarshal a RegexLexer from XML.
+func Unmarshal(data []byte) (*RegexLexer, error) {
+ type lexer struct {
+ Config Config `xml:"config"`
+ Rules Rules `xml:"rules"`
+ }
+ root := &lexer{}
+ err := xml.Unmarshal(data, root)
+ if err != nil {
+ return nil, fmt.Errorf("invalid Lexer XML: %w", err)
+ }
+ lex, err := NewLexer(&root.Config, func() Rules { return root.Rules })
+ if err != nil {
+ return nil, err
+ }
+ return lex, nil
+}
+
+func marshalMutator(e *xml.Encoder, mutator Mutator) error {
+ if mutator == nil {
+ return nil
+ }
+ smutator, ok := mutator.(SerialisableMutator)
+ if !ok {
+ return fmt.Errorf("unsupported mutator: %w", ErrNotSerialisable)
+ }
+ return e.EncodeElement(mutator, xml.StartElement{Name: xml.Name{Local: smutator.MutatorKind()}})
+}
+
+func unmarshalMutator(d *xml.Decoder, start xml.StartElement) (Mutator, error) {
+ kind := start.Name.Local
+ mutator, ok := mutatorTemplates[kind]
+ if !ok {
+ return nil, fmt.Errorf("unknown mutator %q: %w", kind, ErrNotSerialisable)
+ }
+ value, target := newFromTemplate(mutator)
+ if err := d.DecodeElement(target, &start); err != nil {
+ return nil, err
+ }
+ return value().(SerialisableMutator), nil
+}
+
+func marshalEmitter(e *xml.Encoder, emitter Emitter) error {
+ if emitter == nil {
+ return nil
+ }
+ semitter, ok := emitter.(SerialisableEmitter)
+ if !ok {
+ return fmt.Errorf("unsupported emitter %T: %w", emitter, ErrNotSerialisable)
+ }
+ return e.EncodeElement(emitter, xml.StartElement{
+ Name: xml.Name{Local: semitter.EmitterKind()},
+ })
+}
+
+func unmarshalEmitter(d *xml.Decoder, start xml.StartElement) (Emitter, error) {
+ kind := start.Name.Local
+ mutator, ok := emitterTemplates[kind]
+ if !ok {
+ return nil, fmt.Errorf("unknown emitter %q: %w", kind, ErrNotSerialisable)
+ }
+ value, target := newFromTemplate(mutator)
+ if err := d.DecodeElement(target, &start); err != nil {
+ return nil, err
+ }
+ return value().(SerialisableEmitter), nil
+}
+
+func (r Rule) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
+ start := xml.StartElement{
+ Name: xml.Name{Local: "rule"},
+ }
+ if r.Pattern != "" {
+ start.Attr = append(start.Attr, xml.Attr{
+ Name: xml.Name{Local: "pattern"},
+ Value: r.Pattern,
+ })
+ }
+ if err := e.EncodeToken(start); err != nil {
+ return err
+ }
+ if err := marshalEmitter(e, r.Type); err != nil {
+ return err
+ }
+ if err := marshalMutator(e, r.Mutator); err != nil {
+ return err
+ }
+ return e.EncodeToken(xml.EndElement{Name: start.Name})
+}
+
+func (r *Rule) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ for _, attr := range start.Attr {
+ if attr.Name.Local == "pattern" {
+ r.Pattern = attr.Value
+ break
+ }
+ }
+ for {
+ token, err := d.Token()
+ if err != nil {
+ return err
+ }
+ switch token := token.(type) {
+ case xml.StartElement:
+ mutator, err := unmarshalMutator(d, token)
+ if err != nil && !errors.Is(err, ErrNotSerialisable) {
+ return err
+ } else if err == nil {
+ if r.Mutator != nil {
+ return fmt.Errorf("duplicate mutator")
+ }
+ r.Mutator = mutator
+ continue
+ }
+ emitter, err := unmarshalEmitter(d, token)
+ if err != nil && !errors.Is(err, ErrNotSerialisable) { // nolint: gocritic
+ return err
+ } else if err == nil {
+ if r.Type != nil {
+ return fmt.Errorf("duplicate emitter")
+ }
+ r.Type = emitter
+ continue
+ } else {
+ return err
+ }
+
+ case xml.EndElement:
+ return nil
+ }
+ }
+}
+
+type xmlRuleState struct {
+ Name string `xml:"name,attr"`
+ Rules []Rule `xml:"rule"`
+}
+
+type xmlRules struct {
+ States []xmlRuleState `xml:"state"`
+}
+
+func (r Rules) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
+ xr := xmlRules{}
+ for state, rules := range r {
+ xr.States = append(xr.States, xmlRuleState{
+ Name: state,
+ Rules: rules,
+ })
+ }
+ return e.EncodeElement(xr, xml.StartElement{Name: xml.Name{Local: "rules"}})
+}
+
+func (r *Rules) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ xr := xmlRules{}
+ if err := d.DecodeElement(&xr, &start); err != nil {
+ return err
+ }
+ if *r == nil {
+ *r = Rules{}
+ }
+ for _, state := range xr.States {
+ (*r)[state.Name] = state.Rules
+ }
+ return nil
+}
+
+type xmlTokenType struct {
+ Type string `xml:"type,attr"`
+}
+
+func (t *TokenType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ el := xmlTokenType{}
+ if err := d.DecodeElement(&el, &start); err != nil {
+ return err
+ }
+ tt, err := TokenTypeString(el.Type)
+ if err != nil {
+ return err
+ }
+ *t = tt
+ return nil
+}
+
+func (t TokenType) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "type"}, Value: t.String()})
+ if err := e.EncodeToken(start); err != nil {
+ return err
+ }
+ return e.EncodeToken(xml.EndElement{Name: start.Name})
+}
+
+// This hijinks is a bit unfortunate but without it we can't deserialise into TokenType.
+func newFromTemplate(template interface{}) (value func() interface{}, target interface{}) {
+ t := reflect.TypeOf(template)
+ if t.Kind() == reflect.Ptr {
+ v := reflect.New(t.Elem())
+ return v.Interface, v.Interface()
+ }
+ v := reflect.New(t)
+ return func() interface{} { return v.Elem().Interface() }, v.Interface()
+}
+
+func (b *Emitters) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ for {
+ token, err := d.Token()
+ if err != nil {
+ return err
+ }
+ switch token := token.(type) {
+ case xml.StartElement:
+ emitter, err := unmarshalEmitter(d, token)
+ if err != nil {
+ return err
+ }
+ *b = append(*b, emitter)
+
+ case xml.EndElement:
+ return nil
+ }
+ }
+}
+
+func (b Emitters) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ if err := e.EncodeToken(start); err != nil {
+ return err
+ }
+ for _, m := range b {
+ if err := marshalEmitter(e, m); err != nil {
+ return err
+ }
+ }
+ return e.EncodeToken(xml.EndElement{Name: start.Name})
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/style.go b/vendor/github.com/alecthomas/chroma/v2/style.go
new file mode 100644
index 0000000..cc8d9a6
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/style.go
@@ -0,0 +1,481 @@
+package chroma
+
+import (
+ "encoding/xml"
+ "fmt"
+ "io"
+ "sort"
+ "strings"
+)
+
+// Trilean value for StyleEntry value inheritance.
+type Trilean uint8
+
+// Trilean states.
+const (
+ Pass Trilean = iota
+ Yes
+ No
+)
+
+func (t Trilean) String() string {
+ switch t {
+ case Yes:
+ return "Yes"
+ case No:
+ return "No"
+ default:
+ return "Pass"
+ }
+}
+
+// Prefix returns s with "no" as a prefix if Trilean is no.
+func (t Trilean) Prefix(s string) string {
+ if t == Yes {
+ return s
+ } else if t == No {
+ return "no" + s
+ }
+ return ""
+}
+
+// A StyleEntry in the Style map.
+type StyleEntry struct {
+ // Hex colours.
+ Colour Colour
+ Background Colour
+ Border Colour
+
+ Bold Trilean
+ Italic Trilean
+ Underline Trilean
+ NoInherit bool
+}
+
+func (s StyleEntry) MarshalText() ([]byte, error) {
+ return []byte(s.String()), nil
+}
+
+func (s StyleEntry) String() string {
+ out := []string{}
+ if s.Bold != Pass {
+ out = append(out, s.Bold.Prefix("bold"))
+ }
+ if s.Italic != Pass {
+ out = append(out, s.Italic.Prefix("italic"))
+ }
+ if s.Underline != Pass {
+ out = append(out, s.Underline.Prefix("underline"))
+ }
+ if s.NoInherit {
+ out = append(out, "noinherit")
+ }
+ if s.Colour.IsSet() {
+ out = append(out, s.Colour.String())
+ }
+ if s.Background.IsSet() {
+ out = append(out, "bg:"+s.Background.String())
+ }
+ if s.Border.IsSet() {
+ out = append(out, "border:"+s.Border.String())
+ }
+ return strings.Join(out, " ")
+}
+
+// Sub subtracts e from s where elements match.
+func (s StyleEntry) Sub(e StyleEntry) StyleEntry {
+ out := StyleEntry{}
+ if e.Colour != s.Colour {
+ out.Colour = s.Colour
+ }
+ if e.Background != s.Background {
+ out.Background = s.Background
+ }
+ if e.Bold != s.Bold {
+ out.Bold = s.Bold
+ }
+ if e.Italic != s.Italic {
+ out.Italic = s.Italic
+ }
+ if e.Underline != s.Underline {
+ out.Underline = s.Underline
+ }
+ if e.Border != s.Border {
+ out.Border = s.Border
+ }
+ return out
+}
+
+// Inherit styles from ancestors.
+//
+// Ancestors should be provided from oldest to newest.
+func (s StyleEntry) Inherit(ancestors ...StyleEntry) StyleEntry {
+ out := s
+ for i := len(ancestors) - 1; i >= 0; i-- {
+ if out.NoInherit {
+ return out
+ }
+ ancestor := ancestors[i]
+ if !out.Colour.IsSet() {
+ out.Colour = ancestor.Colour
+ }
+ if !out.Background.IsSet() {
+ out.Background = ancestor.Background
+ }
+ if !out.Border.IsSet() {
+ out.Border = ancestor.Border
+ }
+ if out.Bold == Pass {
+ out.Bold = ancestor.Bold
+ }
+ if out.Italic == Pass {
+ out.Italic = ancestor.Italic
+ }
+ if out.Underline == Pass {
+ out.Underline = ancestor.Underline
+ }
+ }
+ return out
+}
+
+func (s StyleEntry) IsZero() bool {
+ return s.Colour == 0 && s.Background == 0 && s.Border == 0 && s.Bold == Pass && s.Italic == Pass &&
+ s.Underline == Pass && !s.NoInherit
+}
+
+// A StyleBuilder is a mutable structure for building styles.
+//
+// Once built, a Style is immutable.
+type StyleBuilder struct {
+ entries map[TokenType]string
+ name string
+ parent *Style
+}
+
+func NewStyleBuilder(name string) *StyleBuilder {
+ return &StyleBuilder{name: name, entries: map[TokenType]string{}}
+}
+
+func (s *StyleBuilder) AddAll(entries StyleEntries) *StyleBuilder {
+ for ttype, entry := range entries {
+ s.entries[ttype] = entry
+ }
+ return s
+}
+
+func (s *StyleBuilder) Get(ttype TokenType) StyleEntry {
+ // This is less than ideal, but it's the price for not having to check errors on each Add().
+ entry, _ := ParseStyleEntry(s.entries[ttype])
+ if s.parent != nil {
+ entry = entry.Inherit(s.parent.Get(ttype))
+ }
+ return entry
+}
+
+// Add an entry to the Style map.
+//
+// See http://pygments.org/docs/styles/#style-rules for details.
+func (s *StyleBuilder) Add(ttype TokenType, entry string) *StyleBuilder { // nolint: gocyclo
+ s.entries[ttype] = entry
+ return s
+}
+
+func (s *StyleBuilder) AddEntry(ttype TokenType, entry StyleEntry) *StyleBuilder {
+ s.entries[ttype] = entry.String()
+ return s
+}
+
+// Transform passes each style entry currently defined in the builder to the supplied
+// function and saves the returned value. This can be used to adjust a style's colours;
+// see Colour's ClampBrightness function, for example.
+func (s *StyleBuilder) Transform(transform func(StyleEntry) StyleEntry) *StyleBuilder {
+ types := make(map[TokenType]struct{})
+ for tt := range s.entries {
+ types[tt] = struct{}{}
+ }
+ if s.parent != nil {
+ for _, tt := range s.parent.Types() {
+ types[tt] = struct{}{}
+ }
+ }
+ for tt := range types {
+ s.AddEntry(tt, transform(s.Get(tt)))
+ }
+ return s
+}
+
+func (s *StyleBuilder) Build() (*Style, error) {
+ style := &Style{
+ Name: s.name,
+ entries: map[TokenType]StyleEntry{},
+ parent: s.parent,
+ }
+ for ttype, descriptor := range s.entries {
+ entry, err := ParseStyleEntry(descriptor)
+ if err != nil {
+ return nil, fmt.Errorf("invalid entry for %s: %s", ttype, err)
+ }
+ style.entries[ttype] = entry
+ }
+ return style, nil
+}
+
+// StyleEntries mapping TokenType to colour definition.
+type StyleEntries map[TokenType]string
+
+// NewXMLStyle parses an XML style definition.
+func NewXMLStyle(r io.Reader) (*Style, error) {
+ dec := xml.NewDecoder(r)
+ style := &Style{}
+ return style, dec.Decode(style)
+}
+
+// MustNewXMLStyle is like NewXMLStyle but panics on error.
+func MustNewXMLStyle(r io.Reader) *Style {
+ style, err := NewXMLStyle(r)
+ if err != nil {
+ panic(err)
+ }
+ return style
+}
+
+// NewStyle creates a new style definition.
+func NewStyle(name string, entries StyleEntries) (*Style, error) {
+ return NewStyleBuilder(name).AddAll(entries).Build()
+}
+
+// MustNewStyle creates a new style or panics.
+func MustNewStyle(name string, entries StyleEntries) *Style {
+ style, err := NewStyle(name, entries)
+ if err != nil {
+ panic(err)
+ }
+ return style
+}
+
+// A Style definition.
+//
+// See http://pygments.org/docs/styles/ for details. Semantics are intended to be identical.
+type Style struct {
+ Name string
+ entries map[TokenType]StyleEntry
+ parent *Style
+}
+
+func (s *Style) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ if s.parent != nil {
+ return fmt.Errorf("cannot marshal style with parent")
+ }
+ start.Name = xml.Name{Local: "style"}
+ start.Attr = []xml.Attr{{Name: xml.Name{Local: "name"}, Value: s.Name}}
+ if err := e.EncodeToken(start); err != nil {
+ return err
+ }
+ sorted := make([]TokenType, 0, len(s.entries))
+ for ttype := range s.entries {
+ sorted = append(sorted, ttype)
+ }
+ sort.Slice(sorted, func(i, j int) bool { return sorted[i] < sorted[j] })
+ for _, ttype := range sorted {
+ entry := s.entries[ttype]
+ el := xml.StartElement{Name: xml.Name{Local: "entry"}}
+ el.Attr = []xml.Attr{
+ {Name: xml.Name{Local: "type"}, Value: ttype.String()},
+ {Name: xml.Name{Local: "style"}, Value: entry.String()},
+ }
+ if err := e.EncodeToken(el); err != nil {
+ return err
+ }
+ if err := e.EncodeToken(xml.EndElement{Name: el.Name}); err != nil {
+ return err
+ }
+ }
+ return e.EncodeToken(xml.EndElement{Name: start.Name})
+}
+
+func (s *Style) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ for _, attr := range start.Attr {
+ if attr.Name.Local == "name" {
+ s.Name = attr.Value
+ } else {
+ return fmt.Errorf("unexpected attribute %s", attr.Name.Local)
+ }
+ }
+ if s.Name == "" {
+ return fmt.Errorf("missing style name attribute")
+ }
+ s.entries = map[TokenType]StyleEntry{}
+ for {
+ tok, err := d.Token()
+ if err != nil {
+ return err
+ }
+ switch el := tok.(type) {
+ case xml.StartElement:
+ if el.Name.Local != "entry" {
+ return fmt.Errorf("unexpected element %s", el.Name.Local)
+ }
+ var ttype TokenType
+ var entry StyleEntry
+ for _, attr := range el.Attr {
+ switch attr.Name.Local {
+ case "type":
+ ttype, err = TokenTypeString(attr.Value)
+ if err != nil {
+ return err
+ }
+
+ case "style":
+ entry, err = ParseStyleEntry(attr.Value)
+ if err != nil {
+ return err
+ }
+
+ default:
+ return fmt.Errorf("unexpected attribute %s", attr.Name.Local)
+ }
+ }
+ s.entries[ttype] = entry
+
+ case xml.EndElement:
+ if el.Name.Local == start.Name.Local {
+ return nil
+ }
+ }
+ }
+}
+
+// Types that are styled.
+func (s *Style) Types() []TokenType {
+ dedupe := map[TokenType]bool{}
+ for tt := range s.entries {
+ dedupe[tt] = true
+ }
+ if s.parent != nil {
+ for _, tt := range s.parent.Types() {
+ dedupe[tt] = true
+ }
+ }
+ out := make([]TokenType, 0, len(dedupe))
+ for tt := range dedupe {
+ out = append(out, tt)
+ }
+ return out
+}
+
+// Builder creates a mutable builder from this Style.
+//
+// The builder can then be safely modified. This is a cheap operation.
+func (s *Style) Builder() *StyleBuilder {
+ return &StyleBuilder{
+ name: s.Name,
+ entries: map[TokenType]string{},
+ parent: s,
+ }
+}
+
+// Has checks if an exact style entry match exists for a token type.
+//
+// This is distinct from Get() which will merge parent tokens.
+func (s *Style) Has(ttype TokenType) bool {
+ return !s.get(ttype).IsZero() || s.synthesisable(ttype)
+}
+
+// Get a style entry. Will try sub-category or category if an exact match is not found, and
+// finally return the Background.
+func (s *Style) Get(ttype TokenType) StyleEntry {
+ return s.get(ttype).Inherit(
+ s.get(Background),
+ s.get(Text),
+ s.get(ttype.Category()),
+ s.get(ttype.SubCategory()))
+}
+
+func (s *Style) get(ttype TokenType) StyleEntry {
+ out := s.entries[ttype]
+ if out.IsZero() && s.parent != nil {
+ return s.parent.get(ttype)
+ }
+ if out.IsZero() && s.synthesisable(ttype) {
+ out = s.synthesise(ttype)
+ }
+ return out
+}
+
+func (s *Style) synthesise(ttype TokenType) StyleEntry {
+ bg := s.get(Background)
+ text := StyleEntry{Colour: bg.Colour}
+ text.Colour = text.Colour.BrightenOrDarken(0.5)
+
+ switch ttype {
+ // If we don't have a line highlight colour, make one that is 10% brighter/darker than the background.
+ case LineHighlight:
+ return StyleEntry{Background: bg.Background.BrightenOrDarken(0.1)}
+
+ // If we don't have line numbers, use the text colour but 20% brighter/darker
+ case LineNumbers, LineNumbersTable:
+ return text
+
+ default:
+ return StyleEntry{}
+ }
+}
+
+func (s *Style) synthesisable(ttype TokenType) bool {
+ return ttype == LineHighlight || ttype == LineNumbers || ttype == LineNumbersTable
+}
+
+// MustParseStyleEntry parses a Pygments style entry or panics.
+func MustParseStyleEntry(entry string) StyleEntry {
+ out, err := ParseStyleEntry(entry)
+ if err != nil {
+ panic(err)
+ }
+ return out
+}
+
+// ParseStyleEntry parses a Pygments style entry.
+func ParseStyleEntry(entry string) (StyleEntry, error) { // nolint: gocyclo
+ out := StyleEntry{}
+ parts := strings.Fields(entry)
+ for _, part := range parts {
+ switch {
+ case part == "italic":
+ out.Italic = Yes
+ case part == "noitalic":
+ out.Italic = No
+ case part == "bold":
+ out.Bold = Yes
+ case part == "nobold":
+ out.Bold = No
+ case part == "underline":
+ out.Underline = Yes
+ case part == "nounderline":
+ out.Underline = No
+ case part == "inherit":
+ out.NoInherit = false
+ case part == "noinherit":
+ out.NoInherit = true
+ case part == "bg:":
+ out.Background = 0
+ case strings.HasPrefix(part, "bg:#"):
+ out.Background = ParseColour(part[3:])
+ if !out.Background.IsSet() {
+ return StyleEntry{}, fmt.Errorf("invalid background colour %q", part)
+ }
+ case strings.HasPrefix(part, "border:#"):
+ out.Border = ParseColour(part[7:])
+ if !out.Border.IsSet() {
+ return StyleEntry{}, fmt.Errorf("invalid border colour %q", part)
+ }
+ case strings.HasPrefix(part, "#"):
+ out.Colour = ParseColour(part)
+ if !out.Colour.IsSet() {
+ return StyleEntry{}, fmt.Errorf("invalid colour %q", part)
+ }
+ default:
+ return StyleEntry{}, fmt.Errorf("unknown style element %q", part)
+ }
+ }
+ return out, nil
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/abap.xml b/vendor/github.com/alecthomas/chroma/v2/styles/abap.xml
new file mode 100644
index 0000000..36ea2f1
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/abap.xml
@@ -0,0 +1,11 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/algol.xml b/vendor/github.com/alecthomas/chroma/v2/styles/algol.xml
new file mode 100644
index 0000000..e8a6dc1
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/algol.xml
@@ -0,0 +1,18 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/algol_nu.xml b/vendor/github.com/alecthomas/chroma/v2/styles/algol_nu.xml
new file mode 100644
index 0000000..7fa340f
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/algol_nu.xml
@@ -0,0 +1,18 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/api.go b/vendor/github.com/alecthomas/chroma/v2/styles/api.go
new file mode 100644
index 0000000..e26d6f0
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/api.go
@@ -0,0 +1,65 @@
+package styles
+
+import (
+ "embed"
+ "io/fs"
+ "sort"
+
+ "github.com/alecthomas/chroma/v2"
+)
+
+//go:embed *.xml
+var embedded embed.FS
+
+// Registry of Styles.
+var Registry = func() map[string]*chroma.Style {
+ registry := map[string]*chroma.Style{}
+ // Register all embedded styles.
+ files, err := fs.ReadDir(embedded, ".")
+ if err != nil {
+ panic(err)
+ }
+ for _, file := range files {
+ if file.IsDir() {
+ continue
+ }
+ r, err := embedded.Open(file.Name())
+ if err != nil {
+ panic(err)
+ }
+ style, err := chroma.NewXMLStyle(r)
+ if err != nil {
+ panic(err)
+ }
+ registry[style.Name] = style
+ _ = r.Close()
+ }
+ return registry
+}()
+
+// Fallback style. Reassign to change the default fallback style.
+var Fallback = Registry["swapoff"]
+
+// Register a chroma.Style.
+func Register(style *chroma.Style) *chroma.Style {
+ Registry[style.Name] = style
+ return style
+}
+
+// Names of all available styles.
+func Names() []string {
+ out := []string{}
+ for name := range Registry {
+ out = append(out, name)
+ }
+ sort.Strings(out)
+ return out
+}
+
+// Get named style, or Fallback.
+func Get(name string) *chroma.Style {
+ if style, ok := Registry[name]; ok {
+ return style
+ }
+ return Fallback
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/arduino.xml b/vendor/github.com/alecthomas/chroma/v2/styles/arduino.xml
new file mode 100644
index 0000000..d9891dc
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/arduino.xml
@@ -0,0 +1,18 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/autumn.xml b/vendor/github.com/alecthomas/chroma/v2/styles/autumn.xml
new file mode 100644
index 0000000..74d2eae
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/autumn.xml
@@ -0,0 +1,36 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/average.xml b/vendor/github.com/alecthomas/chroma/v2/styles/average.xml
new file mode 100644
index 0000000..79bdb95
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/average.xml
@@ -0,0 +1,74 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/base16-snazzy.xml b/vendor/github.com/alecthomas/chroma/v2/styles/base16-snazzy.xml
new file mode 100644
index 0000000..a05ba24
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/base16-snazzy.xml
@@ -0,0 +1,74 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/borland.xml b/vendor/github.com/alecthomas/chroma/v2/styles/borland.xml
new file mode 100644
index 0000000..0d8f574
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/borland.xml
@@ -0,0 +1,26 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/bw.xml b/vendor/github.com/alecthomas/chroma/v2/styles/bw.xml
new file mode 100644
index 0000000..fb0e868
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/bw.xml
@@ -0,0 +1,23 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-frappe.xml b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-frappe.xml
new file mode 100644
index 0000000..0adf1ba
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-frappe.xml
@@ -0,0 +1,83 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-latte.xml b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-latte.xml
new file mode 100644
index 0000000..3ea767f
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-latte.xml
@@ -0,0 +1,83 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-macchiato.xml b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-macchiato.xml
new file mode 100644
index 0000000..6b50028
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-macchiato.xml
@@ -0,0 +1,83 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-mocha.xml b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-mocha.xml
new file mode 100644
index 0000000..9a40191
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-mocha.xml
@@ -0,0 +1,83 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/colorful.xml b/vendor/github.com/alecthomas/chroma/v2/styles/colorful.xml
new file mode 100644
index 0000000..32442d7
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/colorful.xml
@@ -0,0 +1,52 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/compat.go b/vendor/github.com/alecthomas/chroma/v2/styles/compat.go
new file mode 100644
index 0000000..4a6aaa6
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/compat.go
@@ -0,0 +1,66 @@
+package styles
+
+// Present for backwards compatibility.
+//
+// Deprecated: use styles.Get(name) instead.
+var (
+ Abap = Registry["abap"]
+ Algol = Registry["algol"]
+ AlgolNu = Registry["algol_nu"]
+ Arduino = Registry["arduino"]
+ Autumn = Registry["autumn"]
+ Average = Registry["average"]
+ Base16Snazzy = Registry["base16-snazzy"]
+ Borland = Registry["borland"]
+ BlackWhite = Registry["bw"]
+ CatppuccinFrappe = Registry["catppuccin-frappe"]
+ CatppuccinLatte = Registry["catppuccin-latte"]
+ CatppuccinMacchiato = Registry["catppuccin-macchiato"]
+ CatppuccinMocha = Registry["catppuccin-mocha"]
+ Colorful = Registry["colorful"]
+ DoomOne = Registry["doom-one"]
+ DoomOne2 = Registry["doom-one2"]
+ Dracula = Registry["dracula"]
+ Emacs = Registry["emacs"]
+ Friendly = Registry["friendly"]
+ Fruity = Registry["fruity"]
+ GitHubDark = Registry["github-dark"]
+ GitHub = Registry["github"]
+ GruvboxLight = Registry["gruvbox-light"]
+ Gruvbox = Registry["gruvbox"]
+ HrDark = Registry["hrdark"]
+ HrHighContrast = Registry["hr_high_contrast"]
+ Igor = Registry["igor"]
+ Lovelace = Registry["lovelace"]
+ Manni = Registry["manni"]
+ ModusOperandi = Registry["modus-operandi"]
+ ModusVivendi = Registry["modus-vivendi"]
+ Monokai = Registry["monokai"]
+ MonokaiLight = Registry["monokailight"]
+ Murphy = Registry["murphy"]
+ Native = Registry["native"]
+ Nord = Registry["nord"]
+ OnesEnterprise = Registry["onesenterprise"]
+ ParaisoDark = Registry["paraiso-dark"]
+ ParaisoLight = Registry["paraiso-light"]
+ Pastie = Registry["pastie"]
+ Perldoc = Registry["perldoc"]
+ Pygments = Registry["pygments"]
+ RainbowDash = Registry["rainbow_dash"]
+ RosePineDawn = Registry["rose-pine-dawn"]
+ RosePineMoon = Registry["rose-pine-moon"]
+ RosePine = Registry["rose-pine"]
+ Rrt = Registry["rrt"]
+ SolarizedDark = Registry["solarized-dark"]
+ SolarizedDark256 = Registry["solarized-dark256"]
+ SolarizedLight = Registry["solarized-light"]
+ SwapOff = Registry["swapoff"]
+ Tango = Registry["tango"]
+ Trac = Registry["trac"]
+ Vim = Registry["vim"]
+ VisualStudio = Registry["vs"]
+ Vulcan = Registry["vulcan"]
+ WitchHazel = Registry["witchhazel"]
+ XcodeDark = Registry["xcode-dark"]
+ Xcode = Registry["xcode"]
+)
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/doom-one.xml b/vendor/github.com/alecthomas/chroma/v2/styles/doom-one.xml
new file mode 100644
index 0000000..1f5127e
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/doom-one.xml
@@ -0,0 +1,51 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/doom-one2.xml b/vendor/github.com/alecthomas/chroma/v2/styles/doom-one2.xml
new file mode 100644
index 0000000..f47deba
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/doom-one2.xml
@@ -0,0 +1,64 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/dracula.xml b/vendor/github.com/alecthomas/chroma/v2/styles/dracula.xml
new file mode 100644
index 0000000..9df7da1
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/dracula.xml
@@ -0,0 +1,74 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/emacs.xml b/vendor/github.com/alecthomas/chroma/v2/styles/emacs.xml
new file mode 100644
index 0000000..981ce8e
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/emacs.xml
@@ -0,0 +1,44 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/evergarden.xml b/vendor/github.com/alecthomas/chroma/v2/styles/evergarden.xml
new file mode 100644
index 0000000..da1d9b8
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/evergarden.xml
@@ -0,0 +1,33 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/friendly.xml b/vendor/github.com/alecthomas/chroma/v2/styles/friendly.xml
new file mode 100644
index 0000000..f498010
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/friendly.xml
@@ -0,0 +1,44 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/fruity.xml b/vendor/github.com/alecthomas/chroma/v2/styles/fruity.xml
new file mode 100644
index 0000000..bcc06aa
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/fruity.xml
@@ -0,0 +1,19 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/github-dark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/github-dark.xml
new file mode 100644
index 0000000..711aeaf
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/github-dark.xml
@@ -0,0 +1,45 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/github.xml b/vendor/github.com/alecthomas/chroma/v2/styles/github.xml
new file mode 100644
index 0000000..d747f65
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/github.xml
@@ -0,0 +1,39 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox-light.xml b/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox-light.xml
new file mode 100644
index 0000000..8c4f064
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox-light.xml
@@ -0,0 +1,33 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox.xml b/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox.xml
new file mode 100644
index 0000000..2f6a0a2
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox.xml
@@ -0,0 +1,33 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/hr_high_contrast.xml b/vendor/github.com/alecthomas/chroma/v2/styles/hr_high_contrast.xml
new file mode 100644
index 0000000..61cde20
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/hr_high_contrast.xml
@@ -0,0 +1,12 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/hrdark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/hrdark.xml
new file mode 100644
index 0000000..bc7a6f3
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/hrdark.xml
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/igor.xml b/vendor/github.com/alecthomas/chroma/v2/styles/igor.xml
new file mode 100644
index 0000000..773c83b
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/igor.xml
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/lovelace.xml b/vendor/github.com/alecthomas/chroma/v2/styles/lovelace.xml
new file mode 100644
index 0000000..e336c93
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/lovelace.xml
@@ -0,0 +1,53 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/manni.xml b/vendor/github.com/alecthomas/chroma/v2/styles/manni.xml
new file mode 100644
index 0000000..99324bd
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/manni.xml
@@ -0,0 +1,44 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/modus-operandi.xml b/vendor/github.com/alecthomas/chroma/v2/styles/modus-operandi.xml
new file mode 100644
index 0000000..023137a
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/modus-operandi.xml
@@ -0,0 +1,13 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/modus-vivendi.xml b/vendor/github.com/alecthomas/chroma/v2/styles/modus-vivendi.xml
new file mode 100644
index 0000000..8da663d
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/modus-vivendi.xml
@@ -0,0 +1,13 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/monokai.xml b/vendor/github.com/alecthomas/chroma/v2/styles/monokai.xml
new file mode 100644
index 0000000..1a789dd
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/monokai.xml
@@ -0,0 +1,29 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/monokailight.xml b/vendor/github.com/alecthomas/chroma/v2/styles/monokailight.xml
new file mode 100644
index 0000000..85cd23e
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/monokailight.xml
@@ -0,0 +1,26 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/murphy.xml b/vendor/github.com/alecthomas/chroma/v2/styles/murphy.xml
new file mode 100644
index 0000000..112d620
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/murphy.xml
@@ -0,0 +1,52 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/native.xml b/vendor/github.com/alecthomas/chroma/v2/styles/native.xml
new file mode 100644
index 0000000..43eea7f
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/native.xml
@@ -0,0 +1,35 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/nord.xml b/vendor/github.com/alecthomas/chroma/v2/styles/nord.xml
new file mode 100644
index 0000000..1c1d1ff
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/nord.xml
@@ -0,0 +1,46 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/nordic.xml b/vendor/github.com/alecthomas/chroma/v2/styles/nordic.xml
new file mode 100644
index 0000000..4c36b8e
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/nordic.xml
@@ -0,0 +1,46 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/onedark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/onedark.xml
new file mode 100644
index 0000000..6921eb5
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/onedark.xml
@@ -0,0 +1,25 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/onesenterprise.xml b/vendor/github.com/alecthomas/chroma/v2/styles/onesenterprise.xml
new file mode 100644
index 0000000..ce86db3
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/onesenterprise.xml
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-dark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-dark.xml
new file mode 100644
index 0000000..788db3f
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-dark.xml
@@ -0,0 +1,37 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-light.xml b/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-light.xml
new file mode 100644
index 0000000..06a63ba
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-light.xml
@@ -0,0 +1,37 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/pastie.xml b/vendor/github.com/alecthomas/chroma/v2/styles/pastie.xml
new file mode 100644
index 0000000..a3b0abd
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/pastie.xml
@@ -0,0 +1,45 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/perldoc.xml b/vendor/github.com/alecthomas/chroma/v2/styles/perldoc.xml
new file mode 100644
index 0000000..9e5564c
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/perldoc.xml
@@ -0,0 +1,37 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/pygments.xml b/vendor/github.com/alecthomas/chroma/v2/styles/pygments.xml
new file mode 100644
index 0000000..a3d0d8b
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/pygments.xml
@@ -0,0 +1,42 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/rainbow_dash.xml b/vendor/github.com/alecthomas/chroma/v2/styles/rainbow_dash.xml
new file mode 100644
index 0000000..5b0fe49
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/rainbow_dash.xml
@@ -0,0 +1,40 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-dawn.xml b/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-dawn.xml
new file mode 100644
index 0000000..788bd6f
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-dawn.xml
@@ -0,0 +1,29 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-moon.xml b/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-moon.xml
new file mode 100644
index 0000000..f67b804
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-moon.xml
@@ -0,0 +1,29 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine.xml b/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine.xml
new file mode 100644
index 0000000..3fb70a5
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine.xml
@@ -0,0 +1,29 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/rrt.xml b/vendor/github.com/alecthomas/chroma/v2/styles/rrt.xml
new file mode 100644
index 0000000..5f1daaa
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/rrt.xml
@@ -0,0 +1,13 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark.xml
new file mode 100644
index 0000000..a3cf46f
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark.xml
@@ -0,0 +1,39 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark256.xml b/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark256.xml
new file mode 100644
index 0000000..977cfbe
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark256.xml
@@ -0,0 +1,41 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/solarized-light.xml b/vendor/github.com/alecthomas/chroma/v2/styles/solarized-light.xml
new file mode 100644
index 0000000..4fbc1d4
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/solarized-light.xml
@@ -0,0 +1,17 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/swapoff.xml b/vendor/github.com/alecthomas/chroma/v2/styles/swapoff.xml
new file mode 100644
index 0000000..8a398df
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/swapoff.xml
@@ -0,0 +1,18 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/tango.xml b/vendor/github.com/alecthomas/chroma/v2/styles/tango.xml
new file mode 100644
index 0000000..5ca46bb
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/tango.xml
@@ -0,0 +1,72 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-day.xml b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-day.xml
new file mode 100644
index 0000000..c20d9a4
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-day.xml
@@ -0,0 +1,83 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-moon.xml b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-moon.xml
new file mode 100644
index 0000000..3312f02
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-moon.xml
@@ -0,0 +1,83 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-night.xml b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-night.xml
new file mode 100644
index 0000000..c798bad
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-night.xml
@@ -0,0 +1,83 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-storm.xml b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-storm.xml
new file mode 100644
index 0000000..c081152
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-storm.xml
@@ -0,0 +1,83 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/trac.xml b/vendor/github.com/alecthomas/chroma/v2/styles/trac.xml
new file mode 100644
index 0000000..9f1d266
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/trac.xml
@@ -0,0 +1,35 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/vim.xml b/vendor/github.com/alecthomas/chroma/v2/styles/vim.xml
new file mode 100644
index 0000000..fec6934
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/vim.xml
@@ -0,0 +1,29 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/vs.xml b/vendor/github.com/alecthomas/chroma/v2/styles/vs.xml
new file mode 100644
index 0000000..5643501
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/vs.xml
@@ -0,0 +1,16 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/vulcan.xml b/vendor/github.com/alecthomas/chroma/v2/styles/vulcan.xml
new file mode 100644
index 0000000..4e69094
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/vulcan.xml
@@ -0,0 +1,74 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/witchhazel.xml b/vendor/github.com/alecthomas/chroma/v2/styles/witchhazel.xml
new file mode 100644
index 0000000..52f2299
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/witchhazel.xml
@@ -0,0 +1,31 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/xcode-dark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/xcode-dark.xml
new file mode 100644
index 0000000..9343979
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/xcode-dark.xml
@@ -0,0 +1,31 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/xcode.xml b/vendor/github.com/alecthomas/chroma/v2/styles/xcode.xml
new file mode 100644
index 0000000..523d746
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/xcode.xml
@@ -0,0 +1,22 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/table.py b/vendor/github.com/alecthomas/chroma/v2/table.py
new file mode 100644
index 0000000..ea4b755
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/table.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+import re
+from collections import defaultdict
+from subprocess import check_output
+
+README_FILE = "README.md"
+
+lines = check_output(["chroma", "--list"]).decode("utf-8").splitlines()
+lines = [line.strip() for line in lines if line.startswith(" ") and not line.startswith(" ")]
+lines = sorted(lines, key=lambda l: l.lower())
+
+table = defaultdict(list)
+
+for line in lines:
+ table[line[0].upper()].append(line)
+
+rows = []
+for key, value in table.items():
+ rows.append("{} | {}".format(key, ", ".join(value)))
+tbody = "\n".join(rows)
+
+with open(README_FILE, "r") as f:
+ content = f.read()
+
+with open(README_FILE, "w") as f:
+ marker = re.compile(r"(?P:----: \\| --------\n).*?(?P\n\n)", re.DOTALL)
+ replacement = r"\g%s\g" % tbody
+ updated_content = marker.sub(replacement, content)
+ f.write(updated_content)
+
+print(tbody)
diff --git a/vendor/github.com/alecthomas/chroma/v2/tokentype_enumer.go b/vendor/github.com/alecthomas/chroma/v2/tokentype_enumer.go
new file mode 100644
index 0000000..3024264
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/tokentype_enumer.go
@@ -0,0 +1,583 @@
+// Code generated by "enumer -text -type TokenType"; DO NOT EDIT.
+
+package chroma
+
+import (
+ "fmt"
+ "strings"
+)
+
+const _TokenTypeName = "IgnoreNoneOtherErrorCodeLineLineLinkLineTableTDLineTableLineHighlightLineNumbersTableLineNumbersLinePreWrapperBackgroundEOFTypeKeywordKeywordConstantKeywordDeclarationKeywordNamespaceKeywordPseudoKeywordReservedKeywordTypeNameNameAttributeNameBuiltinNameBuiltinPseudoNameClassNameConstantNameDecoratorNameEntityNameExceptionNameFunctionNameFunctionMagicNameKeywordNameLabelNameNamespaceNameOperatorNameOtherNamePseudoNamePropertyNameTagNameVariableNameVariableAnonymousNameVariableClassNameVariableGlobalNameVariableInstanceNameVariableMagicLiteralLiteralDateLiteralOtherLiteralStringLiteralStringAffixLiteralStringAtomLiteralStringBacktickLiteralStringBooleanLiteralStringCharLiteralStringDelimiterLiteralStringDocLiteralStringDoubleLiteralStringEscapeLiteralStringHeredocLiteralStringInterpolLiteralStringNameLiteralStringOtherLiteralStringRegexLiteralStringSingleLiteralStringSymbolLiteralNumberLiteralNumberBinLiteralNumberFloatLiteralNumberHexLiteralNumberIntegerLiteralNumberIntegerLongLiteralNumberOctLiteralNumberByteOperatorOperatorWordPunctuationCommentCommentHashbangCommentMultilineCommentSingleCommentSpecialCommentPreprocCommentPreprocFileGenericGenericDeletedGenericEmphGenericErrorGenericHeadingGenericInsertedGenericOutputGenericPromptGenericStrongGenericSubheadingGenericTracebackGenericUnderlineTextTextWhitespaceTextSymbolTextPunctuation"
+const _TokenTypeLowerName = "ignorenoneothererrorcodelinelinelinklinetabletdlinetablelinehighlightlinenumberstablelinenumberslineprewrapperbackgroundeoftypekeywordkeywordconstantkeyworddeclarationkeywordnamespacekeywordpseudokeywordreservedkeywordtypenamenameattributenamebuiltinnamebuiltinpseudonameclassnameconstantnamedecoratornameentitynameexceptionnamefunctionnamefunctionmagicnamekeywordnamelabelnamenamespacenameoperatornameothernamepseudonamepropertynametagnamevariablenamevariableanonymousnamevariableclassnamevariableglobalnamevariableinstancenamevariablemagicliteralliteraldateliteralotherliteralstringliteralstringaffixliteralstringatomliteralstringbacktickliteralstringbooleanliteralstringcharliteralstringdelimiterliteralstringdocliteralstringdoubleliteralstringescapeliteralstringheredocliteralstringinterpolliteralstringnameliteralstringotherliteralstringregexliteralstringsingleliteralstringsymbolliteralnumberliteralnumberbinliteralnumberfloatliteralnumberhexliteralnumberintegerliteralnumberintegerlongliteralnumberoctliteralnumberbyteoperatoroperatorwordpunctuationcommentcommenthashbangcommentmultilinecommentsinglecommentspecialcommentpreproccommentpreprocfilegenericgenericdeletedgenericemphgenericerrorgenericheadinggenericinsertedgenericoutputgenericpromptgenericstronggenericsubheadinggenerictracebackgenericunderlinetexttextwhitespacetextsymboltextpunctuation"
+
+var _TokenTypeMap = map[TokenType]string{
+ -14: _TokenTypeName[0:6],
+ -13: _TokenTypeName[6:10],
+ -12: _TokenTypeName[10:15],
+ -11: _TokenTypeName[15:20],
+ -10: _TokenTypeName[20:28],
+ -9: _TokenTypeName[28:36],
+ -8: _TokenTypeName[36:47],
+ -7: _TokenTypeName[47:56],
+ -6: _TokenTypeName[56:69],
+ -5: _TokenTypeName[69:85],
+ -4: _TokenTypeName[85:96],
+ -3: _TokenTypeName[96:100],
+ -2: _TokenTypeName[100:110],
+ -1: _TokenTypeName[110:120],
+ 0: _TokenTypeName[120:127],
+ 1000: _TokenTypeName[127:134],
+ 1001: _TokenTypeName[134:149],
+ 1002: _TokenTypeName[149:167],
+ 1003: _TokenTypeName[167:183],
+ 1004: _TokenTypeName[183:196],
+ 1005: _TokenTypeName[196:211],
+ 1006: _TokenTypeName[211:222],
+ 2000: _TokenTypeName[222:226],
+ 2001: _TokenTypeName[226:239],
+ 2002: _TokenTypeName[239:250],
+ 2003: _TokenTypeName[250:267],
+ 2004: _TokenTypeName[267:276],
+ 2005: _TokenTypeName[276:288],
+ 2006: _TokenTypeName[288:301],
+ 2007: _TokenTypeName[301:311],
+ 2008: _TokenTypeName[311:324],
+ 2009: _TokenTypeName[324:336],
+ 2010: _TokenTypeName[336:353],
+ 2011: _TokenTypeName[353:364],
+ 2012: _TokenTypeName[364:373],
+ 2013: _TokenTypeName[373:386],
+ 2014: _TokenTypeName[386:398],
+ 2015: _TokenTypeName[398:407],
+ 2016: _TokenTypeName[407:417],
+ 2017: _TokenTypeName[417:429],
+ 2018: _TokenTypeName[429:436],
+ 2019: _TokenTypeName[436:448],
+ 2020: _TokenTypeName[448:469],
+ 2021: _TokenTypeName[469:486],
+ 2022: _TokenTypeName[486:504],
+ 2023: _TokenTypeName[504:524],
+ 2024: _TokenTypeName[524:541],
+ 3000: _TokenTypeName[541:548],
+ 3001: _TokenTypeName[548:559],
+ 3002: _TokenTypeName[559:571],
+ 3100: _TokenTypeName[571:584],
+ 3101: _TokenTypeName[584:602],
+ 3102: _TokenTypeName[602:619],
+ 3103: _TokenTypeName[619:640],
+ 3104: _TokenTypeName[640:660],
+ 3105: _TokenTypeName[660:677],
+ 3106: _TokenTypeName[677:699],
+ 3107: _TokenTypeName[699:715],
+ 3108: _TokenTypeName[715:734],
+ 3109: _TokenTypeName[734:753],
+ 3110: _TokenTypeName[753:773],
+ 3111: _TokenTypeName[773:794],
+ 3112: _TokenTypeName[794:811],
+ 3113: _TokenTypeName[811:829],
+ 3114: _TokenTypeName[829:847],
+ 3115: _TokenTypeName[847:866],
+ 3116: _TokenTypeName[866:885],
+ 3200: _TokenTypeName[885:898],
+ 3201: _TokenTypeName[898:914],
+ 3202: _TokenTypeName[914:932],
+ 3203: _TokenTypeName[932:948],
+ 3204: _TokenTypeName[948:968],
+ 3205: _TokenTypeName[968:992],
+ 3206: _TokenTypeName[992:1008],
+ 3207: _TokenTypeName[1008:1025],
+ 4000: _TokenTypeName[1025:1033],
+ 4001: _TokenTypeName[1033:1045],
+ 5000: _TokenTypeName[1045:1056],
+ 6000: _TokenTypeName[1056:1063],
+ 6001: _TokenTypeName[1063:1078],
+ 6002: _TokenTypeName[1078:1094],
+ 6003: _TokenTypeName[1094:1107],
+ 6004: _TokenTypeName[1107:1121],
+ 6100: _TokenTypeName[1121:1135],
+ 6101: _TokenTypeName[1135:1153],
+ 7000: _TokenTypeName[1153:1160],
+ 7001: _TokenTypeName[1160:1174],
+ 7002: _TokenTypeName[1174:1185],
+ 7003: _TokenTypeName[1185:1197],
+ 7004: _TokenTypeName[1197:1211],
+ 7005: _TokenTypeName[1211:1226],
+ 7006: _TokenTypeName[1226:1239],
+ 7007: _TokenTypeName[1239:1252],
+ 7008: _TokenTypeName[1252:1265],
+ 7009: _TokenTypeName[1265:1282],
+ 7010: _TokenTypeName[1282:1298],
+ 7011: _TokenTypeName[1298:1314],
+ 8000: _TokenTypeName[1314:1318],
+ 8001: _TokenTypeName[1318:1332],
+ 8002: _TokenTypeName[1332:1342],
+ 8003: _TokenTypeName[1342:1357],
+}
+
+func (i TokenType) String() string {
+ if str, ok := _TokenTypeMap[i]; ok {
+ return str
+ }
+ return fmt.Sprintf("TokenType(%d)", i)
+}
+
+// An "invalid array index" compiler error signifies that the constant values have changed.
+// Re-run the stringer command to generate them again.
+func _TokenTypeNoOp() {
+ var x [1]struct{}
+ _ = x[Ignore-(-14)]
+ _ = x[None-(-13)]
+ _ = x[Other-(-12)]
+ _ = x[Error-(-11)]
+ _ = x[CodeLine-(-10)]
+ _ = x[LineLink-(-9)]
+ _ = x[LineTableTD-(-8)]
+ _ = x[LineTable-(-7)]
+ _ = x[LineHighlight-(-6)]
+ _ = x[LineNumbersTable-(-5)]
+ _ = x[LineNumbers-(-4)]
+ _ = x[Line-(-3)]
+ _ = x[PreWrapper-(-2)]
+ _ = x[Background-(-1)]
+ _ = x[EOFType-(0)]
+ _ = x[Keyword-(1000)]
+ _ = x[KeywordConstant-(1001)]
+ _ = x[KeywordDeclaration-(1002)]
+ _ = x[KeywordNamespace-(1003)]
+ _ = x[KeywordPseudo-(1004)]
+ _ = x[KeywordReserved-(1005)]
+ _ = x[KeywordType-(1006)]
+ _ = x[Name-(2000)]
+ _ = x[NameAttribute-(2001)]
+ _ = x[NameBuiltin-(2002)]
+ _ = x[NameBuiltinPseudo-(2003)]
+ _ = x[NameClass-(2004)]
+ _ = x[NameConstant-(2005)]
+ _ = x[NameDecorator-(2006)]
+ _ = x[NameEntity-(2007)]
+ _ = x[NameException-(2008)]
+ _ = x[NameFunction-(2009)]
+ _ = x[NameFunctionMagic-(2010)]
+ _ = x[NameKeyword-(2011)]
+ _ = x[NameLabel-(2012)]
+ _ = x[NameNamespace-(2013)]
+ _ = x[NameOperator-(2014)]
+ _ = x[NameOther-(2015)]
+ _ = x[NamePseudo-(2016)]
+ _ = x[NameProperty-(2017)]
+ _ = x[NameTag-(2018)]
+ _ = x[NameVariable-(2019)]
+ _ = x[NameVariableAnonymous-(2020)]
+ _ = x[NameVariableClass-(2021)]
+ _ = x[NameVariableGlobal-(2022)]
+ _ = x[NameVariableInstance-(2023)]
+ _ = x[NameVariableMagic-(2024)]
+ _ = x[Literal-(3000)]
+ _ = x[LiteralDate-(3001)]
+ _ = x[LiteralOther-(3002)]
+ _ = x[LiteralString-(3100)]
+ _ = x[LiteralStringAffix-(3101)]
+ _ = x[LiteralStringAtom-(3102)]
+ _ = x[LiteralStringBacktick-(3103)]
+ _ = x[LiteralStringBoolean-(3104)]
+ _ = x[LiteralStringChar-(3105)]
+ _ = x[LiteralStringDelimiter-(3106)]
+ _ = x[LiteralStringDoc-(3107)]
+ _ = x[LiteralStringDouble-(3108)]
+ _ = x[LiteralStringEscape-(3109)]
+ _ = x[LiteralStringHeredoc-(3110)]
+ _ = x[LiteralStringInterpol-(3111)]
+ _ = x[LiteralStringName-(3112)]
+ _ = x[LiteralStringOther-(3113)]
+ _ = x[LiteralStringRegex-(3114)]
+ _ = x[LiteralStringSingle-(3115)]
+ _ = x[LiteralStringSymbol-(3116)]
+ _ = x[LiteralNumber-(3200)]
+ _ = x[LiteralNumberBin-(3201)]
+ _ = x[LiteralNumberFloat-(3202)]
+ _ = x[LiteralNumberHex-(3203)]
+ _ = x[LiteralNumberInteger-(3204)]
+ _ = x[LiteralNumberIntegerLong-(3205)]
+ _ = x[LiteralNumberOct-(3206)]
+ _ = x[LiteralNumberByte-(3207)]
+ _ = x[Operator-(4000)]
+ _ = x[OperatorWord-(4001)]
+ _ = x[Punctuation-(5000)]
+ _ = x[Comment-(6000)]
+ _ = x[CommentHashbang-(6001)]
+ _ = x[CommentMultiline-(6002)]
+ _ = x[CommentSingle-(6003)]
+ _ = x[CommentSpecial-(6004)]
+ _ = x[CommentPreproc-(6100)]
+ _ = x[CommentPreprocFile-(6101)]
+ _ = x[Generic-(7000)]
+ _ = x[GenericDeleted-(7001)]
+ _ = x[GenericEmph-(7002)]
+ _ = x[GenericError-(7003)]
+ _ = x[GenericHeading-(7004)]
+ _ = x[GenericInserted-(7005)]
+ _ = x[GenericOutput-(7006)]
+ _ = x[GenericPrompt-(7007)]
+ _ = x[GenericStrong-(7008)]
+ _ = x[GenericSubheading-(7009)]
+ _ = x[GenericTraceback-(7010)]
+ _ = x[GenericUnderline-(7011)]
+ _ = x[Text-(8000)]
+ _ = x[TextWhitespace-(8001)]
+ _ = x[TextSymbol-(8002)]
+ _ = x[TextPunctuation-(8003)]
+}
+
+var _TokenTypeValues = []TokenType{Ignore, None, Other, Error, CodeLine, LineLink, LineTableTD, LineTable, LineHighlight, LineNumbersTable, LineNumbers, Line, PreWrapper, Background, EOFType, Keyword, KeywordConstant, KeywordDeclaration, KeywordNamespace, KeywordPseudo, KeywordReserved, KeywordType, Name, NameAttribute, NameBuiltin, NameBuiltinPseudo, NameClass, NameConstant, NameDecorator, NameEntity, NameException, NameFunction, NameFunctionMagic, NameKeyword, NameLabel, NameNamespace, NameOperator, NameOther, NamePseudo, NameProperty, NameTag, NameVariable, NameVariableAnonymous, NameVariableClass, NameVariableGlobal, NameVariableInstance, NameVariableMagic, Literal, LiteralDate, LiteralOther, LiteralString, LiteralStringAffix, LiteralStringAtom, LiteralStringBacktick, LiteralStringBoolean, LiteralStringChar, LiteralStringDelimiter, LiteralStringDoc, LiteralStringDouble, LiteralStringEscape, LiteralStringHeredoc, LiteralStringInterpol, LiteralStringName, LiteralStringOther, LiteralStringRegex, LiteralStringSingle, LiteralStringSymbol, LiteralNumber, LiteralNumberBin, LiteralNumberFloat, LiteralNumberHex, LiteralNumberInteger, LiteralNumberIntegerLong, LiteralNumberOct, LiteralNumberByte, Operator, OperatorWord, Punctuation, Comment, CommentHashbang, CommentMultiline, CommentSingle, CommentSpecial, CommentPreproc, CommentPreprocFile, Generic, GenericDeleted, GenericEmph, GenericError, GenericHeading, GenericInserted, GenericOutput, GenericPrompt, GenericStrong, GenericSubheading, GenericTraceback, GenericUnderline, Text, TextWhitespace, TextSymbol, TextPunctuation}
+
+var _TokenTypeNameToValueMap = map[string]TokenType{
+ _TokenTypeName[0:6]: Ignore,
+ _TokenTypeLowerName[0:6]: Ignore,
+ _TokenTypeName[6:10]: None,
+ _TokenTypeLowerName[6:10]: None,
+ _TokenTypeName[10:15]: Other,
+ _TokenTypeLowerName[10:15]: Other,
+ _TokenTypeName[15:20]: Error,
+ _TokenTypeLowerName[15:20]: Error,
+ _TokenTypeName[20:28]: CodeLine,
+ _TokenTypeLowerName[20:28]: CodeLine,
+ _TokenTypeName[28:36]: LineLink,
+ _TokenTypeLowerName[28:36]: LineLink,
+ _TokenTypeName[36:47]: LineTableTD,
+ _TokenTypeLowerName[36:47]: LineTableTD,
+ _TokenTypeName[47:56]: LineTable,
+ _TokenTypeLowerName[47:56]: LineTable,
+ _TokenTypeName[56:69]: LineHighlight,
+ _TokenTypeLowerName[56:69]: LineHighlight,
+ _TokenTypeName[69:85]: LineNumbersTable,
+ _TokenTypeLowerName[69:85]: LineNumbersTable,
+ _TokenTypeName[85:96]: LineNumbers,
+ _TokenTypeLowerName[85:96]: LineNumbers,
+ _TokenTypeName[96:100]: Line,
+ _TokenTypeLowerName[96:100]: Line,
+ _TokenTypeName[100:110]: PreWrapper,
+ _TokenTypeLowerName[100:110]: PreWrapper,
+ _TokenTypeName[110:120]: Background,
+ _TokenTypeLowerName[110:120]: Background,
+ _TokenTypeName[120:127]: EOFType,
+ _TokenTypeLowerName[120:127]: EOFType,
+ _TokenTypeName[127:134]: Keyword,
+ _TokenTypeLowerName[127:134]: Keyword,
+ _TokenTypeName[134:149]: KeywordConstant,
+ _TokenTypeLowerName[134:149]: KeywordConstant,
+ _TokenTypeName[149:167]: KeywordDeclaration,
+ _TokenTypeLowerName[149:167]: KeywordDeclaration,
+ _TokenTypeName[167:183]: KeywordNamespace,
+ _TokenTypeLowerName[167:183]: KeywordNamespace,
+ _TokenTypeName[183:196]: KeywordPseudo,
+ _TokenTypeLowerName[183:196]: KeywordPseudo,
+ _TokenTypeName[196:211]: KeywordReserved,
+ _TokenTypeLowerName[196:211]: KeywordReserved,
+ _TokenTypeName[211:222]: KeywordType,
+ _TokenTypeLowerName[211:222]: KeywordType,
+ _TokenTypeName[222:226]: Name,
+ _TokenTypeLowerName[222:226]: Name,
+ _TokenTypeName[226:239]: NameAttribute,
+ _TokenTypeLowerName[226:239]: NameAttribute,
+ _TokenTypeName[239:250]: NameBuiltin,
+ _TokenTypeLowerName[239:250]: NameBuiltin,
+ _TokenTypeName[250:267]: NameBuiltinPseudo,
+ _TokenTypeLowerName[250:267]: NameBuiltinPseudo,
+ _TokenTypeName[267:276]: NameClass,
+ _TokenTypeLowerName[267:276]: NameClass,
+ _TokenTypeName[276:288]: NameConstant,
+ _TokenTypeLowerName[276:288]: NameConstant,
+ _TokenTypeName[288:301]: NameDecorator,
+ _TokenTypeLowerName[288:301]: NameDecorator,
+ _TokenTypeName[301:311]: NameEntity,
+ _TokenTypeLowerName[301:311]: NameEntity,
+ _TokenTypeName[311:324]: NameException,
+ _TokenTypeLowerName[311:324]: NameException,
+ _TokenTypeName[324:336]: NameFunction,
+ _TokenTypeLowerName[324:336]: NameFunction,
+ _TokenTypeName[336:353]: NameFunctionMagic,
+ _TokenTypeLowerName[336:353]: NameFunctionMagic,
+ _TokenTypeName[353:364]: NameKeyword,
+ _TokenTypeLowerName[353:364]: NameKeyword,
+ _TokenTypeName[364:373]: NameLabel,
+ _TokenTypeLowerName[364:373]: NameLabel,
+ _TokenTypeName[373:386]: NameNamespace,
+ _TokenTypeLowerName[373:386]: NameNamespace,
+ _TokenTypeName[386:398]: NameOperator,
+ _TokenTypeLowerName[386:398]: NameOperator,
+ _TokenTypeName[398:407]: NameOther,
+ _TokenTypeLowerName[398:407]: NameOther,
+ _TokenTypeName[407:417]: NamePseudo,
+ _TokenTypeLowerName[407:417]: NamePseudo,
+ _TokenTypeName[417:429]: NameProperty,
+ _TokenTypeLowerName[417:429]: NameProperty,
+ _TokenTypeName[429:436]: NameTag,
+ _TokenTypeLowerName[429:436]: NameTag,
+ _TokenTypeName[436:448]: NameVariable,
+ _TokenTypeLowerName[436:448]: NameVariable,
+ _TokenTypeName[448:469]: NameVariableAnonymous,
+ _TokenTypeLowerName[448:469]: NameVariableAnonymous,
+ _TokenTypeName[469:486]: NameVariableClass,
+ _TokenTypeLowerName[469:486]: NameVariableClass,
+ _TokenTypeName[486:504]: NameVariableGlobal,
+ _TokenTypeLowerName[486:504]: NameVariableGlobal,
+ _TokenTypeName[504:524]: NameVariableInstance,
+ _TokenTypeLowerName[504:524]: NameVariableInstance,
+ _TokenTypeName[524:541]: NameVariableMagic,
+ _TokenTypeLowerName[524:541]: NameVariableMagic,
+ _TokenTypeName[541:548]: Literal,
+ _TokenTypeLowerName[541:548]: Literal,
+ _TokenTypeName[548:559]: LiteralDate,
+ _TokenTypeLowerName[548:559]: LiteralDate,
+ _TokenTypeName[559:571]: LiteralOther,
+ _TokenTypeLowerName[559:571]: LiteralOther,
+ _TokenTypeName[571:584]: LiteralString,
+ _TokenTypeLowerName[571:584]: LiteralString,
+ _TokenTypeName[584:602]: LiteralStringAffix,
+ _TokenTypeLowerName[584:602]: LiteralStringAffix,
+ _TokenTypeName[602:619]: LiteralStringAtom,
+ _TokenTypeLowerName[602:619]: LiteralStringAtom,
+ _TokenTypeName[619:640]: LiteralStringBacktick,
+ _TokenTypeLowerName[619:640]: LiteralStringBacktick,
+ _TokenTypeName[640:660]: LiteralStringBoolean,
+ _TokenTypeLowerName[640:660]: LiteralStringBoolean,
+ _TokenTypeName[660:677]: LiteralStringChar,
+ _TokenTypeLowerName[660:677]: LiteralStringChar,
+ _TokenTypeName[677:699]: LiteralStringDelimiter,
+ _TokenTypeLowerName[677:699]: LiteralStringDelimiter,
+ _TokenTypeName[699:715]: LiteralStringDoc,
+ _TokenTypeLowerName[699:715]: LiteralStringDoc,
+ _TokenTypeName[715:734]: LiteralStringDouble,
+ _TokenTypeLowerName[715:734]: LiteralStringDouble,
+ _TokenTypeName[734:753]: LiteralStringEscape,
+ _TokenTypeLowerName[734:753]: LiteralStringEscape,
+ _TokenTypeName[753:773]: LiteralStringHeredoc,
+ _TokenTypeLowerName[753:773]: LiteralStringHeredoc,
+ _TokenTypeName[773:794]: LiteralStringInterpol,
+ _TokenTypeLowerName[773:794]: LiteralStringInterpol,
+ _TokenTypeName[794:811]: LiteralStringName,
+ _TokenTypeLowerName[794:811]: LiteralStringName,
+ _TokenTypeName[811:829]: LiteralStringOther,
+ _TokenTypeLowerName[811:829]: LiteralStringOther,
+ _TokenTypeName[829:847]: LiteralStringRegex,
+ _TokenTypeLowerName[829:847]: LiteralStringRegex,
+ _TokenTypeName[847:866]: LiteralStringSingle,
+ _TokenTypeLowerName[847:866]: LiteralStringSingle,
+ _TokenTypeName[866:885]: LiteralStringSymbol,
+ _TokenTypeLowerName[866:885]: LiteralStringSymbol,
+ _TokenTypeName[885:898]: LiteralNumber,
+ _TokenTypeLowerName[885:898]: LiteralNumber,
+ _TokenTypeName[898:914]: LiteralNumberBin,
+ _TokenTypeLowerName[898:914]: LiteralNumberBin,
+ _TokenTypeName[914:932]: LiteralNumberFloat,
+ _TokenTypeLowerName[914:932]: LiteralNumberFloat,
+ _TokenTypeName[932:948]: LiteralNumberHex,
+ _TokenTypeLowerName[932:948]: LiteralNumberHex,
+ _TokenTypeName[948:968]: LiteralNumberInteger,
+ _TokenTypeLowerName[948:968]: LiteralNumberInteger,
+ _TokenTypeName[968:992]: LiteralNumberIntegerLong,
+ _TokenTypeLowerName[968:992]: LiteralNumberIntegerLong,
+ _TokenTypeName[992:1008]: LiteralNumberOct,
+ _TokenTypeLowerName[992:1008]: LiteralNumberOct,
+ _TokenTypeName[1008:1025]: LiteralNumberByte,
+ _TokenTypeLowerName[1008:1025]: LiteralNumberByte,
+ _TokenTypeName[1025:1033]: Operator,
+ _TokenTypeLowerName[1025:1033]: Operator,
+ _TokenTypeName[1033:1045]: OperatorWord,
+ _TokenTypeLowerName[1033:1045]: OperatorWord,
+ _TokenTypeName[1045:1056]: Punctuation,
+ _TokenTypeLowerName[1045:1056]: Punctuation,
+ _TokenTypeName[1056:1063]: Comment,
+ _TokenTypeLowerName[1056:1063]: Comment,
+ _TokenTypeName[1063:1078]: CommentHashbang,
+ _TokenTypeLowerName[1063:1078]: CommentHashbang,
+ _TokenTypeName[1078:1094]: CommentMultiline,
+ _TokenTypeLowerName[1078:1094]: CommentMultiline,
+ _TokenTypeName[1094:1107]: CommentSingle,
+ _TokenTypeLowerName[1094:1107]: CommentSingle,
+ _TokenTypeName[1107:1121]: CommentSpecial,
+ _TokenTypeLowerName[1107:1121]: CommentSpecial,
+ _TokenTypeName[1121:1135]: CommentPreproc,
+ _TokenTypeLowerName[1121:1135]: CommentPreproc,
+ _TokenTypeName[1135:1153]: CommentPreprocFile,
+ _TokenTypeLowerName[1135:1153]: CommentPreprocFile,
+ _TokenTypeName[1153:1160]: Generic,
+ _TokenTypeLowerName[1153:1160]: Generic,
+ _TokenTypeName[1160:1174]: GenericDeleted,
+ _TokenTypeLowerName[1160:1174]: GenericDeleted,
+ _TokenTypeName[1174:1185]: GenericEmph,
+ _TokenTypeLowerName[1174:1185]: GenericEmph,
+ _TokenTypeName[1185:1197]: GenericError,
+ _TokenTypeLowerName[1185:1197]: GenericError,
+ _TokenTypeName[1197:1211]: GenericHeading,
+ _TokenTypeLowerName[1197:1211]: GenericHeading,
+ _TokenTypeName[1211:1226]: GenericInserted,
+ _TokenTypeLowerName[1211:1226]: GenericInserted,
+ _TokenTypeName[1226:1239]: GenericOutput,
+ _TokenTypeLowerName[1226:1239]: GenericOutput,
+ _TokenTypeName[1239:1252]: GenericPrompt,
+ _TokenTypeLowerName[1239:1252]: GenericPrompt,
+ _TokenTypeName[1252:1265]: GenericStrong,
+ _TokenTypeLowerName[1252:1265]: GenericStrong,
+ _TokenTypeName[1265:1282]: GenericSubheading,
+ _TokenTypeLowerName[1265:1282]: GenericSubheading,
+ _TokenTypeName[1282:1298]: GenericTraceback,
+ _TokenTypeLowerName[1282:1298]: GenericTraceback,
+ _TokenTypeName[1298:1314]: GenericUnderline,
+ _TokenTypeLowerName[1298:1314]: GenericUnderline,
+ _TokenTypeName[1314:1318]: Text,
+ _TokenTypeLowerName[1314:1318]: Text,
+ _TokenTypeName[1318:1332]: TextWhitespace,
+ _TokenTypeLowerName[1318:1332]: TextWhitespace,
+ _TokenTypeName[1332:1342]: TextSymbol,
+ _TokenTypeLowerName[1332:1342]: TextSymbol,
+ _TokenTypeName[1342:1357]: TextPunctuation,
+ _TokenTypeLowerName[1342:1357]: TextPunctuation,
+}
+
+var _TokenTypeNames = []string{
+ _TokenTypeName[0:6],
+ _TokenTypeName[6:10],
+ _TokenTypeName[10:15],
+ _TokenTypeName[15:20],
+ _TokenTypeName[20:28],
+ _TokenTypeName[28:36],
+ _TokenTypeName[36:47],
+ _TokenTypeName[47:56],
+ _TokenTypeName[56:69],
+ _TokenTypeName[69:85],
+ _TokenTypeName[85:96],
+ _TokenTypeName[96:100],
+ _TokenTypeName[100:110],
+ _TokenTypeName[110:120],
+ _TokenTypeName[120:127],
+ _TokenTypeName[127:134],
+ _TokenTypeName[134:149],
+ _TokenTypeName[149:167],
+ _TokenTypeName[167:183],
+ _TokenTypeName[183:196],
+ _TokenTypeName[196:211],
+ _TokenTypeName[211:222],
+ _TokenTypeName[222:226],
+ _TokenTypeName[226:239],
+ _TokenTypeName[239:250],
+ _TokenTypeName[250:267],
+ _TokenTypeName[267:276],
+ _TokenTypeName[276:288],
+ _TokenTypeName[288:301],
+ _TokenTypeName[301:311],
+ _TokenTypeName[311:324],
+ _TokenTypeName[324:336],
+ _TokenTypeName[336:353],
+ _TokenTypeName[353:364],
+ _TokenTypeName[364:373],
+ _TokenTypeName[373:386],
+ _TokenTypeName[386:398],
+ _TokenTypeName[398:407],
+ _TokenTypeName[407:417],
+ _TokenTypeName[417:429],
+ _TokenTypeName[429:436],
+ _TokenTypeName[436:448],
+ _TokenTypeName[448:469],
+ _TokenTypeName[469:486],
+ _TokenTypeName[486:504],
+ _TokenTypeName[504:524],
+ _TokenTypeName[524:541],
+ _TokenTypeName[541:548],
+ _TokenTypeName[548:559],
+ _TokenTypeName[559:571],
+ _TokenTypeName[571:584],
+ _TokenTypeName[584:602],
+ _TokenTypeName[602:619],
+ _TokenTypeName[619:640],
+ _TokenTypeName[640:660],
+ _TokenTypeName[660:677],
+ _TokenTypeName[677:699],
+ _TokenTypeName[699:715],
+ _TokenTypeName[715:734],
+ _TokenTypeName[734:753],
+ _TokenTypeName[753:773],
+ _TokenTypeName[773:794],
+ _TokenTypeName[794:811],
+ _TokenTypeName[811:829],
+ _TokenTypeName[829:847],
+ _TokenTypeName[847:866],
+ _TokenTypeName[866:885],
+ _TokenTypeName[885:898],
+ _TokenTypeName[898:914],
+ _TokenTypeName[914:932],
+ _TokenTypeName[932:948],
+ _TokenTypeName[948:968],
+ _TokenTypeName[968:992],
+ _TokenTypeName[992:1008],
+ _TokenTypeName[1008:1025],
+ _TokenTypeName[1025:1033],
+ _TokenTypeName[1033:1045],
+ _TokenTypeName[1045:1056],
+ _TokenTypeName[1056:1063],
+ _TokenTypeName[1063:1078],
+ _TokenTypeName[1078:1094],
+ _TokenTypeName[1094:1107],
+ _TokenTypeName[1107:1121],
+ _TokenTypeName[1121:1135],
+ _TokenTypeName[1135:1153],
+ _TokenTypeName[1153:1160],
+ _TokenTypeName[1160:1174],
+ _TokenTypeName[1174:1185],
+ _TokenTypeName[1185:1197],
+ _TokenTypeName[1197:1211],
+ _TokenTypeName[1211:1226],
+ _TokenTypeName[1226:1239],
+ _TokenTypeName[1239:1252],
+ _TokenTypeName[1252:1265],
+ _TokenTypeName[1265:1282],
+ _TokenTypeName[1282:1298],
+ _TokenTypeName[1298:1314],
+ _TokenTypeName[1314:1318],
+ _TokenTypeName[1318:1332],
+ _TokenTypeName[1332:1342],
+ _TokenTypeName[1342:1357],
+}
+
+// TokenTypeString retrieves an enum value from the enum constants string name.
+// Throws an error if the param is not part of the enum.
+func TokenTypeString(s string) (TokenType, error) {
+ if val, ok := _TokenTypeNameToValueMap[s]; ok {
+ return val, nil
+ }
+
+ if val, ok := _TokenTypeNameToValueMap[strings.ToLower(s)]; ok {
+ return val, nil
+ }
+ return 0, fmt.Errorf("%s does not belong to TokenType values", s)
+}
+
+// TokenTypeValues returns all values of the enum
+func TokenTypeValues() []TokenType {
+ return _TokenTypeValues
+}
+
+// TokenTypeStrings returns a slice of all String values of the enum
+func TokenTypeStrings() []string {
+ strs := make([]string, len(_TokenTypeNames))
+ copy(strs, _TokenTypeNames)
+ return strs
+}
+
+// IsATokenType returns "true" if the value is listed in the enum definition. "false" otherwise
+func (i TokenType) IsATokenType() bool {
+ _, ok := _TokenTypeMap[i]
+ return ok
+}
+
+// MarshalText implements the encoding.TextMarshaler interface for TokenType
+func (i TokenType) MarshalText() ([]byte, error) {
+ return []byte(i.String()), nil
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface for TokenType
+func (i *TokenType) UnmarshalText(text []byte) error {
+ var err error
+ *i, err = TokenTypeString(string(text))
+ return err
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/types.go b/vendor/github.com/alecthomas/chroma/v2/types.go
new file mode 100644
index 0000000..a576293
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/types.go
@@ -0,0 +1,343 @@
+package chroma
+
+//go:generate enumer -text -type TokenType
+
+// TokenType is the type of token to highlight.
+//
+// It is also an Emitter, emitting a single token of itself
+type TokenType int
+
+// Set of TokenTypes.
+//
+// Categories of types are grouped in ranges of 1000, while sub-categories are in ranges of 100. For
+// example, the literal category is in the range 3000-3999. The sub-category for literal strings is
+// in the range 3100-3199.
+
+// Meta token types.
+const (
+ // Default background style.
+ Background TokenType = -1 - iota
+ // PreWrapper style.
+ PreWrapper
+ // Line style.
+ Line
+ // Line numbers in output.
+ LineNumbers
+ // Line numbers in output when in table.
+ LineNumbersTable
+ // Line higlight style.
+ LineHighlight
+ // Line numbers table wrapper style.
+ LineTable
+ // Line numbers table TD wrapper style.
+ LineTableTD
+ // Line number links.
+ LineLink
+ // Code line wrapper style.
+ CodeLine
+ // Input that could not be tokenised.
+ Error
+ // Other is used by the Delegate lexer to indicate which tokens should be handled by the delegate.
+ Other
+ // No highlighting.
+ None
+ // Don't emit this token to the output.
+ Ignore
+ // Used as an EOF marker / nil token
+ EOFType TokenType = 0
+)
+
+// Keywords.
+const (
+ Keyword TokenType = 1000 + iota
+ KeywordConstant
+ KeywordDeclaration
+ KeywordNamespace
+ KeywordPseudo
+ KeywordReserved
+ KeywordType
+)
+
+// Names.
+const (
+ Name TokenType = 2000 + iota
+ NameAttribute
+ NameBuiltin
+ NameBuiltinPseudo
+ NameClass
+ NameConstant
+ NameDecorator
+ NameEntity
+ NameException
+ NameFunction
+ NameFunctionMagic
+ NameKeyword
+ NameLabel
+ NameNamespace
+ NameOperator
+ NameOther
+ NamePseudo
+ NameProperty
+ NameTag
+ NameVariable
+ NameVariableAnonymous
+ NameVariableClass
+ NameVariableGlobal
+ NameVariableInstance
+ NameVariableMagic
+)
+
+// Literals.
+const (
+ Literal TokenType = 3000 + iota
+ LiteralDate
+ LiteralOther
+)
+
+// Strings.
+const (
+ LiteralString TokenType = 3100 + iota
+ LiteralStringAffix
+ LiteralStringAtom
+ LiteralStringBacktick
+ LiteralStringBoolean
+ LiteralStringChar
+ LiteralStringDelimiter
+ LiteralStringDoc
+ LiteralStringDouble
+ LiteralStringEscape
+ LiteralStringHeredoc
+ LiteralStringInterpol
+ LiteralStringName
+ LiteralStringOther
+ LiteralStringRegex
+ LiteralStringSingle
+ LiteralStringSymbol
+)
+
+// Literals.
+const (
+ LiteralNumber TokenType = 3200 + iota
+ LiteralNumberBin
+ LiteralNumberFloat
+ LiteralNumberHex
+ LiteralNumberInteger
+ LiteralNumberIntegerLong
+ LiteralNumberOct
+ LiteralNumberByte
+)
+
+// Operators.
+const (
+ Operator TokenType = 4000 + iota
+ OperatorWord
+)
+
+// Punctuation.
+const (
+ Punctuation TokenType = 5000 + iota
+)
+
+// Comments.
+const (
+ Comment TokenType = 6000 + iota
+ CommentHashbang
+ CommentMultiline
+ CommentSingle
+ CommentSpecial
+)
+
+// Preprocessor "comments".
+const (
+ CommentPreproc TokenType = 6100 + iota
+ CommentPreprocFile
+)
+
+// Generic tokens.
+const (
+ Generic TokenType = 7000 + iota
+ GenericDeleted
+ GenericEmph
+ GenericError
+ GenericHeading
+ GenericInserted
+ GenericOutput
+ GenericPrompt
+ GenericStrong
+ GenericSubheading
+ GenericTraceback
+ GenericUnderline
+)
+
+// Text.
+const (
+ Text TokenType = 8000 + iota
+ TextWhitespace
+ TextSymbol
+ TextPunctuation
+)
+
+// Aliases.
+const (
+ Whitespace = TextWhitespace
+
+ Date = LiteralDate
+
+ String = LiteralString
+ StringAffix = LiteralStringAffix
+ StringBacktick = LiteralStringBacktick
+ StringChar = LiteralStringChar
+ StringDelimiter = LiteralStringDelimiter
+ StringDoc = LiteralStringDoc
+ StringDouble = LiteralStringDouble
+ StringEscape = LiteralStringEscape
+ StringHeredoc = LiteralStringHeredoc
+ StringInterpol = LiteralStringInterpol
+ StringOther = LiteralStringOther
+ StringRegex = LiteralStringRegex
+ StringSingle = LiteralStringSingle
+ StringSymbol = LiteralStringSymbol
+
+ Number = LiteralNumber
+ NumberBin = LiteralNumberBin
+ NumberFloat = LiteralNumberFloat
+ NumberHex = LiteralNumberHex
+ NumberInteger = LiteralNumberInteger
+ NumberIntegerLong = LiteralNumberIntegerLong
+ NumberOct = LiteralNumberOct
+)
+
+var (
+ StandardTypes = map[TokenType]string{
+ Background: "bg",
+ PreWrapper: "chroma",
+ Line: "line",
+ LineNumbers: "ln",
+ LineNumbersTable: "lnt",
+ LineHighlight: "hl",
+ LineTable: "lntable",
+ LineTableTD: "lntd",
+ LineLink: "lnlinks",
+ CodeLine: "cl",
+ Text: "",
+ Whitespace: "w",
+ Error: "err",
+ Other: "x",
+ // I have no idea what this is used for...
+ // Escape: "esc",
+
+ Keyword: "k",
+ KeywordConstant: "kc",
+ KeywordDeclaration: "kd",
+ KeywordNamespace: "kn",
+ KeywordPseudo: "kp",
+ KeywordReserved: "kr",
+ KeywordType: "kt",
+
+ Name: "n",
+ NameAttribute: "na",
+ NameBuiltin: "nb",
+ NameBuiltinPseudo: "bp",
+ NameClass: "nc",
+ NameConstant: "no",
+ NameDecorator: "nd",
+ NameEntity: "ni",
+ NameException: "ne",
+ NameFunction: "nf",
+ NameFunctionMagic: "fm",
+ NameProperty: "py",
+ NameLabel: "nl",
+ NameNamespace: "nn",
+ NameOther: "nx",
+ NameTag: "nt",
+ NameVariable: "nv",
+ NameVariableClass: "vc",
+ NameVariableGlobal: "vg",
+ NameVariableInstance: "vi",
+ NameVariableMagic: "vm",
+
+ Literal: "l",
+ LiteralDate: "ld",
+
+ String: "s",
+ StringAffix: "sa",
+ StringBacktick: "sb",
+ StringChar: "sc",
+ StringDelimiter: "dl",
+ StringDoc: "sd",
+ StringDouble: "s2",
+ StringEscape: "se",
+ StringHeredoc: "sh",
+ StringInterpol: "si",
+ StringOther: "sx",
+ StringRegex: "sr",
+ StringSingle: "s1",
+ StringSymbol: "ss",
+
+ Number: "m",
+ NumberBin: "mb",
+ NumberFloat: "mf",
+ NumberHex: "mh",
+ NumberInteger: "mi",
+ NumberIntegerLong: "il",
+ NumberOct: "mo",
+
+ Operator: "o",
+ OperatorWord: "ow",
+
+ Punctuation: "p",
+
+ Comment: "c",
+ CommentHashbang: "ch",
+ CommentMultiline: "cm",
+ CommentPreproc: "cp",
+ CommentPreprocFile: "cpf",
+ CommentSingle: "c1",
+ CommentSpecial: "cs",
+
+ Generic: "g",
+ GenericDeleted: "gd",
+ GenericEmph: "ge",
+ GenericError: "gr",
+ GenericHeading: "gh",
+ GenericInserted: "gi",
+ GenericOutput: "go",
+ GenericPrompt: "gp",
+ GenericStrong: "gs",
+ GenericSubheading: "gu",
+ GenericTraceback: "gt",
+ GenericUnderline: "gl",
+ }
+)
+
+func (t TokenType) Parent() TokenType {
+ if t%100 != 0 {
+ return t / 100 * 100
+ }
+ if t%1000 != 0 {
+ return t / 1000 * 1000
+ }
+ return 0
+}
+
+func (t TokenType) Category() TokenType {
+ return t / 1000 * 1000
+}
+
+func (t TokenType) SubCategory() TokenType {
+ return t / 100 * 100
+}
+
+func (t TokenType) InCategory(other TokenType) bool {
+ return t/1000 == other/1000
+}
+
+func (t TokenType) InSubCategory(other TokenType) bool {
+ return t/100 == other/100
+}
+
+func (t TokenType) Emit(groups []string, _ *LexerState) Iterator {
+ return Literator(Token{Type: t, Value: groups[0]})
+}
+
+func (t TokenType) EmitterKind() string { return "token" }
diff --git a/vendor/github.com/antonmedv/clipboard/LICENSE b/vendor/github.com/antonmedv/clipboard/LICENSE
new file mode 100644
index 0000000..d992f46
--- /dev/null
+++ b/vendor/github.com/antonmedv/clipboard/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 Anton Medvedev
+
+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/vendor/github.com/antonmedv/clipboard/README.md b/vendor/github.com/antonmedv/clipboard/README.md
new file mode 100644
index 0000000..2a59ed6
--- /dev/null
+++ b/vendor/github.com/antonmedv/clipboard/README.md
@@ -0,0 +1,24 @@
+# Clipboard for Go
+
+[](http://godoc.org/github.com/antonmedv/clipboard)
+
+Cross-platform clipboard package that works on Windows, WSL, macOS and Linux.
+
+```bash
+go get github.com/antonmedv/clipboard
+```
+
+## Usage
+
+
+```go
+clipboard.WriteAll("Hello World!")
+```
+
+```go
+text, err := clipboard.ReadAll()
+```
+
+## License
+
+[MIT](LICENSE)
diff --git a/vendor/github.com/antonmedv/clipboard/clipboard.go b/vendor/github.com/antonmedv/clipboard/clipboard.go
new file mode 100644
index 0000000..4c2ff1e
--- /dev/null
+++ b/vendor/github.com/antonmedv/clipboard/clipboard.go
@@ -0,0 +1,11 @@
+package clipboard
+
+// ReadAll read string from clipboard
+func ReadAll() (string, error) {
+ return readAll()
+}
+
+// WriteAll write string to clipboard
+func WriteAll(text string) error {
+ return writeAll(text)
+}
diff --git a/vendor/github.com/antonmedv/clipboard/clipboard_darwin.go b/vendor/github.com/antonmedv/clipboard/clipboard_darwin.go
new file mode 100644
index 0000000..37eb1d1
--- /dev/null
+++ b/vendor/github.com/antonmedv/clipboard/clipboard_darwin.go
@@ -0,0 +1,49 @@
+//go:build darwin
+// +build darwin
+
+package clipboard
+
+import (
+ "os/exec"
+)
+
+var (
+ pasteCmdArgs = "pbpaste"
+ copyCmdArgs = "pbcopy"
+)
+
+func getPasteCommand() *exec.Cmd {
+ return exec.Command(pasteCmdArgs)
+}
+
+func getCopyCommand() *exec.Cmd {
+ return exec.Command(copyCmdArgs)
+}
+
+func readAll() (string, error) {
+ pasteCmd := getPasteCommand()
+ out, err := pasteCmd.Output()
+ if err != nil {
+ return "", err
+ }
+ return string(out), nil
+}
+
+func writeAll(text string) error {
+ copyCmd := getCopyCommand()
+ in, err := copyCmd.StdinPipe()
+ if err != nil {
+ return err
+ }
+
+ if err := copyCmd.Start(); err != nil {
+ return err
+ }
+ if _, err := in.Write([]byte(text)); err != nil {
+ return err
+ }
+ if err := in.Close(); err != nil {
+ return err
+ }
+ return copyCmd.Wait()
+}
diff --git a/vendor/github.com/antonmedv/clipboard/clipboard_plan9.go b/vendor/github.com/antonmedv/clipboard/clipboard_plan9.go
new file mode 100644
index 0000000..7ea0a87
--- /dev/null
+++ b/vendor/github.com/antonmedv/clipboard/clipboard_plan9.go
@@ -0,0 +1,39 @@
+//go:build plan9
+// +build plan9
+
+package clipboard
+
+import (
+ "io/ioutil"
+ "os"
+)
+
+func readAll() (string, error) {
+ f, err := os.Open("/dev/snarf")
+ if err != nil {
+ return "", err
+ }
+ defer f.Close()
+
+ str, err := ioutil.ReadAll(f)
+ if err != nil {
+ return "", err
+ }
+
+ return string(str), nil
+}
+
+func writeAll(text string) error {
+ f, err := os.OpenFile("/dev/snarf", os.O_WRONLY, 0666)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ _, err = f.Write([]byte(text))
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/antonmedv/clipboard/clipboard_unix.go b/vendor/github.com/antonmedv/clipboard/clipboard_unix.go
new file mode 100644
index 0000000..ff23fc4
--- /dev/null
+++ b/vendor/github.com/antonmedv/clipboard/clipboard_unix.go
@@ -0,0 +1,151 @@
+//go:build freebsd || linux || netbsd || openbsd || solaris || dragonfly
+// +build freebsd linux netbsd openbsd solaris dragonfly
+
+package clipboard
+
+import (
+ "errors"
+ "os"
+ "os/exec"
+)
+
+const (
+ xsel = "xsel"
+ xclip = "xclip"
+ powershellExe = "powershell.exe"
+ clipExe = "clip.exe"
+ wlcopy = "wl-copy"
+ wlpaste = "wl-paste"
+ termuxClipboardGet = "termux-clipboard-get"
+ termuxClipboardSet = "termux-clipboard-set"
+)
+
+var (
+ xselPasteArgs = []string{xsel, "--output", "--clipboard"}
+ xselCopyArgs = []string{xsel, "--input", "--clipboard"}
+
+ xclipPasteArgs = []string{xclip, "-out", "-selection", "clipboard"}
+ xclipCopyArgs = []string{xclip, "-in", "-selection", "clipboard"}
+
+ powershellExePasteArgs = []string{powershellExe, "Get-Clipboard"}
+ clipExeCopyArgs = []string{clipExe}
+
+ wlpasteArgs = []string{wlpaste, "--no-newline"}
+ wlcopyArgs = []string{wlcopy}
+
+ termuxPasteArgs = []string{termuxClipboardGet}
+ termuxCopyArgs = []string{termuxClipboardSet}
+
+ missingCommands = errors.New("No clipboard utilities available. Please install xsel, xclip, wl-clipboard or Termux:API add-on for termux-clipboard-get/set.")
+)
+
+type commandInfo struct {
+ trimDOS bool
+
+ pasteCmdArgs []string
+ copyCmdArgs []string
+
+ unsupported bool
+}
+
+func findClipboardUtility() commandInfo {
+ c := commandInfo{}
+
+ if os.Getenv("WAYLAND_DISPLAY") != "" {
+ c.pasteCmdArgs = wlpasteArgs
+ c.copyCmdArgs = wlcopyArgs
+
+ if _, err := exec.LookPath(wlcopy); err == nil {
+ if _, err := exec.LookPath(wlpaste); err == nil {
+ return c
+ }
+ }
+ }
+
+ if os.Getenv("WSL_DISTRO_NAME") != "" {
+ c.pasteCmdArgs = powershellExePasteArgs
+ c.copyCmdArgs = clipExeCopyArgs
+ c.trimDOS = true
+
+ if _, err := exec.LookPath(clipExe); err == nil {
+ if _, err := exec.LookPath(powershellExe); err == nil {
+ return c
+ }
+ }
+ }
+
+ c.pasteCmdArgs = xclipPasteArgs
+ c.copyCmdArgs = xclipCopyArgs
+
+ if _, err := exec.LookPath(xclip); err == nil {
+ return c
+ }
+
+ c.pasteCmdArgs = xselPasteArgs
+ c.copyCmdArgs = xselCopyArgs
+
+ if _, err := exec.LookPath(xsel); err == nil {
+ return c
+ }
+
+ c.pasteCmdArgs = termuxPasteArgs
+ c.copyCmdArgs = termuxCopyArgs
+
+ if _, err := exec.LookPath(termuxClipboardSet); err == nil {
+ if _, err := exec.LookPath(termuxClipboardGet); err == nil {
+ return c
+ }
+ }
+
+ return commandInfo{unsupported: true}
+}
+
+func getPasteCommand(c commandInfo) *exec.Cmd {
+ return exec.Command(c.pasteCmdArgs[0], c.pasteCmdArgs[1:]...)
+}
+
+func getCopyCommand(c commandInfo) *exec.Cmd {
+ return exec.Command(c.copyCmdArgs[0], c.copyCmdArgs[1:]...)
+}
+
+func readAll() (string, error) {
+ c := findClipboardUtility()
+ if c.unsupported {
+ return "", missingCommands
+ }
+
+ pasteCmd := getPasteCommand(c)
+ out, err := pasteCmd.Output()
+ if err != nil {
+ return "", err
+ }
+ result := string(out)
+ if c.trimDOS && len(result) > 1 {
+ result = result[:len(result)-2]
+ }
+ return result, nil
+}
+
+func writeAll(text string) error {
+ c := findClipboardUtility()
+ if c.unsupported {
+ return missingCommands
+ }
+
+ copyCmd := getCopyCommand(c)
+ in, err := copyCmd.StdinPipe()
+ if err != nil {
+ return err
+ }
+
+ if err := copyCmd.Start(); err != nil {
+ return err
+ }
+ if _, err := in.Write([]byte(text)); err != nil {
+ return err
+ }
+ if err := in.Close(); err != nil {
+ return err
+ }
+ return copyCmd.Wait()
+}
diff --git a/vendor/github.com/antonmedv/clipboard/clipboard_windows.go b/vendor/github.com/antonmedv/clipboard/clipboard_windows.go
new file mode 100644
index 0000000..9670236
--- /dev/null
+++ b/vendor/github.com/antonmedv/clipboard/clipboard_windows.go
@@ -0,0 +1,154 @@
+//go:build windows
+// +build windows
+
+package clipboard
+
+import (
+ "runtime"
+ "syscall"
+ "time"
+ "unsafe"
+)
+
+const (
+ cfUnicodetext = 13
+ gmemMoveable = 0x0002
+)
+
+var (
+ user32 = syscall.MustLoadDLL("user32")
+ isClipboardFormatAvailable = user32.MustFindProc("IsClipboardFormatAvailable")
+ openClipboard = user32.MustFindProc("OpenClipboard")
+ closeClipboard = user32.MustFindProc("CloseClipboard")
+ emptyClipboard = user32.MustFindProc("EmptyClipboard")
+ getClipboardData = user32.MustFindProc("GetClipboardData")
+ setClipboardData = user32.MustFindProc("SetClipboardData")
+
+ kernel32 = syscall.NewLazyDLL("kernel32")
+ globalAlloc = kernel32.NewProc("GlobalAlloc")
+ globalFree = kernel32.NewProc("GlobalFree")
+ globalLock = kernel32.NewProc("GlobalLock")
+ globalUnlock = kernel32.NewProc("GlobalUnlock")
+ lstrcpy = kernel32.NewProc("lstrcpyW")
+)
+
+// waitOpenClipboard opens the clipboard, waiting for up to a second to do so.
+func waitOpenClipboard() error {
+ started := time.Now()
+ limit := started.Add(time.Second)
+ var r uintptr
+ var err error
+ for time.Now().Before(limit) {
+ r, _, err = openClipboard.Call(0)
+ if r != 0 {
+ return nil
+ }
+ time.Sleep(time.Millisecond)
+ }
+ return err
+}
+
+func readAll() (string, error) {
+ // LockOSThread ensure that the whole method will keep executing on the same thread from begin to end (it actually locks the goroutine thread attribution).
+ // Otherwise, if the goroutine switch thread during execution (which is a common practice), the OpenClipboard and CloseClipboard will happen on two different threads, and it will result in a clipboard deadlock.
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+ if formatAvailable, _, err := isClipboardFormatAvailable.Call(cfUnicodetext); formatAvailable == 0 {
+ return "", err
+ }
+ err := waitOpenClipboard()
+ if err != nil {
+ return "", err
+ }
+
+ h, _, err := getClipboardData.Call(cfUnicodetext)
+ if h == 0 {
+ _, _, _ = closeClipboard.Call()
+ return "", err
+ }
+
+ l, _, err := globalLock.Call(h)
+ if l == 0 {
+ _, _, _ = closeClipboard.Call()
+ return "", err
+ }
+
+ text := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(l))[:])
+
+ r, _, err := globalUnlock.Call(h)
+ if r == 0 {
+ _, _, _ = closeClipboard.Call()
+ return "", err
+ }
+
+ closed, _, err := closeClipboard.Call()
+ if closed == 0 {
+ return "", err
+ }
+ return text, nil
+}
+
+func writeAll(text string) error {
+ // LockOSThread ensure that the whole method will keep executing on the same thread from begin to end (it actually locks the goroutine thread attribution).
+ // Otherwise, if the goroutine switch thread during execution (which is a common practice), the OpenClipboard and CloseClipboard will happen on two different threads, and it will result in a clipboard deadlock.
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ err := waitOpenClipboard()
+ if err != nil {
+ return err
+ }
+
+ r, _, err := emptyClipboard.Call(0)
+ if r == 0 {
+ _, _, _ = closeClipboard.Call()
+ return err
+ }
+
+ data := syscall.StringToUTF16(text)
+
+ // "If the hMem parameter identifies a memory object, the object must have
+ // been allocated using the function with the GMEM_MOVEABLE flag."
+ h, _, err := globalAlloc.Call(gmemMoveable, uintptr(len(data)*int(unsafe.Sizeof(data[0]))))
+ if h == 0 {
+ _, _, _ = closeClipboard.Call()
+ return err
+ }
+ defer func() {
+ if h != 0 {
+ globalFree.Call(h)
+ }
+ }()
+
+ l, _, err := globalLock.Call(h)
+ if l == 0 {
+ _, _, _ = closeClipboard.Call()
+ return err
+ }
+
+ r, _, err = lstrcpy.Call(l, uintptr(unsafe.Pointer(&data[0])))
+ if r == 0 {
+ _, _, _ = closeClipboard.Call()
+ return err
+ }
+
+ r, _, err = globalUnlock.Call(h)
+ if r == 0 {
+ if err.(syscall.Errno) != 0 {
+ _, _, _ = closeClipboard.Call()
+ return err
+ }
+ }
+
+ r, _, err = setClipboardData.Call(cfUnicodetext, h)
+ if r == 0 {
+ _, _, _ = closeClipboard.Call()
+ return err
+ }
+ h = 0 // suppress deferred cleanup
+ closed, _, err := closeClipboard.Call()
+ if closed == 0 {
+ return err
+ }
+ return nil
+}
diff --git a/vendor/github.com/aymanbagabas/go-osc52/v2/LICENSE b/vendor/github.com/aymanbagabas/go-osc52/v2/LICENSE
new file mode 100644
index 0000000..25cec1e
--- /dev/null
+++ b/vendor/github.com/aymanbagabas/go-osc52/v2/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 Ayman Bagabas
+
+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/vendor/github.com/aymanbagabas/go-osc52/v2/README.md b/vendor/github.com/aymanbagabas/go-osc52/v2/README.md
new file mode 100644
index 0000000..4de3a22
--- /dev/null
+++ b/vendor/github.com/aymanbagabas/go-osc52/v2/README.md
@@ -0,0 +1,83 @@
+
+# go-osc52
+
+
+
+A Go library to work with the [ANSI OSC52](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands) terminal sequence.
+
+## Usage
+
+You can use this small library to construct an ANSI OSC52 sequence suitable for
+your terminal.
+
+
+### Example
+
+```go
+import (
+ "os"
+ "fmt"
+
+ "github.com/aymanbagabas/go-osc52/v2"
+)
+
+func main() {
+ s := "Hello World!"
+
+ // Copy `s` to system clipboard
+ osc52.New(s).WriteTo(os.Stderr)
+
+ // Copy `s` to primary clipboard (X11)
+ osc52.New(s).Primary().WriteTo(os.Stderr)
+
+ // Query the clipboard
+ osc52.Query().WriteTo(os.Stderr)
+
+ // Clear system clipboard
+ osc52.Clear().WriteTo(os.Stderr)
+
+ // Use the fmt.Stringer interface to copy `s` to system clipboard
+ fmt.Fprint(os.Stderr, osc52.New(s))
+
+ // Or to primary clipboard
+ fmt.Fprint(os.Stderr, osc52.New(s).Primary())
+}
+```
+
+## SSH Example
+
+You can use this over SSH using [gliderlabs/ssh](https://github.com/gliderlabs/ssh) for instance:
+
+```go
+var sshSession ssh.Session
+seq := osc52.New("Hello awesome!")
+// Check if term is screen or tmux
+pty, _, _ := s.Pty()
+if pty.Term == "screen" {
+ seq = seq.Screen()
+} else if isTmux {
+ seq = seq.Tmux()
+}
+seq.WriteTo(sshSession.Stderr())
+```
+
+## Tmux
+
+Make sure you have `set-clipboard on` in your config, otherwise, tmux won't
+allow your application to access the clipboard [^1].
+
+Using the tmux option, `osc52.TmuxMode` or `osc52.New(...).Tmux()`, wraps the
+OSC52 sequence in a special tmux DCS sequence and pass it to the outer
+terminal. This requires `allow-passthrough on` in your config.
+`allow-passthrough` is no longer enabled by default
+[since tmux 3.3a](https://github.com/tmux/tmux/issues/3218#issuecomment-1153089282) [^2].
+
+[^1]: See [tmux clipboard](https://github.com/tmux/tmux/wiki/Clipboard)
+[^2]: [What is allow-passthrough](https://github.com/tmux/tmux/wiki/FAQ#what-is-the-passthrough-escape-sequence-and-how-do-i-use-it)
+
+## Credits
+
+* [vim-oscyank](https://github.com/ojroques/vim-oscyank) this is heavily inspired by vim-oscyank.
diff --git a/vendor/github.com/aymanbagabas/go-osc52/v2/osc52.go b/vendor/github.com/aymanbagabas/go-osc52/v2/osc52.go
new file mode 100644
index 0000000..dc758d2
--- /dev/null
+++ b/vendor/github.com/aymanbagabas/go-osc52/v2/osc52.go
@@ -0,0 +1,305 @@
+// OSC52 is a terminal escape sequence that allows copying text to the clipboard.
+//
+// The sequence consists of the following:
+//
+// OSC 52 ; Pc ; Pd BEL
+//
+// Pc is the clipboard choice:
+//
+// c: clipboard
+// p: primary
+// q: secondary (not supported)
+// s: select (not supported)
+// 0-7: cut-buffers (not supported)
+//
+// Pd is the data to copy to the clipboard. This string should be encoded in
+// base64 (RFC-4648).
+//
+// If Pd is "?", the terminal replies to the host with the current contents of
+// the clipboard.
+//
+// If Pd is neither a base64 string nor "?", the terminal clears the clipboard.
+//
+// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+// where Ps = 52 => Manipulate Selection Data.
+//
+// Examples:
+//
+// // copy "hello world" to the system clipboard
+// fmt.Fprint(os.Stderr, osc52.New("hello world"))
+//
+// // copy "hello world" to the primary Clipboard
+// fmt.Fprint(os.Stderr, osc52.New("hello world").Primary())
+//
+// // limit the size of the string to copy 10 bytes
+// fmt.Fprint(os.Stderr, osc52.New("0123456789").Limit(10))
+//
+// // escape the OSC52 sequence for screen using DCS sequences
+// fmt.Fprint(os.Stderr, osc52.New("hello world").Screen())
+//
+// // escape the OSC52 sequence for Tmux
+// fmt.Fprint(os.Stderr, osc52.New("hello world").Tmux())
+//
+// // query the system Clipboard
+// fmt.Fprint(os.Stderr, osc52.Query())
+//
+// // query the primary clipboard
+// fmt.Fprint(os.Stderr, osc52.Query().Primary())
+//
+// // clear the system Clipboard
+// fmt.Fprint(os.Stderr, osc52.Clear())
+//
+// // clear the primary Clipboard
+// fmt.Fprint(os.Stderr, osc52.Clear().Primary())
+package osc52
+
+import (
+ "encoding/base64"
+ "fmt"
+ "io"
+ "strings"
+)
+
+// Clipboard is the clipboard buffer to use.
+type Clipboard rune
+
+const (
+ // SystemClipboard is the system clipboard buffer.
+ SystemClipboard Clipboard = 'c'
+ // PrimaryClipboard is the primary clipboard buffer (X11).
+ PrimaryClipboard = 'p'
+)
+
+// Mode is the mode to use for the OSC52 sequence.
+type Mode uint
+
+const (
+ // DefaultMode is the default OSC52 sequence mode.
+ DefaultMode Mode = iota
+ // ScreenMode escapes the OSC52 sequence for screen using DCS sequences.
+ ScreenMode
+ // TmuxMode escapes the OSC52 sequence for tmux. Not needed if tmux
+ // clipboard is set to `set-clipboard on`
+ TmuxMode
+)
+
+// Operation is the OSC52 operation.
+type Operation uint
+
+const (
+ // SetOperation is the copy operation.
+ SetOperation Operation = iota
+ // QueryOperation is the query operation.
+ QueryOperation
+ // ClearOperation is the clear operation.
+ ClearOperation
+)
+
+// Sequence is the OSC52 sequence.
+type Sequence struct {
+ str string
+ limit int
+ op Operation
+ mode Mode
+ clipboard Clipboard
+}
+
+var _ fmt.Stringer = Sequence{}
+
+var _ io.WriterTo = Sequence{}
+
+// String returns the OSC52 sequence.
+func (s Sequence) String() string {
+ var seq strings.Builder
+ // mode escape sequences start
+ seq.WriteString(s.seqStart())
+ // actual OSC52 sequence start
+ seq.WriteString(fmt.Sprintf("\x1b]52;%c;", s.clipboard))
+ switch s.op {
+ case SetOperation:
+ str := s.str
+ if s.limit > 0 && len(str) > s.limit {
+ return ""
+ }
+ b64 := base64.StdEncoding.EncodeToString([]byte(str))
+ switch s.mode {
+ case ScreenMode:
+ // Screen doesn't support OSC52 but will pass the contents of a DCS
+ // sequence to the outer terminal unchanged.
+ //
+ // Here, we split the encoded string into 76 bytes chunks and then
+ // join the chunks with sequences. Finally,
+ // wrap the whole thing in
+ // .
+ // s := strings.SplitN(b64, "", 76)
+ s := make([]string, 0, len(b64)/76+1)
+ for i := 0; i < len(b64); i += 76 {
+ end := i + 76
+ if end > len(b64) {
+ end = len(b64)
+ }
+ s = append(s, b64[i:end])
+ }
+ seq.WriteString(strings.Join(s, "\x1b\\\x1bP"))
+ default:
+ seq.WriteString(b64)
+ }
+ case QueryOperation:
+ // OSC52 queries the clipboard using "?"
+ seq.WriteString("?")
+ case ClearOperation:
+ // OSC52 clears the clipboard if the data is neither a base64 string nor "?"
+ // we're using "!" as a default
+ seq.WriteString("!")
+ }
+ // actual OSC52 sequence end
+ seq.WriteString("\x07")
+ // mode escape end
+ seq.WriteString(s.seqEnd())
+ return seq.String()
+}
+
+// WriteTo writes the OSC52 sequence to the writer.
+func (s Sequence) WriteTo(out io.Writer) (int64, error) {
+ n, err := out.Write([]byte(s.String()))
+ return int64(n), err
+}
+
+// Mode sets the mode for the OSC52 sequence.
+func (s Sequence) Mode(m Mode) Sequence {
+ s.mode = m
+ return s
+}
+
+// Tmux sets the mode to TmuxMode.
+// Used to escape the OSC52 sequence for `tmux`.
+//
+// Note: this is not needed if tmux clipboard is set to `set-clipboard on`. If
+// TmuxMode is used, tmux must have `allow-passthrough on` set.
+//
+// This is a syntactic sugar for s.Mode(TmuxMode).
+func (s Sequence) Tmux() Sequence {
+ return s.Mode(TmuxMode)
+}
+
+// Screen sets the mode to ScreenMode.
+// Used to escape the OSC52 sequence for `screen`.
+//
+// This is a syntactic sugar for s.Mode(ScreenMode).
+func (s Sequence) Screen() Sequence {
+ return s.Mode(ScreenMode)
+}
+
+// Clipboard sets the clipboard buffer for the OSC52 sequence.
+func (s Sequence) Clipboard(c Clipboard) Sequence {
+ s.clipboard = c
+ return s
+}
+
+// Primary sets the clipboard buffer to PrimaryClipboard.
+// This is the X11 primary clipboard.
+//
+// This is a syntactic sugar for s.Clipboard(PrimaryClipboard).
+func (s Sequence) Primary() Sequence {
+ return s.Clipboard(PrimaryClipboard)
+}
+
+// Limit sets the limit for the OSC52 sequence.
+// The default limit is 0 (no limit).
+//
+// Strings longer than the limit get ignored. Settting the limit to 0 or a
+// negative value disables the limit. Each terminal defines its own escapse
+// sequence limit.
+func (s Sequence) Limit(l int) Sequence {
+ if l < 0 {
+ s.limit = 0
+ } else {
+ s.limit = l
+ }
+ return s
+}
+
+// Operation sets the operation for the OSC52 sequence.
+// The default operation is SetOperation.
+func (s Sequence) Operation(o Operation) Sequence {
+ s.op = o
+ return s
+}
+
+// Clear sets the operation to ClearOperation.
+// This clears the clipboard.
+//
+// This is a syntactic sugar for s.Operation(ClearOperation).
+func (s Sequence) Clear() Sequence {
+ return s.Operation(ClearOperation)
+}
+
+// Query sets the operation to QueryOperation.
+// This queries the clipboard contents.
+//
+// This is a syntactic sugar for s.Operation(QueryOperation).
+func (s Sequence) Query() Sequence {
+ return s.Operation(QueryOperation)
+}
+
+// SetString sets the string for the OSC52 sequence. Strings are joined with a
+// space character.
+func (s Sequence) SetString(strs ...string) Sequence {
+ s.str = strings.Join(strs, " ")
+ return s
+}
+
+// New creates a new OSC52 sequence with the given string(s). Strings are
+// joined with a space character.
+func New(strs ...string) Sequence {
+ s := Sequence{
+ str: strings.Join(strs, " "),
+ limit: 0,
+ mode: DefaultMode,
+ clipboard: SystemClipboard,
+ op: SetOperation,
+ }
+ return s
+}
+
+// Query creates a new OSC52 sequence with the QueryOperation.
+// This returns a new OSC52 sequence to query the clipboard contents.
+//
+// This is a syntactic sugar for New().Query().
+func Query() Sequence {
+ return New().Query()
+}
+
+// Clear creates a new OSC52 sequence with the ClearOperation.
+// This returns a new OSC52 sequence to clear the clipboard.
+//
+// This is a syntactic sugar for New().Clear().
+func Clear() Sequence {
+ return New().Clear()
+}
+
+func (s Sequence) seqStart() string {
+ switch s.mode {
+ case TmuxMode:
+ // Write the start of a tmux escape sequence.
+ return "\x1bPtmux;\x1b"
+ case ScreenMode:
+ // Write the start of a DCS sequence.
+ return "\x1bP"
+ default:
+ return ""
+ }
+}
+
+func (s Sequence) seqEnd() string {
+ switch s.mode {
+ case TmuxMode:
+ // Terminate the tmux escape sequence.
+ return "\x1b\\"
+ case ScreenMode:
+ // Write the end of a DCS sequence.
+ return "\x1b\x5c"
+ default:
+ return ""
+ }
+}
diff --git a/vendor/github.com/charmbracelet/bubbles/LICENSE b/vendor/github.com/charmbracelet/bubbles/LICENSE
new file mode 100644
index 0000000..31d76c1
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbles/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020-2023 Charmbracelet, Inc
+
+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/vendor/github.com/charmbracelet/bubbles/key/key.go b/vendor/github.com/charmbracelet/bubbles/key/key.go
new file mode 100644
index 0000000..c7888fa
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbles/key/key.go
@@ -0,0 +1,142 @@
+// Package key provides some types and functions for generating user-definable
+// keymappings useful in Bubble Tea components. There are a few different ways
+// you can define a keymapping with this package. Here's one example:
+//
+// type KeyMap struct {
+// Up key.Binding
+// Down key.Binding
+// }
+//
+// var DefaultKeyMap = KeyMap{
+// Up: key.NewBinding(
+// key.WithKeys("k", "up"), // actual keybindings
+// key.WithHelp("↑/k", "move up"), // corresponding help text
+// ),
+// Down: key.NewBinding(
+// key.WithKeys("j", "down"),
+// key.WithHelp("↓/j", "move down"),
+// ),
+// }
+//
+// func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+// switch msg := msg.(type) {
+// case tea.KeyMsg:
+// switch {
+// case key.Matches(msg, DefaultKeyMap.Up):
+// // The user pressed up
+// case key.Matches(msg, DefaultKeyMap.Down):
+// // The user pressed down
+// }
+// }
+//
+// // ...
+// }
+//
+// The help information, which is not used in the example above, can be used
+// to render help text for keystrokes in your views.
+package key
+
+import (
+ tea "github.com/charmbracelet/bubbletea"
+)
+
+// Binding describes a set of keybindings and, optionally, their associated
+// help text.
+type Binding struct {
+ keys []string
+ help Help
+ disabled bool
+}
+
+// BindingOpt is an initialization option for a keybinding. It's used as an
+// argument to NewBinding.
+type BindingOpt func(*Binding)
+
+// NewBinding returns a new keybinding from a set of BindingOpt options.
+func NewBinding(opts ...BindingOpt) Binding {
+ b := &Binding{}
+ for _, opt := range opts {
+ opt(b)
+ }
+ return *b
+}
+
+// WithKeys initializes a keybinding with the given keystrokes.
+func WithKeys(keys ...string) BindingOpt {
+ return func(b *Binding) {
+ b.keys = keys
+ }
+}
+
+// WithHelp initializes a keybinding with the given help text.
+func WithHelp(key, desc string) BindingOpt {
+ return func(b *Binding) {
+ b.help = Help{Key: key, Desc: desc}
+ }
+}
+
+// WithDisabled initializes a disabled keybinding.
+func WithDisabled() BindingOpt {
+ return func(b *Binding) {
+ b.disabled = true
+ }
+}
+
+// SetKeys sets the keys for the keybinding.
+func (b *Binding) SetKeys(keys ...string) {
+ b.keys = keys
+}
+
+// Keys returns the keys for the keybinding.
+func (b Binding) Keys() []string {
+ return b.keys
+}
+
+// SetHelp sets the help text for the keybinding.
+func (b *Binding) SetHelp(key, desc string) {
+ b.help = Help{Key: key, Desc: desc}
+}
+
+// Help returns the Help information for the keybinding.
+func (b Binding) Help() Help {
+ return b.help
+}
+
+// Enabled returns whether or not the keybinding is enabled. Disabled
+// keybindings won't be activated and won't show up in help. Keybindings are
+// enabled by default.
+func (b Binding) Enabled() bool {
+ return !b.disabled && b.keys != nil
+}
+
+// SetEnabled enables or disables the keybinding.
+func (b *Binding) SetEnabled(v bool) {
+ b.disabled = !v
+}
+
+// Unbind removes the keys and help from this binding, effectively nullifying
+// it. This is a step beyond disabling it, since applications can enable
+// or disable key bindings based on application state.
+func (b *Binding) Unbind() {
+ b.keys = nil
+ b.help = Help{}
+}
+
+// Help is help information for a given keybinding.
+type Help struct {
+ Key string
+ Desc string
+}
+
+// Matches checks if the given KeyMsg matches the given bindings.
+func Matches(k tea.KeyMsg, b ...Binding) bool {
+ keys := k.String()
+ for _, binding := range b {
+ for _, v := range binding.keys {
+ if keys == v && binding.Enabled() {
+ return true
+ }
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/.gitattributes b/vendor/github.com/charmbracelet/bubbletea/.gitattributes
new file mode 100644
index 0000000..6c929d4
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/.gitattributes
@@ -0,0 +1 @@
+*.golden -text
diff --git a/vendor/github.com/charmbracelet/bubbletea/.gitignore b/vendor/github.com/charmbracelet/bubbletea/.gitignore
new file mode 100644
index 0000000..abd7c06
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/.gitignore
@@ -0,0 +1,23 @@
+.DS_Store
+.envrc
+
+examples/fullscreen/fullscreen
+examples/help/help
+examples/http/http
+examples/list-default/list-default
+examples/list-fancy/list-fancy
+examples/list-simple/list-simple
+examples/mouse/mouse
+examples/pager/pager
+examples/progress-download/color_vortex.blend
+examples/progress-download/progress-download
+examples/simple/simple
+examples/spinner/spinner
+examples/textinput/textinput
+examples/textinputs/textinputs
+examples/views/views
+tutorials/basics/basics
+tutorials/commands/commands
+.idea
+coverage.txt
+dist/
diff --git a/vendor/github.com/charmbracelet/bubbletea/.golangci-soft.yml b/vendor/github.com/charmbracelet/bubbletea/.golangci-soft.yml
new file mode 100644
index 0000000..d325d4f
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/.golangci-soft.yml
@@ -0,0 +1,40 @@
+run:
+ tests: false
+ issues-exit-code: 0
+
+issues:
+ include:
+ - EXC0001
+ - EXC0005
+ - EXC0011
+ - EXC0012
+ - EXC0013
+
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ enable:
+ - exhaustive
+ - goconst
+ - godot
+ - godox
+ - mnd
+ - gomoddirectives
+ - goprintffuncname
+ - misspell
+ - nakedret
+ - nestif
+ - noctx
+ - nolintlint
+ - prealloc
+ - wrapcheck
+
+ # disable default linters, they are already enabled in .golangci.yml
+ disable:
+ - errcheck
+ - gosimple
+ - govet
+ - ineffassign
+ - staticcheck
+ - unused
diff --git a/vendor/github.com/charmbracelet/bubbletea/.golangci.yml b/vendor/github.com/charmbracelet/bubbletea/.golangci.yml
new file mode 100644
index 0000000..d6789e0
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/.golangci.yml
@@ -0,0 +1,28 @@
+run:
+ tests: false
+
+issues:
+ include:
+ - EXC0001
+ - EXC0005
+ - EXC0011
+ - EXC0012
+ - EXC0013
+
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ enable:
+ - bodyclose
+ - gofumpt
+ - goimports
+ - gosec
+ - nilerr
+ - revive
+ - rowserrcheck
+ - sqlclosecheck
+ - tparallel
+ - unconvert
+ - unparam
+ - whitespace
diff --git a/vendor/github.com/charmbracelet/bubbletea/.goreleaser.yml b/vendor/github.com/charmbracelet/bubbletea/.goreleaser.yml
new file mode 100644
index 0000000..3353d02
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/.goreleaser.yml
@@ -0,0 +1,5 @@
+# yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json
+version: 2
+includes:
+ - from_url:
+ url: charmbracelet/meta/main/goreleaser-lib.yaml
diff --git a/vendor/github.com/charmbracelet/bubbletea/LICENSE b/vendor/github.com/charmbracelet/bubbletea/LICENSE
new file mode 100644
index 0000000..31d76c1
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020-2023 Charmbracelet, Inc
+
+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/vendor/github.com/charmbracelet/bubbletea/README.md b/vendor/github.com/charmbracelet/bubbletea/README.md
new file mode 100644
index 0000000..58dd182
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/README.md
@@ -0,0 +1,396 @@
+# Bubble Tea
+
+
+
+The fun, functional and stateful way to build terminal apps. A Go framework
+based on [The Elm Architecture][elm]. Bubble Tea is well-suited for simple and
+complex terminal applications, either inline, full-window, or a mix of both.
+
+
+
+
+
+Bubble Tea is in use in production and includes a number of features and
+performance optimizations we’ve added along the way. Among those is
+a framerate-based renderer, mouse support, focus reporting and more.
+
+To get started, see the tutorial below, the [examples][examples], the
+[docs][docs], the [video tutorials][youtube] and some common [resources](#libraries-we-use-with-bubble-tea).
+
+[youtube]: https://charm.sh/yt
+
+## By the way
+
+Be sure to check out [Bubbles][bubbles], a library of common UI components for Bubble Tea.
+
+
+
+---
+
+## Tutorial
+
+Bubble Tea is based on the functional design paradigms of [The Elm
+Architecture][elm], which happens to work nicely with Go. It's a delightful way
+to build applications.
+
+This tutorial assumes you have a working knowledge of Go.
+
+By the way, the non-annotated source code for this program is available
+[on GitHub][tut-source].
+
+[elm]: https://guide.elm-lang.org/architecture/
+[tut-source]: https://github.com/charmbracelet/bubbletea/tree/main/tutorials/basics
+
+### Enough! Let's get to it.
+
+For this tutorial, we're making a shopping list.
+
+To start we'll define our package and import some libraries. Our only external
+import will be the Bubble Tea library, which we'll call `tea` for short.
+
+```go
+package main
+
+// These imports will be used later on the tutorial. If you save the file
+// now, Go might complain they are unused, but that's fine.
+// You may also need to run `go mod tidy` to download bubbletea and its
+// dependencies.
+import (
+ "fmt"
+ "os"
+
+ tea "github.com/charmbracelet/bubbletea"
+)
+```
+
+Bubble Tea programs are comprised of a **model** that describes the application
+state and three simple methods on that model:
+
+- **Init**, a function that returns an initial command for the application to run.
+- **Update**, a function that handles incoming events and updates the model accordingly.
+- **View**, a function that renders the UI based on the data in the model.
+
+### The Model
+
+So let's start by defining our model which will store our application's state.
+It can be any type, but a `struct` usually makes the most sense.
+
+```go
+type model struct {
+ choices []string // items on the to-do list
+ cursor int // which to-do list item our cursor is pointing at
+ selected map[int]struct{} // which to-do items are selected
+}
+```
+
+### Initialization
+
+Next, we’ll define our application’s initial state. In this case, we’re defining
+a function to return our initial model, however, we could just as easily define
+the initial model as a variable elsewhere, too.
+
+```go
+func initialModel() model {
+ return model{
+ // Our to-do list is a grocery list
+ choices: []string{"Buy carrots", "Buy celery", "Buy kohlrabi"},
+
+ // A map which indicates which choices are selected. We're using
+ // the map like a mathematical set. The keys refer to the indexes
+ // of the `choices` slice, above.
+ selected: make(map[int]struct{}),
+ }
+}
+```
+
+Next, we define the `Init` method. `Init` can return a `Cmd` that could perform
+some initial I/O. For now, we don't need to do any I/O, so for the command,
+we'll just return `nil`, which translates to "no command."
+
+```go
+func (m model) Init() tea.Cmd {
+ // Just return `nil`, which means "no I/O right now, please."
+ return nil
+}
+```
+
+### The Update Method
+
+Next up is the update method. The update function is called when ”things
+happen.” Its job is to look at what has happened and return an updated model in
+response. It can also return a `Cmd` to make more things happen, but for now
+don't worry about that part.
+
+In our case, when a user presses the down arrow, `Update`’s job is to notice
+that the down arrow was pressed and move the cursor accordingly (or not).
+
+The “something happened” comes in the form of a `Msg`, which can be any type.
+Messages are the result of some I/O that took place, such as a keypress, timer
+tick, or a response from a server.
+
+We usually figure out which type of `Msg` we received with a type switch, but
+you could also use a type assertion.
+
+For now, we'll just deal with `tea.KeyMsg` messages, which are automatically
+sent to the update function when keys are pressed.
+
+```go
+func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+ switch msg := msg.(type) {
+
+ // Is it a key press?
+ case tea.KeyMsg:
+
+ // Cool, what was the actual key pressed?
+ switch msg.String() {
+
+ // These keys should exit the program.
+ case "ctrl+c", "q":
+ return m, tea.Quit
+
+ // The "up" and "k" keys move the cursor up
+ case "up", "k":
+ if m.cursor > 0 {
+ m.cursor--
+ }
+
+ // The "down" and "j" keys move the cursor down
+ case "down", "j":
+ if m.cursor < len(m.choices)-1 {
+ m.cursor++
+ }
+
+ // The "enter" key and the spacebar (a literal space) toggle
+ // the selected state for the item that the cursor is pointing at.
+ case "enter", " ":
+ _, ok := m.selected[m.cursor]
+ if ok {
+ delete(m.selected, m.cursor)
+ } else {
+ m.selected[m.cursor] = struct{}{}
+ }
+ }
+ }
+
+ // Return the updated model to the Bubble Tea runtime for processing.
+ // Note that we're not returning a command.
+ return m, nil
+}
+```
+
+You may have noticed that ctrl+c and q above return
+a `tea.Quit` command with the model. That’s a special command which instructs
+the Bubble Tea runtime to quit, exiting the program.
+
+### The View Method
+
+At last, it’s time to render our UI. Of all the methods, the view is the
+simplest. We look at the model in its current state and use it to return
+a `string`. That string is our UI!
+
+Because the view describes the entire UI of your application, you don’t have to
+worry about redrawing logic and stuff like that. Bubble Tea takes care of it
+for you.
+
+```go
+func (m model) View() string {
+ // The header
+ s := "What should we buy at the market?\n\n"
+
+ // Iterate over our choices
+ for i, choice := range m.choices {
+
+ // Is the cursor pointing at this choice?
+ cursor := " " // no cursor
+ if m.cursor == i {
+ cursor = ">" // cursor!
+ }
+
+ // Is this choice selected?
+ checked := " " // not selected
+ if _, ok := m.selected[i]; ok {
+ checked = "x" // selected!
+ }
+
+ // Render the row
+ s += fmt.Sprintf("%s [%s] %s\n", cursor, checked, choice)
+ }
+
+ // The footer
+ s += "\nPress q to quit.\n"
+
+ // Send the UI for rendering
+ return s
+}
+```
+
+### All Together Now
+
+The last step is to simply run our program. We pass our initial model to
+`tea.NewProgram` and let it rip:
+
+```go
+func main() {
+ p := tea.NewProgram(initialModel())
+ if _, err := p.Run(); err != nil {
+ fmt.Printf("Alas, there's been an error: %v", err)
+ os.Exit(1)
+ }
+}
+```
+
+## What’s Next?
+
+This tutorial covers the basics of building an interactive terminal UI, but
+in the real world you'll also need to perform I/O. To learn about that have a
+look at the [Command Tutorial][cmd]. It's pretty simple.
+
+There are also several [Bubble Tea examples][examples] available and, of course,
+there are [Go Docs][docs].
+
+[cmd]: https://github.com/charmbracelet/bubbletea/tree/main/tutorials/commands/
+[examples]: https://github.com/charmbracelet/bubbletea/tree/main/examples
+[docs]: https://pkg.go.dev/github.com/charmbracelet/bubbletea?tab=doc
+
+## Debugging
+
+### Debugging with Delve
+
+Since Bubble Tea apps assume control of stdin and stdout, you’ll need to run
+delve in headless mode and then connect to it:
+
+```bash
+# Start the debugger
+$ dlv debug --headless --api-version=2 --listen=127.0.0.1:43000 .
+API server listening at: 127.0.0.1:43000
+
+# Connect to it from another terminal
+$ dlv connect 127.0.0.1:43000
+```
+
+If you do not explicitly supply the `--listen` flag, the port used will vary
+per run, so passing this in makes the debugger easier to use from a script
+or your IDE of choice.
+
+Additionally, we pass in `--api-version=2` because delve defaults to version 1
+for backwards compatibility reasons. However, delve recommends using version 2
+for all new development and some clients may no longer work with version 1.
+For more information, see the [Delve documentation](https://github.com/go-delve/delve/tree/master/Documentation/api).
+
+### Logging Stuff
+
+You can’t really log to stdout with Bubble Tea because your TUI is busy
+occupying that! You can, however, log to a file by including something like
+the following prior to starting your Bubble Tea program:
+
+```go
+if len(os.Getenv("DEBUG")) > 0 {
+ f, err := tea.LogToFile("debug.log", "debug")
+ if err != nil {
+ fmt.Println("fatal:", err)
+ os.Exit(1)
+ }
+ defer f.Close()
+}
+```
+
+To see what’s being logged in real time, run `tail -f debug.log` while you run
+your program in another window.
+
+## Libraries we use with Bubble Tea
+
+- [Bubbles][bubbles]: Common Bubble Tea components such as text inputs, viewports, spinners and so on
+- [Lip Gloss][lipgloss]: Style, format and layout tools for terminal applications
+- [Harmonica][harmonica]: A spring animation library for smooth, natural motion
+- [BubbleZone][bubblezone]: Easy mouse event tracking for Bubble Tea components
+- [ntcharts][ntcharts]: A terminal charting library built for Bubble Tea and [Lip Gloss][lipgloss]
+
+[bubbles]: https://github.com/charmbracelet/bubbles
+[lipgloss]: https://github.com/charmbracelet/lipgloss
+[harmonica]: https://github.com/charmbracelet/harmonica
+[bubblezone]: https://github.com/lrstanley/bubblezone
+[ntcharts]: https://github.com/NimbleMarkets/ntcharts
+
+## Bubble Tea in the Wild
+
+There are over [10,000 applications](https://github.com/charmbracelet/bubbletea/network/dependents) built with Bubble Tea! Here are a handful of ’em.
+
+### Staff favourites
+
+- [chezmoi](https://github.com/twpayne/chezmoi): securely manage your dotfiles across multiple machines
+- [circumflex](https://github.com/bensadeh/circumflex): read Hacker News in the terminal
+- [gh-dash](https://www.github.com/dlvhdr/gh-dash): a GitHub CLI extension for PRs and issues
+- [Tetrigo](https://github.com/Broderick-Westrope/tetrigo): Tetris in the terminal
+- [Signls](https://github.com/emprcl/signls): a generative midi sequencer designed for composition and live performance
+- [Superfile](https://github.com/yorukot/superfile): a super file manager
+
+### In Industry
+
+- Microsoft Azure – [Aztify](https://github.com/Azure/aztfy): bring Microsoft Azure resources under Terraform
+- Daytona – [Daytona](https://github.com/daytonaio/daytona): open source dev environment manager
+- Cockroach Labs – [CockroachDB](https://github.com/cockroachdb/cockroach): a cloud-native, high-availability distributed SQL database
+- Truffle Security Co. – [Trufflehog](https://github.com/trufflesecurity/trufflehog): find leaked credentials
+- NVIDIA – [container-canary](https://github.com/NVIDIA/container-canary): a container validator
+- AWS – [eks-node-viewer](https://github.com/awslabs/eks-node-viewer): a tool for visualizing dynamic node usage within an EKS cluster
+- MinIO – [mc](https://github.com/minio/mc): the official [MinIO](https://min.io) client
+- Ubuntu – [Authd](https://github.com/ubuntu/authd): an authentication daemon for cloud-based identity providers
+
+### Charm stuff
+
+- [Glow](https://github.com/charmbracelet/glow): a markdown reader, browser, and online markdown stash
+- [Huh?](https://github.com/charmbracelet/huh): an interactive prompt and form toolkit
+- [Mods](https://github.com/charmbracelet/mods): AI on the CLI, built for pipelines
+- [Wishlist](https://github.com/charmbracelet/wishlist): an SSH directory (and bastion!)
+
+### There’s so much more where that came from
+
+For more applications built with Bubble Tea see [Charm & Friends][community].
+Is there something cool you made with Bubble Tea you want to share? [PRs][community] are
+welcome!
+
+## Contributing
+
+See [contributing][contribute].
+
+[contribute]: https://github.com/charmbracelet/bubbletea/contribute
+
+## Feedback
+
+We’d love to hear your thoughts on this project. Feel free to drop us a note!
+
+- [Twitter](https://twitter.com/charmcli)
+- [The Fediverse](https://mastodon.social/@charmcli)
+- [Discord](https://charm.sh/chat)
+
+## Acknowledgments
+
+Bubble Tea is based on the paradigms of [The Elm Architecture][elm] by Evan
+Czaplicki et alia and the excellent [go-tea][gotea] by TJ Holowaychuk. It’s
+inspired by the many great [_Zeichenorientierte Benutzerschnittstellen_][zb]
+of days past.
+
+[elm]: https://guide.elm-lang.org/architecture/
+[gotea]: https://github.com/tj/go-tea
+[zb]: https://de.wikipedia.org/wiki/Zeichenorientierte_Benutzerschnittstelle
+[community]: https://github.com/charm-and-friends/charm-in-the-wild
+
+## License
+
+[MIT](https://github.com/charmbracelet/bubbletea/raw/main/LICENSE)
+
+---
+
+Part of [Charm](https://charm.sh).
+
+
+
+Charm热爱开源 • Charm loves open source • نحنُ نحب المصادر المفتوحة
diff --git a/vendor/github.com/charmbracelet/bubbletea/commands.go b/vendor/github.com/charmbracelet/bubbletea/commands.go
new file mode 100644
index 0000000..bfa3b70
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/commands.go
@@ -0,0 +1,216 @@
+package tea
+
+import (
+ "time"
+)
+
+// Batch performs a bunch of commands concurrently with no ordering guarantees
+// about the results. Use a Batch to return several commands.
+//
+// Example:
+//
+// func (m model) Init() Cmd {
+// return tea.Batch(someCommand, someOtherCommand)
+// }
+func Batch(cmds ...Cmd) Cmd {
+ var validCmds []Cmd //nolint:prealloc
+ for _, c := range cmds {
+ if c == nil {
+ continue
+ }
+ validCmds = append(validCmds, c)
+ }
+ switch len(validCmds) {
+ case 0:
+ return nil
+ case 1:
+ return validCmds[0]
+ default:
+ return func() Msg {
+ return BatchMsg(validCmds)
+ }
+ }
+}
+
+// BatchMsg is a message used to perform a bunch of commands concurrently with
+// no ordering guarantees. You can send a BatchMsg with Batch.
+type BatchMsg []Cmd
+
+// Sequence runs the given commands one at a time, in order. Contrast this with
+// Batch, which runs commands concurrently.
+func Sequence(cmds ...Cmd) Cmd {
+ return func() Msg {
+ return sequenceMsg(cmds)
+ }
+}
+
+// sequenceMsg is used internally to run the given commands in order.
+type sequenceMsg []Cmd
+
+// Every is a command that ticks in sync with the system clock. So, if you
+// wanted to tick with the system clock every second, minute or hour you
+// could use this. It's also handy for having different things tick in sync.
+//
+// Because we're ticking with the system clock the tick will likely not run for
+// the entire specified duration. For example, if we're ticking for one minute
+// and the clock is at 12:34:20 then the next tick will happen at 12:35:00, 40
+// seconds later.
+//
+// To produce the command, pass a duration and a function which returns
+// a message containing the time at which the tick occurred.
+//
+// type TickMsg time.Time
+//
+// cmd := Every(time.Second, func(t time.Time) Msg {
+// return TickMsg(t)
+// })
+//
+// Beginners' note: Every sends a single message and won't automatically
+// dispatch messages at an interval. To do that, you'll want to return another
+// Every command after receiving your tick message. For example:
+//
+// type TickMsg time.Time
+//
+// // Send a message every second.
+// func tickEvery() Cmd {
+// return Every(time.Second, func(t time.Time) Msg {
+// return TickMsg(t)
+// })
+// }
+//
+// func (m model) Init() Cmd {
+// // Start ticking.
+// return tickEvery()
+// }
+//
+// func (m model) Update(msg Msg) (Model, Cmd) {
+// switch msg.(type) {
+// case TickMsg:
+// // Return your Every command again to loop.
+// return m, tickEvery()
+// }
+// return m, nil
+// }
+//
+// Every is analogous to Tick in the Elm Architecture.
+func Every(duration time.Duration, fn func(time.Time) Msg) Cmd {
+ n := time.Now()
+ d := n.Truncate(duration).Add(duration).Sub(n)
+ t := time.NewTimer(d)
+ return func() Msg {
+ ts := <-t.C
+ t.Stop()
+ for len(t.C) > 0 {
+ <-t.C
+ }
+ return fn(ts)
+ }
+}
+
+// Tick produces a command at an interval independent of the system clock at
+// the given duration. That is, the timer begins precisely when invoked,
+// and runs for its entire duration.
+//
+// To produce the command, pass a duration and a function which returns
+// a message containing the time at which the tick occurred.
+//
+// type TickMsg time.Time
+//
+// cmd := Tick(time.Second, func(t time.Time) Msg {
+// return TickMsg(t)
+// })
+//
+// Beginners' note: Tick sends a single message and won't automatically
+// dispatch messages at an interval. To do that, you'll want to return another
+// Tick command after receiving your tick message. For example:
+//
+// type TickMsg time.Time
+//
+// func doTick() Cmd {
+// return Tick(time.Second, func(t time.Time) Msg {
+// return TickMsg(t)
+// })
+// }
+//
+// func (m model) Init() Cmd {
+// // Start ticking.
+// return doTick()
+// }
+//
+// func (m model) Update(msg Msg) (Model, Cmd) {
+// switch msg.(type) {
+// case TickMsg:
+// // Return your Tick command again to loop.
+// return m, doTick()
+// }
+// return m, nil
+// }
+func Tick(d time.Duration, fn func(time.Time) Msg) Cmd {
+ t := time.NewTimer(d)
+ return func() Msg {
+ ts := <-t.C
+ t.Stop()
+ for len(t.C) > 0 {
+ <-t.C
+ }
+ return fn(ts)
+ }
+}
+
+// Sequentially produces a command that sequentially executes the given
+// commands.
+// The Msg returned is the first non-nil message returned by a Cmd.
+//
+// func saveStateCmd() Msg {
+// if err := save(); err != nil {
+// return errMsg{err}
+// }
+// return nil
+// }
+//
+// cmd := Sequentially(saveStateCmd, Quit)
+//
+// Deprecated: use Sequence instead.
+func Sequentially(cmds ...Cmd) Cmd {
+ return func() Msg {
+ for _, cmd := range cmds {
+ if cmd == nil {
+ continue
+ }
+ if msg := cmd(); msg != nil {
+ return msg
+ }
+ }
+ return nil
+ }
+}
+
+// setWindowTitleMsg is an internal message used to set the window title.
+type setWindowTitleMsg string
+
+// SetWindowTitle produces a command that sets the terminal title.
+//
+// For example:
+//
+// func (m model) Init() Cmd {
+// // Set title.
+// return tea.SetWindowTitle("My App")
+// }
+func SetWindowTitle(title string) Cmd {
+ return func() Msg {
+ return setWindowTitleMsg(title)
+ }
+}
+
+type windowSizeMsg struct{}
+
+// WindowSize is a command that queries the terminal for its current size. It
+// delivers the results to Update via a [WindowSizeMsg]. Keep in mind that
+// WindowSizeMsgs will automatically be delivered to Update when the [Program]
+// starts and when the window dimensions change so in many cases you will not
+// need to explicitly invoke this command.
+func WindowSize() Cmd {
+ return func() Msg {
+ return windowSizeMsg{}
+ }
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/exec.go b/vendor/github.com/charmbracelet/bubbletea/exec.go
new file mode 100644
index 0000000..7a14d2a
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/exec.go
@@ -0,0 +1,129 @@
+package tea
+
+import (
+ "io"
+ "os"
+ "os/exec"
+)
+
+// execMsg is used internally to run an ExecCommand sent with Exec.
+type execMsg struct {
+ cmd ExecCommand
+ fn ExecCallback
+}
+
+// Exec is used to perform arbitrary I/O in a blocking fashion, effectively
+// pausing the Program while execution is running and resuming it when
+// execution has completed.
+//
+// Most of the time you'll want to use ExecProcess, which runs an exec.Cmd.
+//
+// For non-interactive i/o you should use a Cmd (that is, a tea.Cmd).
+func Exec(c ExecCommand, fn ExecCallback) Cmd {
+ return func() Msg {
+ return execMsg{cmd: c, fn: fn}
+ }
+}
+
+// ExecProcess runs the given *exec.Cmd in a blocking fashion, effectively
+// pausing the Program while the command is running. After the *exec.Cmd exists
+// the Program resumes. It's useful for spawning other interactive applications
+// such as editors and shells from within a Program.
+//
+// To produce the command, pass an *exec.Cmd and a function which returns
+// a message containing the error which may have occurred when running the
+// ExecCommand.
+//
+// type VimFinishedMsg struct { err error }
+//
+// c := exec.Command("vim", "file.txt")
+//
+// cmd := ExecProcess(c, func(err error) Msg {
+// return VimFinishedMsg{err: err}
+// })
+//
+// Or, if you don't care about errors, you could simply:
+//
+// cmd := ExecProcess(exec.Command("vim", "file.txt"), nil)
+//
+// For non-interactive i/o you should use a Cmd (that is, a tea.Cmd).
+func ExecProcess(c *exec.Cmd, fn ExecCallback) Cmd {
+ return Exec(wrapExecCommand(c), fn)
+}
+
+// ExecCallback is used when executing an *exec.Command to return a message
+// with an error, which may or may not be nil.
+type ExecCallback func(error) Msg
+
+// ExecCommand can be implemented to execute things in a blocking fashion in
+// the current terminal.
+type ExecCommand interface {
+ Run() error
+ SetStdin(io.Reader)
+ SetStdout(io.Writer)
+ SetStderr(io.Writer)
+}
+
+// wrapExecCommand wraps an exec.Cmd so that it satisfies the ExecCommand
+// interface so it can be used with Exec.
+func wrapExecCommand(c *exec.Cmd) ExecCommand {
+ return &osExecCommand{Cmd: c}
+}
+
+// osExecCommand is a layer over an exec.Cmd that satisfies the ExecCommand
+// interface.
+type osExecCommand struct{ *exec.Cmd }
+
+// SetStdin sets stdin on underlying exec.Cmd to the given io.Reader.
+func (c *osExecCommand) SetStdin(r io.Reader) {
+ // If unset, have the command use the same input as the terminal.
+ if c.Stdin == nil {
+ c.Stdin = r
+ }
+}
+
+// SetStdout sets stdout on underlying exec.Cmd to the given io.Writer.
+func (c *osExecCommand) SetStdout(w io.Writer) {
+ // If unset, have the command use the same output as the terminal.
+ if c.Stdout == nil {
+ c.Stdout = w
+ }
+}
+
+// SetStderr sets stderr on the underlying exec.Cmd to the given io.Writer.
+func (c *osExecCommand) SetStderr(w io.Writer) {
+ // If unset, use stderr for the command's stderr
+ if c.Stderr == nil {
+ c.Stderr = w
+ }
+}
+
+// exec runs an ExecCommand and delivers the results to the program as a Msg.
+func (p *Program) exec(c ExecCommand, fn ExecCallback) {
+ if err := p.ReleaseTerminal(); err != nil {
+ // If we can't release input, abort.
+ if fn != nil {
+ go p.Send(fn(err))
+ }
+ return
+ }
+
+ c.SetStdin(p.input)
+ c.SetStdout(p.output)
+ c.SetStderr(os.Stderr)
+
+ // Execute system command.
+ if err := c.Run(); err != nil {
+ _ = p.RestoreTerminal() // also try to restore the terminal.
+ if fn != nil {
+ go p.Send(fn(err))
+ }
+ return
+ }
+
+ // Have the program re-capture input.
+ err := p.RestoreTerminal()
+ if fn != nil {
+ go p.Send(fn(err))
+ }
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/focus.go b/vendor/github.com/charmbracelet/bubbletea/focus.go
new file mode 100644
index 0000000..4d34bea
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/focus.go
@@ -0,0 +1,9 @@
+package tea
+
+// FocusMsg represents a terminal focus message.
+// This occurs when the terminal gains focus.
+type FocusMsg struct{}
+
+// BlurMsg represents a terminal blur message.
+// This occurs when the terminal loses focus.
+type BlurMsg struct{}
diff --git a/vendor/github.com/charmbracelet/bubbletea/inputreader_other.go b/vendor/github.com/charmbracelet/bubbletea/inputreader_other.go
new file mode 100644
index 0000000..8e63a87
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/inputreader_other.go
@@ -0,0 +1,14 @@
+//go:build !windows
+// +build !windows
+
+package tea
+
+import (
+ "io"
+
+ "github.com/muesli/cancelreader"
+)
+
+func newInputReader(r io.Reader) (cancelreader.CancelReader, error) {
+ return cancelreader.NewReader(r)
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/inputreader_windows.go b/vendor/github.com/charmbracelet/bubbletea/inputreader_windows.go
new file mode 100644
index 0000000..dd5277c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/inputreader_windows.go
@@ -0,0 +1,117 @@
+//go:build windows
+// +build windows
+
+package tea
+
+import (
+ "fmt"
+ "io"
+ "os"
+ "sync"
+
+ "github.com/charmbracelet/x/term"
+ "github.com/erikgeiser/coninput"
+ "github.com/muesli/cancelreader"
+ "golang.org/x/sys/windows"
+)
+
+type conInputReader struct {
+ cancelMixin
+
+ conin windows.Handle
+
+ originalMode uint32
+}
+
+var _ cancelreader.CancelReader = &conInputReader{}
+
+func newInputReader(r io.Reader) (cancelreader.CancelReader, error) {
+ fallback := func(io.Reader) (cancelreader.CancelReader, error) {
+ return cancelreader.NewReader(r)
+ }
+ if f, ok := r.(term.File); !ok || f.Fd() != os.Stdin.Fd() {
+ return fallback(r)
+ }
+
+ conin, err := coninput.NewStdinHandle()
+ if err != nil {
+ return fallback(r)
+ }
+
+ originalMode, err := prepareConsole(conin,
+ windows.ENABLE_MOUSE_INPUT,
+ windows.ENABLE_WINDOW_INPUT,
+ windows.ENABLE_EXTENDED_FLAGS,
+ )
+ if err != nil {
+ return nil, fmt.Errorf("failed to prepare console input: %w", err)
+ }
+
+ return &conInputReader{
+ conin: conin,
+ originalMode: originalMode,
+ }, nil
+}
+
+// Cancel implements cancelreader.CancelReader.
+func (r *conInputReader) Cancel() bool {
+ r.setCanceled()
+
+ return windows.CancelIoEx(r.conin, nil) == nil || windows.CancelIo(r.conin) == nil
+}
+
+// Close implements cancelreader.CancelReader.
+func (r *conInputReader) Close() error {
+ if r.originalMode != 0 {
+ err := windows.SetConsoleMode(r.conin, r.originalMode)
+ if err != nil {
+ return fmt.Errorf("reset console mode: %w", err)
+ }
+ }
+
+ return nil
+}
+
+// Read implements cancelreader.CancelReader.
+func (r *conInputReader) Read(_ []byte) (n int, err error) {
+ if r.isCanceled() {
+ err = cancelreader.ErrCanceled
+ }
+ return
+}
+
+func prepareConsole(input windows.Handle, modes ...uint32) (originalMode uint32, err error) {
+ err = windows.GetConsoleMode(input, &originalMode)
+ if err != nil {
+ return 0, fmt.Errorf("get console mode: %w", err)
+ }
+
+ newMode := coninput.AddInputModes(0, modes...)
+
+ err = windows.SetConsoleMode(input, newMode)
+ if err != nil {
+ return 0, fmt.Errorf("set console mode: %w", err)
+ }
+
+ return originalMode, nil
+}
+
+// cancelMixin represents a goroutine-safe cancelation status.
+type cancelMixin struct {
+ unsafeCanceled bool
+ lock sync.Mutex
+}
+
+func (c *cancelMixin) setCanceled() {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ c.unsafeCanceled = true
+}
+
+func (c *cancelMixin) isCanceled() bool {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ return c.unsafeCanceled
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/key.go b/vendor/github.com/charmbracelet/bubbletea/key.go
new file mode 100644
index 0000000..ab4792a
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/key.go
@@ -0,0 +1,715 @@
+package tea
+
+import (
+ "context"
+ "fmt"
+ "io"
+ "regexp"
+ "strings"
+ "unicode/utf8"
+)
+
+// KeyMsg contains information about a keypress. KeyMsgs are always sent to
+// the program's update function. There are a couple general patterns you could
+// use to check for keypresses:
+//
+// // Switch on the string representation of the key (shorter)
+// switch msg := msg.(type) {
+// case KeyMsg:
+// switch msg.String() {
+// case "enter":
+// fmt.Println("you pressed enter!")
+// case "a":
+// fmt.Println("you pressed a!")
+// }
+// }
+//
+// // Switch on the key type (more foolproof)
+// switch msg := msg.(type) {
+// case KeyMsg:
+// switch msg.Type {
+// case KeyEnter:
+// fmt.Println("you pressed enter!")
+// case KeyRunes:
+// switch string(msg.Runes) {
+// case "a":
+// fmt.Println("you pressed a!")
+// }
+// }
+// }
+//
+// Note that Key.Runes will always contain at least one character, so you can
+// always safely call Key.Runes[0]. In most cases Key.Runes will only contain
+// one character, though certain input method editors (most notably Chinese
+// IMEs) can input multiple runes at once.
+type KeyMsg Key
+
+// String returns a string representation for a key message. It's safe (and
+// encouraged) for use in key comparison.
+func (k KeyMsg) String() (str string) {
+ return Key(k).String()
+}
+
+// Key contains information about a keypress.
+type Key struct {
+ Type KeyType
+ Runes []rune
+ Alt bool
+ Paste bool
+}
+
+// String returns a friendly string representation for a key. It's safe (and
+// encouraged) for use in key comparison.
+//
+// k := Key{Type: KeyEnter}
+// fmt.Println(k)
+// // Output: enter
+func (k Key) String() (str string) {
+ var buf strings.Builder
+ if k.Alt {
+ buf.WriteString("alt+")
+ }
+ if k.Type == KeyRunes {
+ if k.Paste {
+ // Note: bubbles/keys bindings currently do string compares to
+ // recognize shortcuts. Since pasted text should never activate
+ // shortcuts, we need to ensure that the binding code doesn't
+ // match Key events that result from pastes. We achieve this
+ // here by enclosing pastes in '[...]' so that the string
+ // comparison in Matches() fails in that case.
+ buf.WriteByte('[')
+ }
+ buf.WriteString(string(k.Runes))
+ if k.Paste {
+ buf.WriteByte(']')
+ }
+ return buf.String()
+ } else if s, ok := keyNames[k.Type]; ok {
+ buf.WriteString(s)
+ return buf.String()
+ }
+ return ""
+}
+
+// KeyType indicates the key pressed, such as KeyEnter or KeyBreak or KeyCtrlC.
+// All other keys will be type KeyRunes. To get the rune value, check the Rune
+// method on a Key struct, or use the Key.String() method:
+//
+// k := Key{Type: KeyRunes, Runes: []rune{'a'}, Alt: true}
+// if k.Type == KeyRunes {
+//
+// fmt.Println(k.Runes)
+// // Output: a
+//
+// fmt.Println(k.String())
+// // Output: alt+a
+//
+// }
+type KeyType int
+
+func (k KeyType) String() (str string) {
+ if s, ok := keyNames[k]; ok {
+ return s
+ }
+ return ""
+}
+
+// Control keys. We could do this with an iota, but the values are very
+// specific, so we set the values explicitly to avoid any confusion.
+//
+// See also:
+// https://en.wikipedia.org/wiki/C0_and_C1_control_codes
+const (
+ keyNUL KeyType = 0 // null, \0
+ keySOH KeyType = 1 // start of heading
+ keySTX KeyType = 2 // start of text
+ keyETX KeyType = 3 // break, ctrl+c
+ keyEOT KeyType = 4 // end of transmission
+ keyENQ KeyType = 5 // enquiry
+ keyACK KeyType = 6 // acknowledge
+ keyBEL KeyType = 7 // bell, \a
+ keyBS KeyType = 8 // backspace
+ keyHT KeyType = 9 // horizontal tabulation, \t
+ keyLF KeyType = 10 // line feed, \n
+ keyVT KeyType = 11 // vertical tabulation \v
+ keyFF KeyType = 12 // form feed \f
+ keyCR KeyType = 13 // carriage return, \r
+ keySO KeyType = 14 // shift out
+ keySI KeyType = 15 // shift in
+ keyDLE KeyType = 16 // data link escape
+ keyDC1 KeyType = 17 // device control one
+ keyDC2 KeyType = 18 // device control two
+ keyDC3 KeyType = 19 // device control three
+ keyDC4 KeyType = 20 // device control four
+ keyNAK KeyType = 21 // negative acknowledge
+ keySYN KeyType = 22 // synchronous idle
+ keyETB KeyType = 23 // end of transmission block
+ keyCAN KeyType = 24 // cancel
+ keyEM KeyType = 25 // end of medium
+ keySUB KeyType = 26 // substitution
+ keyESC KeyType = 27 // escape, \e
+ keyFS KeyType = 28 // file separator
+ keyGS KeyType = 29 // group separator
+ keyRS KeyType = 30 // record separator
+ keyUS KeyType = 31 // unit separator
+ keyDEL KeyType = 127 // delete. on most systems this is mapped to backspace, I hear
+)
+
+// Control key aliases.
+const (
+ KeyNull KeyType = keyNUL
+ KeyBreak KeyType = keyETX
+ KeyEnter KeyType = keyCR
+ KeyBackspace KeyType = keyDEL
+ KeyTab KeyType = keyHT
+ KeyEsc KeyType = keyESC
+ KeyEscape KeyType = keyESC
+
+ KeyCtrlAt KeyType = keyNUL // ctrl+@
+ KeyCtrlA KeyType = keySOH
+ KeyCtrlB KeyType = keySTX
+ KeyCtrlC KeyType = keyETX
+ KeyCtrlD KeyType = keyEOT
+ KeyCtrlE KeyType = keyENQ
+ KeyCtrlF KeyType = keyACK
+ KeyCtrlG KeyType = keyBEL
+ KeyCtrlH KeyType = keyBS
+ KeyCtrlI KeyType = keyHT
+ KeyCtrlJ KeyType = keyLF
+ KeyCtrlK KeyType = keyVT
+ KeyCtrlL KeyType = keyFF
+ KeyCtrlM KeyType = keyCR
+ KeyCtrlN KeyType = keySO
+ KeyCtrlO KeyType = keySI
+ KeyCtrlP KeyType = keyDLE
+ KeyCtrlQ KeyType = keyDC1
+ KeyCtrlR KeyType = keyDC2
+ KeyCtrlS KeyType = keyDC3
+ KeyCtrlT KeyType = keyDC4
+ KeyCtrlU KeyType = keyNAK
+ KeyCtrlV KeyType = keySYN
+ KeyCtrlW KeyType = keyETB
+ KeyCtrlX KeyType = keyCAN
+ KeyCtrlY KeyType = keyEM
+ KeyCtrlZ KeyType = keySUB
+ KeyCtrlOpenBracket KeyType = keyESC // ctrl+[
+ KeyCtrlBackslash KeyType = keyFS // ctrl+\
+ KeyCtrlCloseBracket KeyType = keyGS // ctrl+]
+ KeyCtrlCaret KeyType = keyRS // ctrl+^
+ KeyCtrlUnderscore KeyType = keyUS // ctrl+_
+ KeyCtrlQuestionMark KeyType = keyDEL // ctrl+?
+)
+
+// Other keys.
+const (
+ KeyRunes KeyType = -(iota + 1)
+ KeyUp
+ KeyDown
+ KeyRight
+ KeyLeft
+ KeyShiftTab
+ KeyHome
+ KeyEnd
+ KeyPgUp
+ KeyPgDown
+ KeyCtrlPgUp
+ KeyCtrlPgDown
+ KeyDelete
+ KeyInsert
+ KeySpace
+ KeyCtrlUp
+ KeyCtrlDown
+ KeyCtrlRight
+ KeyCtrlLeft
+ KeyCtrlHome
+ KeyCtrlEnd
+ KeyShiftUp
+ KeyShiftDown
+ KeyShiftRight
+ KeyShiftLeft
+ KeyShiftHome
+ KeyShiftEnd
+ KeyCtrlShiftUp
+ KeyCtrlShiftDown
+ KeyCtrlShiftLeft
+ KeyCtrlShiftRight
+ KeyCtrlShiftHome
+ KeyCtrlShiftEnd
+ KeyF1
+ KeyF2
+ KeyF3
+ KeyF4
+ KeyF5
+ KeyF6
+ KeyF7
+ KeyF8
+ KeyF9
+ KeyF10
+ KeyF11
+ KeyF12
+ KeyF13
+ KeyF14
+ KeyF15
+ KeyF16
+ KeyF17
+ KeyF18
+ KeyF19
+ KeyF20
+)
+
+// Mappings for control keys and other special keys to friendly consts.
+var keyNames = map[KeyType]string{
+ // Control keys.
+ keyNUL: "ctrl+@", // also ctrl+` (that's ctrl+backtick)
+ keySOH: "ctrl+a",
+ keySTX: "ctrl+b",
+ keyETX: "ctrl+c",
+ keyEOT: "ctrl+d",
+ keyENQ: "ctrl+e",
+ keyACK: "ctrl+f",
+ keyBEL: "ctrl+g",
+ keyBS: "ctrl+h",
+ keyHT: "tab", // also ctrl+i
+ keyLF: "ctrl+j",
+ keyVT: "ctrl+k",
+ keyFF: "ctrl+l",
+ keyCR: "enter",
+ keySO: "ctrl+n",
+ keySI: "ctrl+o",
+ keyDLE: "ctrl+p",
+ keyDC1: "ctrl+q",
+ keyDC2: "ctrl+r",
+ keyDC3: "ctrl+s",
+ keyDC4: "ctrl+t",
+ keyNAK: "ctrl+u",
+ keySYN: "ctrl+v",
+ keyETB: "ctrl+w",
+ keyCAN: "ctrl+x",
+ keyEM: "ctrl+y",
+ keySUB: "ctrl+z",
+ keyESC: "esc",
+ keyFS: "ctrl+\\",
+ keyGS: "ctrl+]",
+ keyRS: "ctrl+^",
+ keyUS: "ctrl+_",
+ keyDEL: "backspace",
+
+ // Other keys.
+ KeyRunes: "runes",
+ KeyUp: "up",
+ KeyDown: "down",
+ KeyRight: "right",
+ KeySpace: " ", // for backwards compatibility
+ KeyLeft: "left",
+ KeyShiftTab: "shift+tab",
+ KeyHome: "home",
+ KeyEnd: "end",
+ KeyCtrlHome: "ctrl+home",
+ KeyCtrlEnd: "ctrl+end",
+ KeyShiftHome: "shift+home",
+ KeyShiftEnd: "shift+end",
+ KeyCtrlShiftHome: "ctrl+shift+home",
+ KeyCtrlShiftEnd: "ctrl+shift+end",
+ KeyPgUp: "pgup",
+ KeyPgDown: "pgdown",
+ KeyCtrlPgUp: "ctrl+pgup",
+ KeyCtrlPgDown: "ctrl+pgdown",
+ KeyDelete: "delete",
+ KeyInsert: "insert",
+ KeyCtrlUp: "ctrl+up",
+ KeyCtrlDown: "ctrl+down",
+ KeyCtrlRight: "ctrl+right",
+ KeyCtrlLeft: "ctrl+left",
+ KeyShiftUp: "shift+up",
+ KeyShiftDown: "shift+down",
+ KeyShiftRight: "shift+right",
+ KeyShiftLeft: "shift+left",
+ KeyCtrlShiftUp: "ctrl+shift+up",
+ KeyCtrlShiftDown: "ctrl+shift+down",
+ KeyCtrlShiftLeft: "ctrl+shift+left",
+ KeyCtrlShiftRight: "ctrl+shift+right",
+ KeyF1: "f1",
+ KeyF2: "f2",
+ KeyF3: "f3",
+ KeyF4: "f4",
+ KeyF5: "f5",
+ KeyF6: "f6",
+ KeyF7: "f7",
+ KeyF8: "f8",
+ KeyF9: "f9",
+ KeyF10: "f10",
+ KeyF11: "f11",
+ KeyF12: "f12",
+ KeyF13: "f13",
+ KeyF14: "f14",
+ KeyF15: "f15",
+ KeyF16: "f16",
+ KeyF17: "f17",
+ KeyF18: "f18",
+ KeyF19: "f19",
+ KeyF20: "f20",
+}
+
+// Sequence mappings.
+var sequences = map[string]Key{
+ // Arrow keys
+ "\x1b[A": {Type: KeyUp},
+ "\x1b[B": {Type: KeyDown},
+ "\x1b[C": {Type: KeyRight},
+ "\x1b[D": {Type: KeyLeft},
+ "\x1b[1;2A": {Type: KeyShiftUp},
+ "\x1b[1;2B": {Type: KeyShiftDown},
+ "\x1b[1;2C": {Type: KeyShiftRight},
+ "\x1b[1;2D": {Type: KeyShiftLeft},
+ "\x1b[OA": {Type: KeyShiftUp}, // DECCKM
+ "\x1b[OB": {Type: KeyShiftDown}, // DECCKM
+ "\x1b[OC": {Type: KeyShiftRight}, // DECCKM
+ "\x1b[OD": {Type: KeyShiftLeft}, // DECCKM
+ "\x1b[a": {Type: KeyShiftUp}, // urxvt
+ "\x1b[b": {Type: KeyShiftDown}, // urxvt
+ "\x1b[c": {Type: KeyShiftRight}, // urxvt
+ "\x1b[d": {Type: KeyShiftLeft}, // urxvt
+ "\x1b[1;3A": {Type: KeyUp, Alt: true},
+ "\x1b[1;3B": {Type: KeyDown, Alt: true},
+ "\x1b[1;3C": {Type: KeyRight, Alt: true},
+ "\x1b[1;3D": {Type: KeyLeft, Alt: true},
+
+ "\x1b[1;4A": {Type: KeyShiftUp, Alt: true},
+ "\x1b[1;4B": {Type: KeyShiftDown, Alt: true},
+ "\x1b[1;4C": {Type: KeyShiftRight, Alt: true},
+ "\x1b[1;4D": {Type: KeyShiftLeft, Alt: true},
+
+ "\x1b[1;5A": {Type: KeyCtrlUp},
+ "\x1b[1;5B": {Type: KeyCtrlDown},
+ "\x1b[1;5C": {Type: KeyCtrlRight},
+ "\x1b[1;5D": {Type: KeyCtrlLeft},
+ "\x1b[Oa": {Type: KeyCtrlUp, Alt: true}, // urxvt
+ "\x1b[Ob": {Type: KeyCtrlDown, Alt: true}, // urxvt
+ "\x1b[Oc": {Type: KeyCtrlRight, Alt: true}, // urxvt
+ "\x1b[Od": {Type: KeyCtrlLeft, Alt: true}, // urxvt
+ "\x1b[1;6A": {Type: KeyCtrlShiftUp},
+ "\x1b[1;6B": {Type: KeyCtrlShiftDown},
+ "\x1b[1;6C": {Type: KeyCtrlShiftRight},
+ "\x1b[1;6D": {Type: KeyCtrlShiftLeft},
+ "\x1b[1;7A": {Type: KeyCtrlUp, Alt: true},
+ "\x1b[1;7B": {Type: KeyCtrlDown, Alt: true},
+ "\x1b[1;7C": {Type: KeyCtrlRight, Alt: true},
+ "\x1b[1;7D": {Type: KeyCtrlLeft, Alt: true},
+ "\x1b[1;8A": {Type: KeyCtrlShiftUp, Alt: true},
+ "\x1b[1;8B": {Type: KeyCtrlShiftDown, Alt: true},
+ "\x1b[1;8C": {Type: KeyCtrlShiftRight, Alt: true},
+ "\x1b[1;8D": {Type: KeyCtrlShiftLeft, Alt: true},
+
+ // Miscellaneous keys
+ "\x1b[Z": {Type: KeyShiftTab},
+
+ "\x1b[2~": {Type: KeyInsert},
+ "\x1b[3;2~": {Type: KeyInsert, Alt: true},
+
+ "\x1b[3~": {Type: KeyDelete},
+ "\x1b[3;3~": {Type: KeyDelete, Alt: true},
+
+ "\x1b[5~": {Type: KeyPgUp},
+ "\x1b[5;3~": {Type: KeyPgUp, Alt: true},
+ "\x1b[5;5~": {Type: KeyCtrlPgUp},
+ "\x1b[5^": {Type: KeyCtrlPgUp}, // urxvt
+ "\x1b[5;7~": {Type: KeyCtrlPgUp, Alt: true},
+
+ "\x1b[6~": {Type: KeyPgDown},
+ "\x1b[6;3~": {Type: KeyPgDown, Alt: true},
+ "\x1b[6;5~": {Type: KeyCtrlPgDown},
+ "\x1b[6^": {Type: KeyCtrlPgDown}, // urxvt
+ "\x1b[6;7~": {Type: KeyCtrlPgDown, Alt: true},
+
+ "\x1b[1~": {Type: KeyHome},
+ "\x1b[H": {Type: KeyHome}, // xterm, lxterm
+ "\x1b[1;3H": {Type: KeyHome, Alt: true}, // xterm, lxterm
+ "\x1b[1;5H": {Type: KeyCtrlHome}, // xterm, lxterm
+ "\x1b[1;7H": {Type: KeyCtrlHome, Alt: true}, // xterm, lxterm
+ "\x1b[1;2H": {Type: KeyShiftHome}, // xterm, lxterm
+ "\x1b[1;4H": {Type: KeyShiftHome, Alt: true}, // xterm, lxterm
+ "\x1b[1;6H": {Type: KeyCtrlShiftHome}, // xterm, lxterm
+ "\x1b[1;8H": {Type: KeyCtrlShiftHome, Alt: true}, // xterm, lxterm
+
+ "\x1b[4~": {Type: KeyEnd},
+ "\x1b[F": {Type: KeyEnd}, // xterm, lxterm
+ "\x1b[1;3F": {Type: KeyEnd, Alt: true}, // xterm, lxterm
+ "\x1b[1;5F": {Type: KeyCtrlEnd}, // xterm, lxterm
+ "\x1b[1;7F": {Type: KeyCtrlEnd, Alt: true}, // xterm, lxterm
+ "\x1b[1;2F": {Type: KeyShiftEnd}, // xterm, lxterm
+ "\x1b[1;4F": {Type: KeyShiftEnd, Alt: true}, // xterm, lxterm
+ "\x1b[1;6F": {Type: KeyCtrlShiftEnd}, // xterm, lxterm
+ "\x1b[1;8F": {Type: KeyCtrlShiftEnd, Alt: true}, // xterm, lxterm
+
+ "\x1b[7~": {Type: KeyHome}, // urxvt
+ "\x1b[7^": {Type: KeyCtrlHome}, // urxvt
+ "\x1b[7$": {Type: KeyShiftHome}, // urxvt
+ "\x1b[7@": {Type: KeyCtrlShiftHome}, // urxvt
+
+ "\x1b[8~": {Type: KeyEnd}, // urxvt
+ "\x1b[8^": {Type: KeyCtrlEnd}, // urxvt
+ "\x1b[8$": {Type: KeyShiftEnd}, // urxvt
+ "\x1b[8@": {Type: KeyCtrlShiftEnd}, // urxvt
+
+ // Function keys, Linux console
+ "\x1b[[A": {Type: KeyF1}, // linux console
+ "\x1b[[B": {Type: KeyF2}, // linux console
+ "\x1b[[C": {Type: KeyF3}, // linux console
+ "\x1b[[D": {Type: KeyF4}, // linux console
+ "\x1b[[E": {Type: KeyF5}, // linux console
+
+ // Function keys, X11
+ "\x1bOP": {Type: KeyF1}, // vt100, xterm
+ "\x1bOQ": {Type: KeyF2}, // vt100, xterm
+ "\x1bOR": {Type: KeyF3}, // vt100, xterm
+ "\x1bOS": {Type: KeyF4}, // vt100, xterm
+
+ "\x1b[1;3P": {Type: KeyF1, Alt: true}, // vt100, xterm
+ "\x1b[1;3Q": {Type: KeyF2, Alt: true}, // vt100, xterm
+ "\x1b[1;3R": {Type: KeyF3, Alt: true}, // vt100, xterm
+ "\x1b[1;3S": {Type: KeyF4, Alt: true}, // vt100, xterm
+
+ "\x1b[11~": {Type: KeyF1}, // urxvt
+ "\x1b[12~": {Type: KeyF2}, // urxvt
+ "\x1b[13~": {Type: KeyF3}, // urxvt
+ "\x1b[14~": {Type: KeyF4}, // urxvt
+
+ "\x1b[15~": {Type: KeyF5}, // vt100, xterm, also urxvt
+
+ "\x1b[15;3~": {Type: KeyF5, Alt: true}, // vt100, xterm, also urxvt
+
+ "\x1b[17~": {Type: KeyF6}, // vt100, xterm, also urxvt
+ "\x1b[18~": {Type: KeyF7}, // vt100, xterm, also urxvt
+ "\x1b[19~": {Type: KeyF8}, // vt100, xterm, also urxvt
+ "\x1b[20~": {Type: KeyF9}, // vt100, xterm, also urxvt
+ "\x1b[21~": {Type: KeyF10}, // vt100, xterm, also urxvt
+
+ "\x1b[17;3~": {Type: KeyF6, Alt: true}, // vt100, xterm
+ "\x1b[18;3~": {Type: KeyF7, Alt: true}, // vt100, xterm
+ "\x1b[19;3~": {Type: KeyF8, Alt: true}, // vt100, xterm
+ "\x1b[20;3~": {Type: KeyF9, Alt: true}, // vt100, xterm
+ "\x1b[21;3~": {Type: KeyF10, Alt: true}, // vt100, xterm
+
+ "\x1b[23~": {Type: KeyF11}, // vt100, xterm, also urxvt
+ "\x1b[24~": {Type: KeyF12}, // vt100, xterm, also urxvt
+
+ "\x1b[23;3~": {Type: KeyF11, Alt: true}, // vt100, xterm
+ "\x1b[24;3~": {Type: KeyF12, Alt: true}, // vt100, xterm
+
+ "\x1b[1;2P": {Type: KeyF13},
+ "\x1b[1;2Q": {Type: KeyF14},
+
+ "\x1b[25~": {Type: KeyF13}, // vt100, xterm, also urxvt
+ "\x1b[26~": {Type: KeyF14}, // vt100, xterm, also urxvt
+
+ "\x1b[25;3~": {Type: KeyF13, Alt: true}, // vt100, xterm
+ "\x1b[26;3~": {Type: KeyF14, Alt: true}, // vt100, xterm
+
+ "\x1b[1;2R": {Type: KeyF15},
+ "\x1b[1;2S": {Type: KeyF16},
+
+ "\x1b[28~": {Type: KeyF15}, // vt100, xterm, also urxvt
+ "\x1b[29~": {Type: KeyF16}, // vt100, xterm, also urxvt
+
+ "\x1b[28;3~": {Type: KeyF15, Alt: true}, // vt100, xterm
+ "\x1b[29;3~": {Type: KeyF16, Alt: true}, // vt100, xterm
+
+ "\x1b[15;2~": {Type: KeyF17},
+ "\x1b[17;2~": {Type: KeyF18},
+ "\x1b[18;2~": {Type: KeyF19},
+ "\x1b[19;2~": {Type: KeyF20},
+
+ "\x1b[31~": {Type: KeyF17},
+ "\x1b[32~": {Type: KeyF18},
+ "\x1b[33~": {Type: KeyF19},
+ "\x1b[34~": {Type: KeyF20},
+
+ // Powershell sequences.
+ "\x1bOA": {Type: KeyUp, Alt: false},
+ "\x1bOB": {Type: KeyDown, Alt: false},
+ "\x1bOC": {Type: KeyRight, Alt: false},
+ "\x1bOD": {Type: KeyLeft, Alt: false},
+}
+
+// unknownInputByteMsg is reported by the input reader when an invalid
+// utf-8 byte is detected on the input. Currently, it is not handled
+// further by bubbletea. However, having this event makes it possible
+// to troubleshoot invalid inputs.
+type unknownInputByteMsg byte
+
+func (u unknownInputByteMsg) String() string {
+ return fmt.Sprintf("?%#02x?", int(u))
+}
+
+// unknownCSISequenceMsg is reported by the input reader when an
+// unrecognized CSI sequence is detected on the input. Currently, it
+// is not handled further by bubbletea. However, having this event
+// makes it possible to troubleshoot invalid inputs.
+type unknownCSISequenceMsg []byte
+
+func (u unknownCSISequenceMsg) String() string {
+ return fmt.Sprintf("?CSI%+v?", []byte(u)[2:])
+}
+
+var spaceRunes = []rune{' '}
+
+// readAnsiInputs reads keypress and mouse inputs from a TTY and produces messages
+// containing information about the key or mouse events accordingly.
+func readAnsiInputs(ctx context.Context, msgs chan<- Msg, input io.Reader) error {
+ var buf [256]byte
+
+ var leftOverFromPrevIteration []byte
+loop:
+ for {
+ // Read and block.
+ numBytes, err := input.Read(buf[:])
+ if err != nil {
+ return fmt.Errorf("error reading input: %w", err)
+ }
+ b := buf[:numBytes]
+ if leftOverFromPrevIteration != nil {
+ b = append(leftOverFromPrevIteration, b...)
+ }
+
+ // If we had a short read (numBytes < len(buf)), we're sure that
+ // the end of this read is an event boundary, so there is no doubt
+ // if we are encountering the end of the buffer while parsing a message.
+ // However, if we've succeeded in filling up the buffer, there may
+ // be more data in the OS buffer ready to be read in, to complete
+ // the last message in the input. In that case, we will retry with
+ // the left over data in the next iteration.
+ canHaveMoreData := numBytes == len(buf)
+
+ var i, w int
+ for i, w = 0, 0; i < len(b); i += w {
+ var msg Msg
+ w, msg = detectOneMsg(b[i:], canHaveMoreData)
+ if w == 0 {
+ // Expecting more bytes beyond the current buffer. Try waiting
+ // for more input.
+ leftOverFromPrevIteration = make([]byte, 0, len(b[i:])+len(buf))
+ leftOverFromPrevIteration = append(leftOverFromPrevIteration, b[i:]...)
+ continue loop
+ }
+
+ select {
+ case msgs <- msg:
+ case <-ctx.Done():
+ err := ctx.Err()
+ if err != nil {
+ err = fmt.Errorf("found context error while reading input: %w", err)
+ }
+ return err
+ }
+ }
+ leftOverFromPrevIteration = nil
+ }
+}
+
+var (
+ unknownCSIRe = regexp.MustCompile(`^\x1b\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]`)
+ mouseSGRRegex = regexp.MustCompile(`(\d+);(\d+);(\d+)([Mm])`)
+)
+
+func detectOneMsg(b []byte, canHaveMoreData bool) (w int, msg Msg) {
+ // Detect mouse events.
+ // X10 mouse events have a length of 6 bytes
+ const mouseEventX10Len = 6
+ if len(b) >= mouseEventX10Len && b[0] == '\x1b' && b[1] == '[' {
+ switch b[2] {
+ case 'M':
+ return mouseEventX10Len, MouseMsg(parseX10MouseEvent(b))
+ case '<':
+ if matchIndices := mouseSGRRegex.FindSubmatchIndex(b[3:]); matchIndices != nil {
+ // SGR mouse events length is the length of the match plus the length of the escape sequence
+ mouseEventSGRLen := matchIndices[1] + 3 //nolint:gomnd
+ return mouseEventSGRLen, MouseMsg(parseSGRMouseEvent(b))
+ }
+ }
+ }
+
+ // Detect focus events.
+ var foundRF bool
+ foundRF, w, msg = detectReportFocus(b)
+ if foundRF {
+ return w, msg
+ }
+
+ // Detect bracketed paste.
+ var foundbp bool
+ foundbp, w, msg = detectBracketedPaste(b)
+ if foundbp {
+ return w, msg
+ }
+
+ // Detect escape sequence and control characters other than NUL,
+ // possibly with an escape character in front to mark the Alt
+ // modifier.
+ var foundSeq bool
+ foundSeq, w, msg = detectSequence(b)
+ if foundSeq {
+ return w, msg
+ }
+
+ // No non-NUL control character or escape sequence.
+ // If we are seeing at least an escape character, remember it for later below.
+ alt := false
+ i := 0
+ if b[0] == '\x1b' {
+ alt = true
+ i++
+ }
+
+ // Are we seeing a standalone NUL? This is not handled by detectSequence().
+ if i < len(b) && b[i] == 0 {
+ return i + 1, KeyMsg{Type: keyNUL, Alt: alt}
+ }
+
+ // Find the longest sequence of runes that are not control
+ // characters from this point.
+ var runes []rune
+ for rw := 0; i < len(b); i += rw {
+ var r rune
+ r, rw = utf8.DecodeRune(b[i:])
+ if r == utf8.RuneError || r <= rune(keyUS) || r == rune(keyDEL) || r == ' ' {
+ // Rune errors are handled below; control characters and spaces will
+ // be handled by detectSequence in the next call to detectOneMsg.
+ break
+ }
+ runes = append(runes, r)
+ if alt {
+ // We only support a single rune after an escape alt modifier.
+ i += rw
+ break
+ }
+ }
+ if i >= len(b) && canHaveMoreData {
+ // We have encountered the end of the input buffer. Alas, we can't
+ // be sure whether the data in the remainder of the buffer is
+ // complete (maybe there was a short read). Instead of sending anything
+ // dumb to the message channel, do a short read. The outer loop will
+ // handle this case by extending the buffer as necessary.
+ return 0, nil
+ }
+
+ // If we found at least one rune, we report the bunch of them as
+ // a single KeyRunes or KeySpace event.
+ if len(runes) > 0 {
+ k := Key{Type: KeyRunes, Runes: runes, Alt: alt}
+ if len(runes) == 1 && runes[0] == ' ' {
+ k.Type = KeySpace
+ }
+ return i, KeyMsg(k)
+ }
+
+ // We didn't find an escape sequence, nor a valid rune. Was this a
+ // lone escape character at the end of the input?
+ if alt && len(b) == 1 {
+ return 1, KeyMsg(Key{Type: KeyEscape})
+ }
+
+ // The character at the current position is neither an escape
+ // sequence, a valid rune start or a sole escape character. Report
+ // it as an invalid byte.
+ return 1, unknownInputByteMsg(b[0])
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/key_other.go b/vendor/github.com/charmbracelet/bubbletea/key_other.go
new file mode 100644
index 0000000..b8c4608
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/key_other.go
@@ -0,0 +1,13 @@
+//go:build !windows
+// +build !windows
+
+package tea
+
+import (
+ "context"
+ "io"
+)
+
+func readInputs(ctx context.Context, msgs chan<- Msg, input io.Reader) error {
+ return readAnsiInputs(ctx, msgs, input)
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/key_sequences.go b/vendor/github.com/charmbracelet/bubbletea/key_sequences.go
new file mode 100644
index 0000000..15483ef
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/key_sequences.go
@@ -0,0 +1,131 @@
+package tea
+
+import (
+ "bytes"
+ "sort"
+ "unicode/utf8"
+)
+
+// extSequences is used by the map-based algorithm below. It contains
+// the sequences plus their alternatives with an escape character
+// prefixed, plus the control chars, plus the space.
+// It does not contain the NUL character, which is handled specially
+// by detectOneMsg.
+var extSequences = func() map[string]Key {
+ s := map[string]Key{}
+ for seq, key := range sequences {
+ key := key
+ s[seq] = key
+ if !key.Alt {
+ key.Alt = true
+ s["\x1b"+seq] = key
+ }
+ }
+ for i := keyNUL + 1; i <= keyDEL; i++ {
+ if i == keyESC {
+ continue
+ }
+ s[string([]byte{byte(i)})] = Key{Type: i}
+ s[string([]byte{'\x1b', byte(i)})] = Key{Type: i, Alt: true}
+ if i == keyUS {
+ i = keyDEL - 1
+ }
+ }
+ s[" "] = Key{Type: KeySpace, Runes: spaceRunes}
+ s["\x1b "] = Key{Type: KeySpace, Alt: true, Runes: spaceRunes}
+ s["\x1b\x1b"] = Key{Type: KeyEscape, Alt: true}
+ return s
+}()
+
+// seqLengths is the sizes of valid sequences, starting with the
+// largest size.
+var seqLengths = func() []int {
+ sizes := map[int]struct{}{}
+ for seq := range extSequences {
+ sizes[len(seq)] = struct{}{}
+ }
+ lsizes := make([]int, 0, len(sizes))
+ for sz := range sizes {
+ lsizes = append(lsizes, sz)
+ }
+ sort.Slice(lsizes, func(i, j int) bool { return lsizes[i] > lsizes[j] })
+ return lsizes
+}()
+
+// detectSequence uses a longest prefix match over the input
+// sequence and a hash map.
+func detectSequence(input []byte) (hasSeq bool, width int, msg Msg) {
+ seqs := extSequences
+ for _, sz := range seqLengths {
+ if sz > len(input) {
+ continue
+ }
+ prefix := input[:sz]
+ key, ok := seqs[string(prefix)]
+ if ok {
+ return true, sz, KeyMsg(key)
+ }
+ }
+ // Is this an unknown CSI sequence?
+ if loc := unknownCSIRe.FindIndex(input); loc != nil {
+ return true, loc[1], unknownCSISequenceMsg(input[:loc[1]])
+ }
+
+ return false, 0, nil
+}
+
+// detectBracketedPaste detects an input pasted while bracketed
+// paste mode was enabled.
+//
+// Note: this function is a no-op if bracketed paste was not enabled
+// on the terminal, since in that case we'd never see this
+// particular escape sequence.
+func detectBracketedPaste(input []byte) (hasBp bool, width int, msg Msg) {
+ // Detect the start sequence.
+ const bpStart = "\x1b[200~"
+ if len(input) < len(bpStart) || string(input[:len(bpStart)]) != bpStart {
+ return false, 0, nil
+ }
+
+ // Skip over the start sequence.
+ input = input[len(bpStart):]
+
+ // If we saw the start sequence, then we must have an end sequence
+ // as well. Find it.
+ const bpEnd = "\x1b[201~"
+ idx := bytes.Index(input, []byte(bpEnd))
+ inputLen := len(bpStart) + idx + len(bpEnd)
+ if idx == -1 {
+ // We have encountered the end of the input buffer without seeing
+ // the marker for the end of the bracketed paste.
+ // Tell the outer loop we have done a short read and we want more.
+ return true, 0, nil
+ }
+
+ // The paste is everything in-between.
+ paste := input[:idx]
+
+ // All there is in-between is runes, not to be interpreted further.
+ k := Key{Type: KeyRunes, Paste: true}
+ for len(paste) > 0 {
+ r, w := utf8.DecodeRune(paste)
+ if r != utf8.RuneError {
+ k.Runes = append(k.Runes, r)
+ }
+ paste = paste[w:]
+ }
+
+ return true, inputLen, KeyMsg(k)
+}
+
+// detectReportFocus detects a focus report sequence.
+// nolint: gomnd
+func detectReportFocus(input []byte) (hasRF bool, width int, msg Msg) {
+ switch {
+ case bytes.Equal(input, []byte("\x1b[I")):
+ return true, 3, FocusMsg{}
+ case bytes.Equal(input, []byte("\x1b[O")):
+ return true, 3, BlurMsg{}
+ }
+ return false, 0, nil
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/key_windows.go b/vendor/github.com/charmbracelet/bubbletea/key_windows.go
new file mode 100644
index 0000000..d59ff1c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/key_windows.go
@@ -0,0 +1,360 @@
+//go:build windows
+// +build windows
+
+package tea
+
+import (
+ "context"
+ "fmt"
+ "io"
+
+ "github.com/erikgeiser/coninput"
+ localereader "github.com/mattn/go-localereader"
+ "github.com/muesli/cancelreader"
+)
+
+func readInputs(ctx context.Context, msgs chan<- Msg, input io.Reader) error {
+ if coninReader, ok := input.(*conInputReader); ok {
+ return readConInputs(ctx, msgs, coninReader)
+ }
+
+ return readAnsiInputs(ctx, msgs, localereader.NewReader(input))
+}
+
+func readConInputs(ctx context.Context, msgsch chan<- Msg, con *conInputReader) error {
+ var ps coninput.ButtonState // keep track of previous mouse state
+ var ws coninput.WindowBufferSizeEventRecord // keep track of the last window size event
+ for {
+ events, err := coninput.ReadNConsoleInputs(con.conin, 16)
+ if err != nil {
+ if con.isCanceled() {
+ return cancelreader.ErrCanceled
+ }
+ return fmt.Errorf("read coninput events: %w", err)
+ }
+
+ for _, event := range events {
+ var msgs []Msg
+ switch e := event.Unwrap().(type) {
+ case coninput.KeyEventRecord:
+ if !e.KeyDown || e.VirtualKeyCode == coninput.VK_SHIFT {
+ continue
+ }
+
+ for i := 0; i < int(e.RepeatCount); i++ {
+ eventKeyType := keyType(e)
+ var runes []rune
+
+ // Add the character only if the key type is an actual character and not a control sequence.
+ // This mimics the behavior in readAnsiInputs where the character is also removed.
+ // We don't need to handle KeySpace here. See the comment in keyType().
+ if eventKeyType == KeyRunes {
+ runes = []rune{e.Char}
+ }
+
+ msgs = append(msgs, KeyMsg{
+ Type: eventKeyType,
+ Runes: runes,
+ Alt: e.ControlKeyState.Contains(coninput.LEFT_ALT_PRESSED | coninput.RIGHT_ALT_PRESSED),
+ })
+ }
+ case coninput.WindowBufferSizeEventRecord:
+ if e != ws {
+ ws = e
+ msgs = append(msgs, WindowSizeMsg{
+ Width: int(e.Size.X),
+ Height: int(e.Size.Y),
+ })
+ }
+ case coninput.MouseEventRecord:
+ event := mouseEvent(ps, e)
+ if event.Type != MouseUnknown {
+ msgs = append(msgs, event)
+ }
+ ps = e.ButtonState
+ case coninput.FocusEventRecord, coninput.MenuEventRecord:
+ // ignore
+ default: // unknown event
+ continue
+ }
+
+ // Send all messages to the channel
+ for _, msg := range msgs {
+ select {
+ case msgsch <- msg:
+ case <-ctx.Done():
+ err := ctx.Err()
+ if err != nil {
+ return fmt.Errorf("coninput context error: %w", err)
+ }
+ return err
+ }
+ }
+ }
+ }
+}
+
+func mouseEventButton(p, s coninput.ButtonState) (button MouseButton, action MouseAction) {
+ btn := p ^ s
+ action = MouseActionPress
+ if btn&s == 0 {
+ action = MouseActionRelease
+ }
+
+ if btn == 0 {
+ switch {
+ case s&coninput.FROM_LEFT_1ST_BUTTON_PRESSED > 0:
+ button = MouseButtonLeft
+ case s&coninput.FROM_LEFT_2ND_BUTTON_PRESSED > 0:
+ button = MouseButtonMiddle
+ case s&coninput.RIGHTMOST_BUTTON_PRESSED > 0:
+ button = MouseButtonRight
+ case s&coninput.FROM_LEFT_3RD_BUTTON_PRESSED > 0:
+ button = MouseButtonBackward
+ case s&coninput.FROM_LEFT_4TH_BUTTON_PRESSED > 0:
+ button = MouseButtonForward
+ }
+ return
+ }
+
+ switch {
+ case btn == coninput.FROM_LEFT_1ST_BUTTON_PRESSED: // left button
+ button = MouseButtonLeft
+ case btn == coninput.RIGHTMOST_BUTTON_PRESSED: // right button
+ button = MouseButtonRight
+ case btn == coninput.FROM_LEFT_2ND_BUTTON_PRESSED: // middle button
+ button = MouseButtonMiddle
+ case btn == coninput.FROM_LEFT_3RD_BUTTON_PRESSED: // unknown (possibly mouse backward)
+ button = MouseButtonBackward
+ case btn == coninput.FROM_LEFT_4TH_BUTTON_PRESSED: // unknown (possibly mouse forward)
+ button = MouseButtonForward
+ }
+
+ return button, action
+}
+
+func mouseEvent(p coninput.ButtonState, e coninput.MouseEventRecord) MouseMsg {
+ ev := MouseMsg{
+ X: int(e.MousePositon.X),
+ Y: int(e.MousePositon.Y),
+ Alt: e.ControlKeyState.Contains(coninput.LEFT_ALT_PRESSED | coninput.RIGHT_ALT_PRESSED),
+ Ctrl: e.ControlKeyState.Contains(coninput.LEFT_CTRL_PRESSED | coninput.RIGHT_CTRL_PRESSED),
+ Shift: e.ControlKeyState.Contains(coninput.SHIFT_PRESSED),
+ }
+ switch e.EventFlags {
+ case coninput.CLICK, coninput.DOUBLE_CLICK:
+ ev.Button, ev.Action = mouseEventButton(p, e.ButtonState)
+ if ev.Action == MouseActionRelease {
+ ev.Type = MouseRelease
+ }
+ switch ev.Button {
+ case MouseButtonLeft:
+ ev.Type = MouseLeft
+ case MouseButtonMiddle:
+ ev.Type = MouseMiddle
+ case MouseButtonRight:
+ ev.Type = MouseRight
+ case MouseButtonBackward:
+ ev.Type = MouseBackward
+ case MouseButtonForward:
+ ev.Type = MouseForward
+ }
+ case coninput.MOUSE_WHEELED:
+ if e.WheelDirection > 0 {
+ ev.Button = MouseButtonWheelUp
+ ev.Type = MouseWheelUp
+ } else {
+ ev.Button = MouseButtonWheelDown
+ ev.Type = MouseWheelDown
+ }
+ case coninput.MOUSE_HWHEELED:
+ if e.WheelDirection > 0 {
+ ev.Button = MouseButtonWheelRight
+ ev.Type = MouseWheelRight
+ } else {
+ ev.Button = MouseButtonWheelLeft
+ ev.Type = MouseWheelLeft
+ }
+ case coninput.MOUSE_MOVED:
+ ev.Button, _ = mouseEventButton(p, e.ButtonState)
+ ev.Action = MouseActionMotion
+ ev.Type = MouseMotion
+ }
+
+ return ev
+}
+
+func keyType(e coninput.KeyEventRecord) KeyType {
+ code := e.VirtualKeyCode
+
+ shiftPressed := e.ControlKeyState.Contains(coninput.SHIFT_PRESSED)
+ ctrlPressed := e.ControlKeyState.Contains(coninput.LEFT_CTRL_PRESSED | coninput.RIGHT_CTRL_PRESSED)
+
+ switch code {
+ case coninput.VK_RETURN:
+ return KeyEnter
+ case coninput.VK_BACK:
+ return KeyBackspace
+ case coninput.VK_TAB:
+ if shiftPressed {
+ return KeyShiftTab
+ }
+ return KeyTab
+ case coninput.VK_SPACE:
+ return KeyRunes // this could be KeySpace but on unix space also produces KeyRunes
+ case coninput.VK_ESCAPE:
+ return KeyEscape
+ case coninput.VK_UP:
+ switch {
+ case shiftPressed && ctrlPressed:
+ return KeyCtrlShiftUp
+ case shiftPressed:
+ return KeyShiftUp
+ case ctrlPressed:
+ return KeyCtrlUp
+ default:
+ return KeyUp
+ }
+ case coninput.VK_DOWN:
+ switch {
+ case shiftPressed && ctrlPressed:
+ return KeyCtrlShiftDown
+ case shiftPressed:
+ return KeyShiftDown
+ case ctrlPressed:
+ return KeyCtrlDown
+ default:
+ return KeyDown
+ }
+ case coninput.VK_RIGHT:
+ switch {
+ case shiftPressed && ctrlPressed:
+ return KeyCtrlShiftRight
+ case shiftPressed:
+ return KeyShiftRight
+ case ctrlPressed:
+ return KeyCtrlRight
+ default:
+ return KeyRight
+ }
+ case coninput.VK_LEFT:
+ switch {
+ case shiftPressed && ctrlPressed:
+ return KeyCtrlShiftLeft
+ case shiftPressed:
+ return KeyShiftLeft
+ case ctrlPressed:
+ return KeyCtrlLeft
+ default:
+ return KeyLeft
+ }
+ case coninput.VK_HOME:
+ switch {
+ case shiftPressed && ctrlPressed:
+ return KeyCtrlShiftHome
+ case shiftPressed:
+ return KeyShiftHome
+ case ctrlPressed:
+ return KeyCtrlHome
+ default:
+ return KeyHome
+ }
+ case coninput.VK_END:
+ switch {
+ case shiftPressed && ctrlPressed:
+ return KeyCtrlShiftEnd
+ case shiftPressed:
+ return KeyShiftEnd
+ case ctrlPressed:
+ return KeyCtrlEnd
+ default:
+ return KeyEnd
+ }
+ case coninput.VK_PRIOR:
+ return KeyPgUp
+ case coninput.VK_NEXT:
+ return KeyPgDown
+ case coninput.VK_DELETE:
+ return KeyDelete
+ default:
+ switch {
+ case e.ControlKeyState.Contains(coninput.LEFT_CTRL_PRESSED) && e.ControlKeyState.Contains(coninput.RIGHT_ALT_PRESSED):
+ // AltGr is pressed, then it's a rune.
+ fallthrough
+ case !e.ControlKeyState.Contains(coninput.LEFT_CTRL_PRESSED) && !e.ControlKeyState.Contains(coninput.RIGHT_CTRL_PRESSED):
+ return KeyRunes
+ }
+
+ switch e.Char {
+ case '@':
+ return KeyCtrlAt
+ case '\x01':
+ return KeyCtrlA
+ case '\x02':
+ return KeyCtrlB
+ case '\x03':
+ return KeyCtrlC
+ case '\x04':
+ return KeyCtrlD
+ case '\x05':
+ return KeyCtrlE
+ case '\x06':
+ return KeyCtrlF
+ case '\a':
+ return KeyCtrlG
+ case '\b':
+ return KeyCtrlH
+ case '\t':
+ return KeyCtrlI
+ case '\n':
+ return KeyCtrlJ
+ case '\v':
+ return KeyCtrlK
+ case '\f':
+ return KeyCtrlL
+ case '\r':
+ return KeyCtrlM
+ case '\x0e':
+ return KeyCtrlN
+ case '\x0f':
+ return KeyCtrlO
+ case '\x10':
+ return KeyCtrlP
+ case '\x11':
+ return KeyCtrlQ
+ case '\x12':
+ return KeyCtrlR
+ case '\x13':
+ return KeyCtrlS
+ case '\x14':
+ return KeyCtrlT
+ case '\x15':
+ return KeyCtrlU
+ case '\x16':
+ return KeyCtrlV
+ case '\x17':
+ return KeyCtrlW
+ case '\x18':
+ return KeyCtrlX
+ case '\x19':
+ return KeyCtrlY
+ case '\x1a':
+ return KeyCtrlZ
+ case '\x1b':
+ return KeyCtrlOpenBracket // KeyEscape
+ case '\x1c':
+ return KeyCtrlBackslash
+ case '\x1f':
+ return KeyCtrlUnderscore
+ }
+
+ switch code {
+ case coninput.VK_OEM_4:
+ return KeyCtrlOpenBracket
+ case coninput.VK_OEM_6:
+ return KeyCtrlCloseBracket
+ }
+
+ return KeyRunes
+ }
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/logging.go b/vendor/github.com/charmbracelet/bubbletea/logging.go
new file mode 100644
index 0000000..a531181
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/logging.go
@@ -0,0 +1,53 @@
+package tea
+
+import (
+ "fmt"
+ "io"
+ "log"
+ "os"
+ "unicode"
+)
+
+// LogToFile sets up default logging to log to a file. This is helpful as we
+// can't print to the terminal since our TUI is occupying it. If the file
+// doesn't exist it will be created.
+//
+// Don't forget to close the file when you're done with it.
+//
+// f, err := LogToFile("debug.log", "debug")
+// if err != nil {
+// fmt.Println("fatal:", err)
+// os.Exit(1)
+// }
+// defer f.Close()
+func LogToFile(path string, prefix string) (*os.File, error) {
+ return LogToFileWith(path, prefix, log.Default())
+}
+
+// LogOptionsSetter is an interface implemented by stdlib's log and charm's log
+// libraries.
+type LogOptionsSetter interface {
+ SetOutput(io.Writer)
+ SetPrefix(string)
+}
+
+// LogToFileWith does allows to call LogToFile with a custom LogOptionsSetter.
+func LogToFileWith(path string, prefix string, log LogOptionsSetter) (*os.File, error) {
+ f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0o600) //nolint:gomnd
+ if err != nil {
+ return nil, fmt.Errorf("error opening file for logging: %w", err)
+ }
+ log.SetOutput(f)
+
+ // Add a space after the prefix if a prefix is being specified and it
+ // doesn't already have a trailing space.
+ if len(prefix) > 0 {
+ finalChar := prefix[len(prefix)-1]
+ if !unicode.IsSpace(rune(finalChar)) {
+ prefix += " "
+ }
+ }
+ log.SetPrefix(prefix)
+
+ return f, nil
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/mouse.go b/vendor/github.com/charmbracelet/bubbletea/mouse.go
new file mode 100644
index 0000000..6ec51cc
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/mouse.go
@@ -0,0 +1,308 @@
+package tea
+
+import "strconv"
+
+// MouseMsg contains information about a mouse event and are sent to a programs
+// update function when mouse activity occurs. Note that the mouse must first
+// be enabled in order for the mouse events to be received.
+type MouseMsg MouseEvent
+
+// String returns a string representation of a mouse event.
+func (m MouseMsg) String() string {
+ return MouseEvent(m).String()
+}
+
+// MouseEvent represents a mouse event, which could be a click, a scroll wheel
+// movement, a cursor movement, or a combination.
+type MouseEvent struct {
+ X int
+ Y int
+ Shift bool
+ Alt bool
+ Ctrl bool
+ Action MouseAction
+ Button MouseButton
+
+ // Deprecated: Use MouseAction & MouseButton instead.
+ Type MouseEventType
+}
+
+// IsWheel returns true if the mouse event is a wheel event.
+func (m MouseEvent) IsWheel() bool {
+ return m.Button == MouseButtonWheelUp || m.Button == MouseButtonWheelDown ||
+ m.Button == MouseButtonWheelLeft || m.Button == MouseButtonWheelRight
+}
+
+// String returns a string representation of a mouse event.
+func (m MouseEvent) String() (s string) {
+ if m.Ctrl {
+ s += "ctrl+"
+ }
+ if m.Alt {
+ s += "alt+"
+ }
+ if m.Shift {
+ s += "shift+"
+ }
+
+ if m.Button == MouseButtonNone { //nolint:nestif
+ if m.Action == MouseActionMotion || m.Action == MouseActionRelease {
+ s += mouseActions[m.Action]
+ } else {
+ s += "unknown"
+ }
+ } else if m.IsWheel() {
+ s += mouseButtons[m.Button]
+ } else {
+ btn := mouseButtons[m.Button]
+ if btn != "" {
+ s += btn
+ }
+ act := mouseActions[m.Action]
+ if act != "" {
+ s += " " + act
+ }
+ }
+
+ return s
+}
+
+// MouseAction represents the action that occurred during a mouse event.
+type MouseAction int
+
+// Mouse event actions.
+const (
+ MouseActionPress MouseAction = iota
+ MouseActionRelease
+ MouseActionMotion
+)
+
+var mouseActions = map[MouseAction]string{
+ MouseActionPress: "press",
+ MouseActionRelease: "release",
+ MouseActionMotion: "motion",
+}
+
+// MouseButton represents the button that was pressed during a mouse event.
+type MouseButton int
+
+// Mouse event buttons
+//
+// This is based on X11 mouse button codes.
+//
+// 1 = left button
+// 2 = middle button (pressing the scroll wheel)
+// 3 = right button
+// 4 = turn scroll wheel up
+// 5 = turn scroll wheel down
+// 6 = push scroll wheel left
+// 7 = push scroll wheel right
+// 8 = 4th button (aka browser backward button)
+// 9 = 5th button (aka browser forward button)
+// 10
+// 11
+//
+// Other buttons are not supported.
+const (
+ MouseButtonNone MouseButton = iota
+ MouseButtonLeft
+ MouseButtonMiddle
+ MouseButtonRight
+ MouseButtonWheelUp
+ MouseButtonWheelDown
+ MouseButtonWheelLeft
+ MouseButtonWheelRight
+ MouseButtonBackward
+ MouseButtonForward
+ MouseButton10
+ MouseButton11
+)
+
+var mouseButtons = map[MouseButton]string{
+ MouseButtonNone: "none",
+ MouseButtonLeft: "left",
+ MouseButtonMiddle: "middle",
+ MouseButtonRight: "right",
+ MouseButtonWheelUp: "wheel up",
+ MouseButtonWheelDown: "wheel down",
+ MouseButtonWheelLeft: "wheel left",
+ MouseButtonWheelRight: "wheel right",
+ MouseButtonBackward: "backward",
+ MouseButtonForward: "forward",
+ MouseButton10: "button 10",
+ MouseButton11: "button 11",
+}
+
+// MouseEventType indicates the type of mouse event occurring.
+//
+// Deprecated: Use MouseAction & MouseButton instead.
+type MouseEventType int
+
+// Mouse event types.
+//
+// Deprecated: Use MouseAction & MouseButton instead.
+const (
+ MouseUnknown MouseEventType = iota
+ MouseLeft
+ MouseRight
+ MouseMiddle
+ MouseRelease // mouse button release (X10 only)
+ MouseWheelUp
+ MouseWheelDown
+ MouseWheelLeft
+ MouseWheelRight
+ MouseBackward
+ MouseForward
+ MouseMotion
+)
+
+// Parse SGR-encoded mouse events; SGR extended mouse events. SGR mouse events
+// look like:
+//
+// ESC [ < Cb ; Cx ; Cy (M or m)
+//
+// where:
+//
+// Cb is the encoded button code
+// Cx is the x-coordinate of the mouse
+// Cy is the y-coordinate of the mouse
+// M is for button press, m is for button release
+//
+// https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Extended-coordinates
+func parseSGRMouseEvent(buf []byte) MouseEvent {
+ str := string(buf[3:])
+ matches := mouseSGRRegex.FindStringSubmatch(str)
+ if len(matches) != 5 { //nolint:gomnd
+ // Unreachable, we already checked the regex in `detectOneMsg`.
+ panic("invalid mouse event")
+ }
+
+ b, _ := strconv.Atoi(matches[1])
+ px := matches[2]
+ py := matches[3]
+ release := matches[4] == "m"
+ m := parseMouseButton(b, true)
+
+ // Wheel buttons don't have release events
+ // Motion can be reported as a release event in some terminals (Windows Terminal)
+ if m.Action != MouseActionMotion && !m.IsWheel() && release {
+ m.Action = MouseActionRelease
+ m.Type = MouseRelease
+ }
+
+ x, _ := strconv.Atoi(px)
+ y, _ := strconv.Atoi(py)
+
+ // (1,1) is the upper left. We subtract 1 to normalize it to (0,0).
+ m.X = x - 1
+ m.Y = y - 1
+
+ return m
+}
+
+const x10MouseByteOffset = 32
+
+// Parse X10-encoded mouse events; the simplest kind. The last release of X10
+// was December 1986, by the way. The original X10 mouse protocol limits the Cx
+// and Cy coordinates to 223 (=255-032).
+//
+// X10 mouse events look like:
+//
+// ESC [M Cb Cx Cy
+//
+// See: http://www.xfree86.org/current/ctlseqs.html#Mouse%20Tracking
+func parseX10MouseEvent(buf []byte) MouseEvent {
+ v := buf[3:6]
+ m := parseMouseButton(int(v[0]), false)
+
+ // (1,1) is the upper left. We subtract 1 to normalize it to (0,0).
+ m.X = int(v[1]) - x10MouseByteOffset - 1
+ m.Y = int(v[2]) - x10MouseByteOffset - 1
+
+ return m
+}
+
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Extended-coordinates
+func parseMouseButton(b int, isSGR bool) MouseEvent {
+ var m MouseEvent
+ e := b
+ if !isSGR {
+ e -= x10MouseByteOffset
+ }
+
+ const (
+ bitShift = 0b0000_0100
+ bitAlt = 0b0000_1000
+ bitCtrl = 0b0001_0000
+ bitMotion = 0b0010_0000
+ bitWheel = 0b0100_0000
+ bitAdd = 0b1000_0000 // additional buttons 8-11
+
+ bitsMask = 0b0000_0011
+ )
+
+ if e&bitAdd != 0 {
+ m.Button = MouseButtonBackward + MouseButton(e&bitsMask)
+ } else if e&bitWheel != 0 {
+ m.Button = MouseButtonWheelUp + MouseButton(e&bitsMask)
+ } else {
+ m.Button = MouseButtonLeft + MouseButton(e&bitsMask)
+ // X10 reports a button release as 0b0000_0011 (3)
+ if e&bitsMask == bitsMask {
+ m.Action = MouseActionRelease
+ m.Button = MouseButtonNone
+ }
+ }
+
+ // Motion bit doesn't get reported for wheel events.
+ if e&bitMotion != 0 && !m.IsWheel() {
+ m.Action = MouseActionMotion
+ }
+
+ // Modifiers
+ m.Alt = e&bitAlt != 0
+ m.Ctrl = e&bitCtrl != 0
+ m.Shift = e&bitShift != 0
+
+ // backward compatibility
+ switch {
+ case m.Button == MouseButtonLeft && m.Action == MouseActionPress:
+ m.Type = MouseLeft
+ case m.Button == MouseButtonMiddle && m.Action == MouseActionPress:
+ m.Type = MouseMiddle
+ case m.Button == MouseButtonRight && m.Action == MouseActionPress:
+ m.Type = MouseRight
+ case m.Button == MouseButtonNone && m.Action == MouseActionRelease:
+ m.Type = MouseRelease
+ case m.Button == MouseButtonWheelUp && m.Action == MouseActionPress:
+ m.Type = MouseWheelUp
+ case m.Button == MouseButtonWheelDown && m.Action == MouseActionPress:
+ m.Type = MouseWheelDown
+ case m.Button == MouseButtonWheelLeft && m.Action == MouseActionPress:
+ m.Type = MouseWheelLeft
+ case m.Button == MouseButtonWheelRight && m.Action == MouseActionPress:
+ m.Type = MouseWheelRight
+ case m.Button == MouseButtonBackward && m.Action == MouseActionPress:
+ m.Type = MouseBackward
+ case m.Button == MouseButtonForward && m.Action == MouseActionPress:
+ m.Type = MouseForward
+ case m.Action == MouseActionMotion:
+ m.Type = MouseMotion
+ switch m.Button { //nolint:exhaustive
+ case MouseButtonLeft:
+ m.Type = MouseLeft
+ case MouseButtonMiddle:
+ m.Type = MouseMiddle
+ case MouseButtonRight:
+ m.Type = MouseRight
+ case MouseButtonBackward:
+ m.Type = MouseBackward
+ case MouseButtonForward:
+ m.Type = MouseForward
+ }
+ default:
+ m.Type = MouseUnknown
+ }
+
+ return m
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/nil_renderer.go b/vendor/github.com/charmbracelet/bubbletea/nil_renderer.go
new file mode 100644
index 0000000..0bc4a17
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/nil_renderer.go
@@ -0,0 +1,28 @@
+package tea
+
+type nilRenderer struct{}
+
+func (n nilRenderer) start() {}
+func (n nilRenderer) stop() {}
+func (n nilRenderer) kill() {}
+func (n nilRenderer) write(_ string) {}
+func (n nilRenderer) repaint() {}
+func (n nilRenderer) clearScreen() {}
+func (n nilRenderer) altScreen() bool { return false }
+func (n nilRenderer) enterAltScreen() {}
+func (n nilRenderer) exitAltScreen() {}
+func (n nilRenderer) showCursor() {}
+func (n nilRenderer) hideCursor() {}
+func (n nilRenderer) enableMouseCellMotion() {}
+func (n nilRenderer) disableMouseCellMotion() {}
+func (n nilRenderer) enableMouseAllMotion() {}
+func (n nilRenderer) disableMouseAllMotion() {}
+func (n nilRenderer) enableBracketedPaste() {}
+func (n nilRenderer) disableBracketedPaste() {}
+func (n nilRenderer) enableMouseSGRMode() {}
+func (n nilRenderer) disableMouseSGRMode() {}
+func (n nilRenderer) bracketedPasteActive() bool { return false }
+func (n nilRenderer) setWindowTitle(_ string) {}
+func (n nilRenderer) reportFocus() bool { return false }
+func (n nilRenderer) enableReportFocus() {}
+func (n nilRenderer) disableReportFocus() {}
diff --git a/vendor/github.com/charmbracelet/bubbletea/options.go b/vendor/github.com/charmbracelet/bubbletea/options.go
new file mode 100644
index 0000000..e1f70ef
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/options.go
@@ -0,0 +1,269 @@
+package tea
+
+import (
+ "context"
+ "io"
+ "sync/atomic"
+)
+
+// ProgramOption is used to set options when initializing a Program. Program can
+// accept a variable number of options.
+//
+// Example usage:
+//
+// p := NewProgram(model, WithInput(someInput), WithOutput(someOutput))
+type ProgramOption func(*Program)
+
+// WithContext lets you specify a context in which to run the Program. This is
+// useful if you want to cancel the execution from outside. When a Program gets
+// cancelled it will exit with an error ErrProgramKilled.
+func WithContext(ctx context.Context) ProgramOption {
+ return func(p *Program) {
+ p.ctx = ctx
+ }
+}
+
+// WithOutput sets the output which, by default, is stdout. In most cases you
+// won't need to use this.
+func WithOutput(output io.Writer) ProgramOption {
+ return func(p *Program) {
+ p.output = output
+ }
+}
+
+// WithInput sets the input which, by default, is stdin. In most cases you
+// won't need to use this. To disable input entirely pass nil.
+//
+// p := NewProgram(model, WithInput(nil))
+func WithInput(input io.Reader) ProgramOption {
+ return func(p *Program) {
+ p.input = input
+ p.inputType = customInput
+ }
+}
+
+// WithInputTTY opens a new TTY for input (or console input device on Windows).
+func WithInputTTY() ProgramOption {
+ return func(p *Program) {
+ p.inputType = ttyInput
+ }
+}
+
+// WithEnvironment sets the environment variables that the program will use.
+// This useful when the program is running in a remote session (e.g. SSH) and
+// you want to pass the environment variables from the remote session to the
+// program.
+//
+// Example:
+//
+// var sess ssh.Session // ssh.Session is a type from the github.com/charmbracelet/ssh package
+// pty, _, _ := sess.Pty()
+// environ := append(sess.Environ(), "TERM="+pty.Term)
+// p := tea.NewProgram(model, tea.WithEnvironment(environ)
+func WithEnvironment(env []string) ProgramOption {
+ return func(p *Program) {
+ p.environ = env
+ }
+}
+
+// WithoutSignalHandler disables the signal handler that Bubble Tea sets up for
+// Programs. This is useful if you want to handle signals yourself.
+func WithoutSignalHandler() ProgramOption {
+ return func(p *Program) {
+ p.startupOptions |= withoutSignalHandler
+ }
+}
+
+// WithoutCatchPanics disables the panic catching that Bubble Tea does by
+// default. If panic catching is disabled the terminal will be in a fairly
+// unusable state after a panic because Bubble Tea will not perform its usual
+// cleanup on exit.
+func WithoutCatchPanics() ProgramOption {
+ return func(p *Program) {
+ p.startupOptions |= withoutCatchPanics
+ }
+}
+
+// WithoutSignals will ignore OS signals.
+// This is mainly useful for testing.
+func WithoutSignals() ProgramOption {
+ return func(p *Program) {
+ atomic.StoreUint32(&p.ignoreSignals, 1)
+ }
+}
+
+// WithAltScreen starts the program with the alternate screen buffer enabled
+// (i.e. the program starts in full window mode). Note that the altscreen will
+// be automatically exited when the program quits.
+//
+// Example:
+//
+// p := tea.NewProgram(Model{}, tea.WithAltScreen())
+// if _, err := p.Run(); err != nil {
+// fmt.Println("Error running program:", err)
+// os.Exit(1)
+// }
+//
+// To enter the altscreen once the program has already started running use the
+// EnterAltScreen command.
+//
+// Deprecated: use the [EnterAltScreen] [Cmd] in your [Model.Init] instead.
+func WithAltScreen() ProgramOption {
+ return func(p *Program) {
+ p.startupOptions |= withAltScreen
+ }
+}
+
+// WithoutBracketedPaste starts the program with bracketed paste disabled.
+//
+// Deprecated: use the [EnableBracketedPaste] [Cmd] in your [Model.Init]
+// instead.
+func WithoutBracketedPaste() ProgramOption {
+ return func(p *Program) {
+ p.startupOptions |= withoutBracketedPaste
+ }
+}
+
+// WithMouseCellMotion starts the program with the mouse enabled in "cell
+// motion" mode.
+//
+// Cell motion mode enables mouse click, release, and wheel events. Mouse
+// movement events are also captured if a mouse button is pressed (i.e., drag
+// events). Cell motion mode is better supported than all motion mode.
+//
+// This will try to enable the mouse in extended mode (SGR), if that is not
+// supported by the terminal it will fall back to normal mode (X10).
+//
+// To enable mouse cell motion once the program has already started running use
+// the EnableMouseCellMotion command. To disable the mouse when the program is
+// running use the DisableMouse command.
+//
+// The mouse will be automatically disabled when the program exits.
+//
+// Deprecated: use the [EnableMouseCellMotion] [Cmd] in your [Model.Init]
+// instead.
+func WithMouseCellMotion() ProgramOption {
+ return func(p *Program) {
+ p.startupOptions |= withMouseCellMotion // set
+ p.startupOptions &^= withMouseAllMotion // clear
+ }
+}
+
+// WithMouseAllMotion starts the program with the mouse enabled in "all motion"
+// mode.
+//
+// EnableMouseAllMotion is a special command that enables mouse click, release,
+// wheel, and motion events, which are delivered regardless of whether a mouse
+// button is pressed, effectively enabling support for hover interactions.
+//
+// This will try to enable the mouse in extended mode (SGR), if that is not
+// supported by the terminal it will fall back to normal mode (X10).
+//
+// Many modern terminals support this, but not all. If in doubt, use
+// EnableMouseCellMotion instead.
+//
+// To enable the mouse once the program has already started running use the
+// EnableMouseAllMotion command. To disable the mouse when the program is
+// running use the DisableMouse command.
+//
+// The mouse will be automatically disabled when the program exits.
+//
+// Deprecated: use the [EnableMouseAllMotion] [Cmd] in your [Model.Init]
+// instead.
+func WithMouseAllMotion() ProgramOption {
+ return func(p *Program) {
+ p.startupOptions |= withMouseAllMotion // set
+ p.startupOptions &^= withMouseCellMotion // clear
+ }
+}
+
+// WithoutRenderer disables the renderer. When this is set output and log
+// statements will be plainly sent to stdout (or another output if one is set)
+// without any rendering and redrawing logic. In other words, printing and
+// logging will behave the same way it would in a non-TUI commandline tool.
+// This can be useful if you want to use the Bubble Tea framework for a non-TUI
+// application, or to provide an additional non-TUI mode to your Bubble Tea
+// programs. For example, your program could behave like a daemon if output is
+// not a TTY.
+func WithoutRenderer() ProgramOption {
+ return func(p *Program) {
+ p.renderer = &nilRenderer{}
+ }
+}
+
+// WithANSICompressor removes redundant ANSI sequences to produce potentially
+// smaller output, at the cost of some processing overhead.
+//
+// This feature is provisional, and may be changed or removed in a future version
+// of this package.
+//
+// Deprecated: this incurs a noticeable performance hit. A future release will
+// optimize ANSI automatically without the performance penalty.
+//
+// Deprecated: this will be removed in a future release. This ANSI compressor
+// has major performance implications and we don't recommend using it. In v2,
+// rendering bandwidth will be decreased significantly.
+func WithANSICompressor() ProgramOption {
+ return func(p *Program) {
+ p.startupOptions |= withANSICompressor
+ }
+}
+
+// WithFilter supplies an event filter that will be invoked before Bubble Tea
+// processes a tea.Msg. The event filter can return any tea.Msg which will then
+// get handled by Bubble Tea instead of the original event. If the event filter
+// returns nil, the event will be ignored and Bubble Tea will not process it.
+//
+// As an example, this could be used to prevent a program from shutting down if
+// there are unsaved changes.
+//
+// Example:
+//
+// func filter(m tea.Model, msg tea.Msg) tea.Msg {
+// if _, ok := msg.(tea.QuitMsg); !ok {
+// return msg
+// }
+//
+// model := m.(myModel)
+// if model.hasChanges {
+// return nil
+// }
+//
+// return msg
+// }
+//
+// p := tea.NewProgram(Model{}, tea.WithFilter(filter));
+//
+// if _,err := p.Run(); err != nil {
+// fmt.Println("Error running program:", err)
+// os.Exit(1)
+// }
+func WithFilter(filter func(Model, Msg) Msg) ProgramOption {
+ return func(p *Program) {
+ p.filter = filter
+ }
+}
+
+// WithFPS sets a custom maximum FPS at which the renderer should run. If
+// less than 1, the default value of 60 will be used. If over 120, the FPS
+// will be capped at 120.
+func WithFPS(fps int) ProgramOption {
+ return func(p *Program) {
+ p.fps = fps
+ }
+}
+
+// WithReportFocus enables reporting when the terminal gains and loses
+// focus. When this is enabled [FocusMsg] and [BlurMsg] messages will be sent
+// to your Update method.
+//
+// Note that while most terminals and multiplexers support focus reporting,
+// some do not. Also note that tmux needs to be configured to report focus
+// events.
+//
+// Deprecated: use the [EnableReportFocus] [Cmd] in your [Model.Init] instead.
+func WithReportFocus() ProgramOption {
+ return func(p *Program) {
+ p.startupOptions |= withReportFocus
+ }
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/renderer.go b/vendor/github.com/charmbracelet/bubbletea/renderer.go
new file mode 100644
index 0000000..9eb7943
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/renderer.go
@@ -0,0 +1,85 @@
+package tea
+
+// renderer is the interface for Bubble Tea renderers.
+type renderer interface {
+ // Start the renderer.
+ start()
+
+ // Stop the renderer, but render the final frame in the buffer, if any.
+ stop()
+
+ // Stop the renderer without doing any final rendering.
+ kill()
+
+ // Write a frame to the renderer. The renderer can write this data to
+ // output at its discretion.
+ write(string)
+
+ // Request a full re-render. Note that this will not trigger a render
+ // immediately. Rather, this method causes the next render to be a full
+ // repaint. Because of this, it's safe to call this method multiple times
+ // in succession.
+ repaint()
+
+ // Clears the terminal.
+ clearScreen()
+
+ // Whether or not the alternate screen buffer is enabled.
+ altScreen() bool
+ // Enable the alternate screen buffer.
+ enterAltScreen()
+ // Disable the alternate screen buffer.
+ exitAltScreen()
+
+ // Show the cursor.
+ showCursor()
+ // Hide the cursor.
+ hideCursor()
+
+ // enableMouseCellMotion enables mouse click, release, wheel and motion
+ // events if a mouse button is pressed (i.e., drag events).
+ enableMouseCellMotion()
+
+ // disableMouseCellMotion disables Mouse Cell Motion tracking.
+ disableMouseCellMotion()
+
+ // enableMouseAllMotion enables mouse click, release, wheel and motion
+ // events, regardless of whether a mouse button is pressed. Many modern
+ // terminals support this, but not all.
+ enableMouseAllMotion()
+
+ // disableMouseAllMotion disables All Motion mouse tracking.
+ disableMouseAllMotion()
+
+ // enableMouseSGRMode enables mouse extended mode (SGR).
+ enableMouseSGRMode()
+
+ // disableMouseSGRMode disables mouse extended mode (SGR).
+ disableMouseSGRMode()
+
+ // enableBracketedPaste enables bracketed paste, where characters
+ // inside the input are not interpreted when pasted as a whole.
+ enableBracketedPaste()
+
+ // disableBracketedPaste disables bracketed paste.
+ disableBracketedPaste()
+
+ // bracketedPasteActive reports whether bracketed paste mode is
+ // currently enabled.
+ bracketedPasteActive() bool
+
+ // setWindowTitle sets the terminal window title.
+ setWindowTitle(string)
+
+ // reportFocus returns whether reporting focus events is enabled.
+ reportFocus() bool
+
+ // enableReportFocus reports focus events to the program.
+ enableReportFocus()
+
+ // disableReportFocus stops reporting focus events to the program.
+ disableReportFocus()
+}
+
+// repaintMsg forces a full repaint.
+type repaintMsg struct{}
diff --git a/vendor/github.com/charmbracelet/bubbletea/screen.go b/vendor/github.com/charmbracelet/bubbletea/screen.go
new file mode 100644
index 0000000..daf3360
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/screen.go
@@ -0,0 +1,246 @@
+package tea
+
+// WindowSizeMsg is used to report the terminal size. It's sent to Update once
+// initially and then on every terminal resize. Note that Windows does not
+// have support for reporting when resizes occur as it does not support the
+// SIGWINCH signal.
+type WindowSizeMsg struct {
+ Width int
+ Height int
+}
+
+// ClearScreen is a special command that tells the program to clear the screen
+// before the next update. This can be used to move the cursor to the top left
+// of the screen and clear visual clutter when the alt screen is not in use.
+//
+// Note that it should never be necessary to call ClearScreen() for regular
+// redraws.
+func ClearScreen() Msg {
+ return clearScreenMsg{}
+}
+
+// clearScreenMsg is an internal message that signals to clear the screen.
+// You can send a clearScreenMsg with ClearScreen.
+type clearScreenMsg struct{}
+
+// EnterAltScreen is a special command that tells the Bubble Tea program to
+// enter the alternate screen buffer (i.e. the full terminal window). The
+// altscreen will be automatically exited when the program quits. To manually
+// exit the altscreen while the program is running, use [ExitAltScreen].
+func EnterAltScreen() Msg {
+ return enterAltScreenMsg{}
+}
+
+// enterAltScreenMsg in an internal message signals that the program should
+// enter alternate screen buffer. You can send a enterAltScreenMsg with
+// EnterAltScreen.
+type enterAltScreenMsg struct{}
+
+// ExitAltScreen is a special command that tells the Bubble Tea program to exit
+// the alternate screen buffer. This command should be used to exit the
+// alternate screen buffer while the program is running.
+//
+// Note that the alternate screen buffer will be automatically exited when the
+// program quits.
+func ExitAltScreen() Msg {
+ return exitAltScreenMsg{}
+}
+
+// exitAltScreenMsg in an internal message signals that the program should exit
+// alternate screen buffer. You can send a exitAltScreenMsg with
+// [ExitAltScreen].
+type exitAltScreenMsg struct{}
+
+// EnableMouseCellMotion is a special command that enables mouse click,
+// release, and wheel events. Mouse movement events are also captured if
+// a mouse button is pressed (i.e., drag events).
+func EnableMouseCellMotion() Msg {
+ return enableMouseCellMotionMsg{}
+}
+
+// enableMouseCellMotionMsg is a special command that signals to start
+// listening for "cell motion" type mouse events (ESC[?1002l). To send an
+// enableMouseCellMotionMsg, use the EnableMouseCellMotion command.
+type enableMouseCellMotionMsg struct{}
+
+// EnableMouseAllMotion is a special command that enables mouse click, release,
+// wheel, and motion events, which are delivered regardless of whether a mouse
+// button is pressed, effectively enabling support for hover interactions.
+//
+// Many modern terminals support this, but not all. If in doubt, use
+// [EnableMouseCellMotion] instead.
+func EnableMouseAllMotion() Msg {
+ return enableMouseAllMotionMsg{}
+}
+
+// enableMouseAllMotionMsg is a special command that signals to start listening
+// for "all motion" type mouse events (ESC[?1003l). To send an
+// enableMouseAllMotionMsg, use the EnableMouseAllMotion command.
+type enableMouseAllMotionMsg struct{}
+
+// DisableMouse is a special command that stops listening for mouse events.
+func DisableMouse() Msg {
+ return disableMouseMsg{}
+}
+
+// disableMouseMsg is an internal message that signals to stop listening
+// for mouse events. To send a disableMouseMsg, use the DisableMouse command.
+type disableMouseMsg struct{}
+
+// HideCursor is a special command for manually instructing Bubble Tea to hide
+// the cursor. In some rare cases, certain operations will cause the terminal
+// to show the cursor, which is normally hidden for the duration of a Bubble
+// Tea program's lifetime. You will most likely not need to use this command.
+func HideCursor() Msg {
+ return hideCursorMsg{}
+}
+
+// hideCursorMsg is an internal command used to hide the cursor. You can send
+// this message with HideCursor.
+type hideCursorMsg struct{}
+
+// ShowCursor is a special command for manually instructing Bubble Tea to show
+// the cursor.
+//
+// Deprecated: this will be removed in a future release. In v2, the cursor will
+// can be manged via a dedicated API.
+func ShowCursor() Msg {
+ return showCursorMsg{}
+}
+
+// showCursorMsg is an internal command used to show the cursor. You can send
+// this message with ShowCursor.
+type showCursorMsg struct{}
+
+// EnableBracketedPaste is a special command that tells the Bubble Tea program
+// to accept bracketed paste input. To disable bracketed paste, use
+// [DisableBracketedPaste].
+//
+// Also note that bracketed paste will be automatically disabled when the
+// program quits.
+func EnableBracketedPaste() Msg {
+ return enableBracketedPasteMsg{}
+}
+
+// enableBracketedPasteMsg in an internal message signals that
+// bracketed paste should be enabled. You can send an
+// enableBracketedPasteMsg with EnableBracketedPaste.
+type enableBracketedPasteMsg struct{}
+
+// DisableBracketedPaste is a special command that tells the Bubble Tea program
+// to accept bracketed paste input. To enable bracketed paste, use
+// [EnableBracketedPaste].
+//
+// Also note that bracketed paste will be automatically disabled when the
+// program quits.
+func DisableBracketedPaste() Msg {
+ return disableBracketedPasteMsg{}
+}
+
+// disableBracketedPasteMsg in an internal message signals that bracketed paste
+// should be disabled. You can send an disableBracketedPasteMsg with
+// DisableBracketedPaste.
+type disableBracketedPasteMsg struct{}
+
+// enableReportFocusMsg is an internal message that signals to enable focus
+// reporting. You can send an enableReportFocusMsg with EnableReportFocus.
+type enableReportFocusMsg struct{}
+
+// EnableReportFocus is a special command that tells the Bubble Tea program to
+// report focus events to the program.
+func EnableReportFocus() Msg {
+ return enableReportFocusMsg{}
+}
+
+// disableReportFocusMsg is an internal message that signals to disable focus
+// reporting. You can send an disableReportFocusMsg with DisableReportFocus.
+type disableReportFocusMsg struct{}
+
+// DisableReportFocus is a special command that tells the Bubble Tea program to
+// stop reporting focus events to the program.
+func DisableReportFocus() Msg {
+ return disableReportFocusMsg{}
+}
+
+// EnterAltScreen enters the alternate screen buffer, which consumes the entire
+// terminal window. ExitAltScreen will return the terminal to its former state.
+//
+// Deprecated: Use the [EnterAltScreen] [Cmd] instead.
+func (p *Program) EnterAltScreen() {
+ if p.renderer != nil {
+ p.renderer.enterAltScreen()
+ } else {
+ p.startupOptions |= withAltScreen
+ }
+}
+
+// ExitAltScreen exits the alternate screen buffer.
+//
+// Deprecated: The altscreen will exited automatically when the program exits.
+func (p *Program) ExitAltScreen() {
+ if p.renderer != nil {
+ p.renderer.exitAltScreen()
+ } else {
+ p.startupOptions &^= withAltScreen
+ }
+}
+
+// EnableMouseCellMotion enables mouse click, release, wheel and motion events
+// if a mouse button is pressed (i.e., drag events).
+//
+// Deprecated: Use the [EnableMouseCellMotion] [Cmd] instead.
+func (p *Program) EnableMouseCellMotion() {
+ if p.renderer != nil {
+ p.renderer.enableMouseCellMotion()
+ } else {
+ p.startupOptions |= withMouseCellMotion
+ }
+}
+
+// DisableMouseCellMotion disables Mouse Cell Motion tracking. This will be
+// called automatically when exiting a Bubble Tea program.
+//
+// Deprecated: The mouse will automatically be disabled when the program exits.
+func (p *Program) DisableMouseCellMotion() {
+ if p.renderer != nil {
+ p.renderer.disableMouseCellMotion()
+ } else {
+ p.startupOptions &^= withMouseCellMotion
+ }
+}
+
+// EnableMouseAllMotion enables mouse click, release, wheel and motion events,
+// regardless of whether a mouse button is pressed. Many modern terminals
+// support this, but not all.
+//
+// Deprecated: Use the [EnableMouseAllMotion] [Cmd] instead.
+func (p *Program) EnableMouseAllMotion() {
+ if p.renderer != nil {
+ p.renderer.enableMouseAllMotion()
+ } else {
+ p.startupOptions |= withMouseAllMotion
+ }
+}
+
+// DisableMouseAllMotion disables All Motion mouse tracking. This will be
+// called automatically when exiting a Bubble Tea program.
+//
+// Deprecated: The mouse will automatically be disabled when the program exits.
+func (p *Program) DisableMouseAllMotion() {
+ if p.renderer != nil {
+ p.renderer.disableMouseAllMotion()
+ } else {
+ p.startupOptions &^= withMouseAllMotion
+ }
+}
+
+// SetWindowTitle sets the terminal window title.
+//
+// Deprecated: Use the SetWindowTitle command instead.
+func (p *Program) SetWindowTitle(title string) {
+ if p.renderer != nil {
+ p.renderer.setWindowTitle(title)
+ } else {
+ p.startupTitle = title
+ }
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/signals_unix.go b/vendor/github.com/charmbracelet/bubbletea/signals_unix.go
new file mode 100644
index 0000000..4095403
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/signals_unix.go
@@ -0,0 +1,33 @@
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || aix || zos
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris aix zos
+
+package tea
+
+import (
+ "os"
+ "os/signal"
+ "syscall"
+)
+
+// listenForResize sends messages (or errors) when the terminal resizes.
+// Argument output should be the file descriptor for the terminal; usually
+// os.Stdout.
+func (p *Program) listenForResize(done chan struct{}) {
+ sig := make(chan os.Signal, 1)
+ signal.Notify(sig, syscall.SIGWINCH)
+
+ defer func() {
+ signal.Stop(sig)
+ close(done)
+ }()
+
+ for {
+ select {
+ case <-p.ctx.Done():
+ return
+ case <-sig:
+ }
+
+ p.checkResize()
+ }
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/signals_windows.go b/vendor/github.com/charmbracelet/bubbletea/signals_windows.go
new file mode 100644
index 0000000..2fc6f8a
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/signals_windows.go
@@ -0,0 +1,10 @@
+//go:build windows
+// +build windows
+
+package tea
+
+// listenForResize is not available on windows because windows does not
+// implement syscall.SIGWINCH.
+func (p *Program) listenForResize(done chan struct{}) {
+ close(done)
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/standard_renderer.go b/vendor/github.com/charmbracelet/bubbletea/standard_renderer.go
new file mode 100644
index 0000000..45e8c82
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/standard_renderer.go
@@ -0,0 +1,786 @@
+package tea
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/charmbracelet/x/ansi"
+ "github.com/muesli/ansi/compressor"
+)
+
+const (
+ // defaultFramerate specifies the maximum interval at which we should
+ // update the view.
+ defaultFPS = 60
+ maxFPS = 120
+)
+
+// standardRenderer is a framerate-based terminal renderer, updating the view
+// at a given framerate to avoid overloading the terminal emulator.
+//
+// In cases where very high performance is needed the renderer can be told
+// to exclude ranges of lines, allowing them to be written to directly.
+type standardRenderer struct {
+ mtx *sync.Mutex
+ out io.Writer
+
+ buf bytes.Buffer
+ queuedMessageLines []string
+ framerate time.Duration
+ ticker *time.Ticker
+ done chan struct{}
+ lastRender string
+ lastRenderedLines []string
+ linesRendered int
+ altLinesRendered int
+ useANSICompressor bool
+ once sync.Once
+
+ // cursor visibility state
+ cursorHidden bool
+
+ // essentially whether or not we're using the full size of the terminal
+ altScreenActive bool
+
+ // whether or not we're currently using bracketed paste
+ bpActive bool
+
+ // reportingFocus whether reporting focus events is enabled
+ reportingFocus bool
+
+ // renderer dimensions; usually the size of the window
+ width int
+ height int
+
+ // lines explicitly set not to render
+ ignoreLines map[int]struct{}
+}
+
+// newRenderer creates a new renderer. Normally you'll want to initialize it
+// with os.Stdout as the first argument.
+func newRenderer(out io.Writer, useANSICompressor bool, fps int) renderer {
+ if fps < 1 {
+ fps = defaultFPS
+ } else if fps > maxFPS {
+ fps = maxFPS
+ }
+ r := &standardRenderer{
+ out: out,
+ mtx: &sync.Mutex{},
+ done: make(chan struct{}),
+ framerate: time.Second / time.Duration(fps),
+ useANSICompressor: useANSICompressor,
+ queuedMessageLines: []string{},
+ }
+ if r.useANSICompressor {
+ r.out = &compressor.Writer{Forward: out}
+ }
+ return r
+}
+
+// start starts the renderer.
+func (r *standardRenderer) start() {
+ if r.ticker == nil {
+ r.ticker = time.NewTicker(r.framerate)
+ } else {
+ // If the ticker already exists, it has been stopped and we need to
+ // reset it.
+ r.ticker.Reset(r.framerate)
+ }
+
+ // Since the renderer can be restarted after a stop, we need to reset
+ // the done channel and its corresponding sync.Once.
+ r.once = sync.Once{}
+
+ go r.listen()
+}
+
+// stop permanently halts the renderer, rendering the final frame.
+func (r *standardRenderer) stop() {
+ // Stop the renderer before acquiring the mutex to avoid a deadlock.
+ r.once.Do(func() {
+ r.done <- struct{}{}
+ })
+
+ // flush locks the mutex
+ r.flush()
+
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.execute(ansi.EraseEntireLine)
+ // Move the cursor back to the beginning of the line
+ r.execute("\r")
+
+ if r.useANSICompressor {
+ if w, ok := r.out.(io.WriteCloser); ok {
+ _ = w.Close()
+ }
+ }
+}
+
+// execute writes a sequence to the terminal.
+func (r *standardRenderer) execute(seq string) {
+ _, _ = io.WriteString(r.out, seq)
+}
+
+// kill halts the renderer. The final frame will not be rendered.
+func (r *standardRenderer) kill() {
+ // Stop the renderer before acquiring the mutex to avoid a deadlock.
+ r.once.Do(func() {
+ r.done <- struct{}{}
+ })
+
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.execute(ansi.EraseEntireLine)
+ // Move the cursor back to the beginning of the line
+ r.execute("\r")
+}
+
+// listen waits for ticks on the ticker, or a signal to stop the renderer.
+func (r *standardRenderer) listen() {
+ for {
+ select {
+ case <-r.done:
+ r.ticker.Stop()
+ return
+
+ case <-r.ticker.C:
+ r.flush()
+ }
+ }
+}
+
+// flush renders the buffer.
+func (r *standardRenderer) flush() {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ if r.buf.Len() == 0 || r.buf.String() == r.lastRender {
+ // Nothing to do.
+ return
+ }
+
+ // Output buffer.
+ buf := &bytes.Buffer{}
+
+ // Moving to the beginning of the section, that we rendered.
+ if r.altScreenActive {
+ buf.WriteString(ansi.CursorHomePosition)
+ } else if r.linesRendered > 1 {
+ buf.WriteString(ansi.CursorUp(r.linesRendered - 1))
+ }
+
+ newLines := strings.Split(r.buf.String(), "\n")
+
+ // If we know the output's height, we can use it to determine how many
+ // lines we can render. We drop lines from the top of the render buffer if
+ // necessary, as we can't navigate the cursor into the terminal's scrollback
+ // buffer.
+ if r.height > 0 && len(newLines) > r.height {
+ newLines = newLines[len(newLines)-r.height:]
+ }
+
+ flushQueuedMessages := len(r.queuedMessageLines) > 0 && !r.altScreenActive
+
+ if flushQueuedMessages {
+ // Dump the lines we've queued up for printing.
+ for _, line := range r.queuedMessageLines {
+ if ansi.StringWidth(line) < r.width {
+ // We only erase the rest of the line when the line is shorter than
+ // the width of the terminal. When the cursor reaches the end of
+ // the line, any escape sequences that follow will only affect the
+ // last cell of the line.
+
+ // Removing previously rendered content at the end of line.
+ line = line + ansi.EraseLineRight
+ }
+
+ _, _ = buf.WriteString(line)
+ _, _ = buf.WriteString("\r\n")
+ }
+ // Clear the queued message lines.
+ r.queuedMessageLines = []string{}
+ }
+
+ // Paint new lines.
+ for i := 0; i < len(newLines); i++ {
+ canSkip := !flushQueuedMessages && // Queuing messages triggers repaint -> we don't have access to previous frame content.
+ len(r.lastRenderedLines) > i && r.lastRenderedLines[i] == newLines[i] // Previously rendered line is the same.
+
+ if _, ignore := r.ignoreLines[i]; ignore || canSkip {
+ // Unless this is the last line, move the cursor down.
+ if i < len(newLines)-1 {
+ buf.WriteByte('\n')
+ }
+ continue
+ }
+
+ if i == 0 && r.lastRender == "" {
+ // On first render, reset the cursor to the start of the line
+ // before writing anything.
+ buf.WriteByte('\r')
+ }
+
+ line := newLines[i]
+
+ // Truncate lines wider than the width of the window to avoid
+ // wrapping, which will mess up rendering. If we don't have the
+ // width of the window this will be ignored.
+ //
+ // Note that on Windows we only get the width of the window on
+ // program initialization, so after a resize this won't perform
+ // correctly (signal SIGWINCH is not supported on Windows).
+ if r.width > 0 {
+ line = ansi.Truncate(line, r.width, "")
+ }
+
+ if ansi.StringWidth(line) < r.width {
+ // We only erase the rest of the line when the line is shorter than
+ // the width of the terminal. When the cursor reaches the end of
+ // the line, any escape sequences that follow will only affect the
+ // last cell of the line.
+
+ // Removing previously rendered content at the end of line.
+ line = line + ansi.EraseLineRight
+ }
+
+ _, _ = buf.WriteString(line)
+
+ if i < len(newLines)-1 {
+ _, _ = buf.WriteString("\r\n")
+ }
+ }
+
+ // Clearing left over content from last render.
+ if r.lastLinesRendered() > len(newLines) {
+ buf.WriteString(ansi.EraseScreenBelow)
+ }
+
+ if r.altScreenActive {
+ r.altLinesRendered = len(newLines)
+ } else {
+ r.linesRendered = len(newLines)
+ }
+
+ // Make sure the cursor is at the start of the last line to keep rendering
+ // behavior consistent.
+ if r.altScreenActive {
+ // This case fixes a bug in macOS terminal. In other terminals the
+ // other case seems to do the job regardless of whether or not we're
+ // using the full terminal window.
+ buf.WriteString(ansi.CursorPosition(0, len(newLines)))
+ } else {
+ buf.WriteString(ansi.CursorBackward(r.width))
+ }
+
+ _, _ = r.out.Write(buf.Bytes())
+ r.lastRender = r.buf.String()
+
+ // Save previously rendered lines for comparison in the next render. If we
+ // don't do this, we can't skip rendering lines that haven't changed.
+ // See https://github.com/charmbracelet/bubbletea/pull/1233
+ r.lastRenderedLines = newLines
+ r.buf.Reset()
+}
+
+// lastLinesRendered returns the number of lines rendered lastly.
+func (r *standardRenderer) lastLinesRendered() int {
+ if r.altScreenActive {
+ return r.altLinesRendered
+ }
+ return r.linesRendered
+}
+
+// write writes to the internal buffer. The buffer will be outputted via the
+// ticker which calls flush().
+func (r *standardRenderer) write(s string) {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+ r.buf.Reset()
+
+ // If an empty string was passed we should clear existing output and
+ // rendering nothing. Rather than introduce additional state to manage
+ // this, we render a single space as a simple (albeit less correct)
+ // solution.
+ if s == "" {
+ s = " "
+ }
+
+ _, _ = r.buf.WriteString(s)
+}
+
+func (r *standardRenderer) repaint() {
+ r.lastRender = ""
+ r.lastRenderedLines = nil
+}
+
+func (r *standardRenderer) clearScreen() {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.execute(ansi.EraseEntireScreen)
+ r.execute(ansi.CursorHomePosition)
+
+ r.repaint()
+}
+
+func (r *standardRenderer) altScreen() bool {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ return r.altScreenActive
+}
+
+func (r *standardRenderer) enterAltScreen() {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ if r.altScreenActive {
+ return
+ }
+
+ r.altScreenActive = true
+ r.execute(ansi.SetAltScreenSaveCursorMode)
+
+ // Ensure that the terminal is cleared, even when it doesn't support
+ // alt screen (or alt screen support is disabled, like GNU screen by
+ // default).
+ //
+ // Note: we can't use r.clearScreen() here because the mutex is already
+ // locked.
+ r.execute(ansi.EraseEntireScreen)
+ r.execute(ansi.CursorHomePosition)
+
+ // cmd.exe and other terminals keep separate cursor states for the AltScreen
+ // and the main buffer. We have to explicitly reset the cursor visibility
+ // whenever we enter AltScreen.
+ if r.cursorHidden {
+ r.execute(ansi.HideCursor)
+ } else {
+ r.execute(ansi.ShowCursor)
+ }
+
+ // Entering the alt screen resets the lines rendered count.
+ r.altLinesRendered = 0
+
+ r.repaint()
+}
+
+func (r *standardRenderer) exitAltScreen() {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ if !r.altScreenActive {
+ return
+ }
+
+ r.altScreenActive = false
+ r.execute(ansi.ResetAltScreenSaveCursorMode)
+
+ // cmd.exe and other terminals keep separate cursor states for the AltScreen
+ // and the main buffer. We have to explicitly reset the cursor visibility
+ // whenever we exit AltScreen.
+ if r.cursorHidden {
+ r.execute(ansi.HideCursor)
+ } else {
+ r.execute(ansi.ShowCursor)
+ }
+
+ r.repaint()
+}
+
+func (r *standardRenderer) showCursor() {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.cursorHidden = false
+ r.execute(ansi.ShowCursor)
+}
+
+func (r *standardRenderer) hideCursor() {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.cursorHidden = true
+ r.execute(ansi.HideCursor)
+}
+
+func (r *standardRenderer) enableMouseCellMotion() {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.execute(ansi.SetButtonEventMouseMode)
+}
+
+func (r *standardRenderer) disableMouseCellMotion() {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.execute(ansi.ResetButtonEventMouseMode)
+}
+
+func (r *standardRenderer) enableMouseAllMotion() {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.execute(ansi.SetAnyEventMouseMode)
+}
+
+func (r *standardRenderer) disableMouseAllMotion() {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.execute(ansi.ResetAnyEventMouseMode)
+}
+
+func (r *standardRenderer) enableMouseSGRMode() {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.execute(ansi.SetSgrExtMouseMode)
+}
+
+func (r *standardRenderer) disableMouseSGRMode() {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.execute(ansi.ResetSgrExtMouseMode)
+}
+
+func (r *standardRenderer) enableBracketedPaste() {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.execute(ansi.SetBracketedPasteMode)
+ r.bpActive = true
+}
+
+func (r *standardRenderer) disableBracketedPaste() {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.execute(ansi.ResetBracketedPasteMode)
+ r.bpActive = false
+}
+
+func (r *standardRenderer) bracketedPasteActive() bool {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ return r.bpActive
+}
+
+func (r *standardRenderer) enableReportFocus() {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.execute(ansi.SetFocusEventMode)
+ r.reportingFocus = true
+}
+
+func (r *standardRenderer) disableReportFocus() {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.execute(ansi.ResetFocusEventMode)
+ r.reportingFocus = false
+}
+
+func (r *standardRenderer) reportFocus() bool {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ return r.reportingFocus
+}
+
+// setWindowTitle sets the terminal window title.
+func (r *standardRenderer) setWindowTitle(title string) {
+ r.execute(ansi.SetWindowTitle(title))
+}
+
+// setIgnoredLines specifies lines not to be touched by the standard Bubble Tea
+// renderer.
+func (r *standardRenderer) setIgnoredLines(from int, to int) {
+ // Lock if we're going to be clearing some lines since we don't want
+ // anything jacking our cursor.
+ if r.lastLinesRendered() > 0 {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+ }
+
+ if r.ignoreLines == nil {
+ r.ignoreLines = make(map[int]struct{})
+ }
+ for i := from; i < to; i++ {
+ r.ignoreLines[i] = struct{}{}
+ }
+
+ // Erase ignored lines
+ lastLinesRendered := r.lastLinesRendered()
+ if lastLinesRendered > 0 {
+ buf := &bytes.Buffer{}
+
+ for i := lastLinesRendered - 1; i >= 0; i-- {
+ if _, exists := r.ignoreLines[i]; exists {
+ buf.WriteString(ansi.EraseEntireLine)
+ }
+ buf.WriteString(ansi.CUU1)
+ }
+ buf.WriteString(ansi.CursorPosition(0, lastLinesRendered)) // put cursor back
+ _, _ = r.out.Write(buf.Bytes())
+ }
+}
+
+// clearIgnoredLines returns control of any ignored lines to the standard
+// Bubble Tea renderer. That is, any lines previously set to be ignored can be
+// rendered to again.
+func (r *standardRenderer) clearIgnoredLines() {
+ r.ignoreLines = nil
+}
+
+// insertTop effectively scrolls up. It inserts lines at the top of a given
+// area designated to be a scrollable region, pushing everything else down.
+// This is roughly how ncurses does it.
+//
+// To call this function use command ScrollUp().
+//
+// For this to work renderer.ignoreLines must be set to ignore the scrollable
+// region since we are bypassing the normal Bubble Tea renderer here.
+//
+// Because this method relies on the terminal dimensions, it's only valid for
+// full-window applications (generally those that use the alternate screen
+// buffer).
+//
+// This method bypasses the normal rendering buffer and is philosophically
+// different than the normal way we approach rendering in Bubble Tea. It's for
+// use in high-performance rendering, such as a pager that could potentially
+// be rendering very complicated ansi. In cases where the content is simpler
+// standard Bubble Tea rendering should suffice.
+//
+// Deprecated: This option is deprecated and will be removed in a future
+// version of this package.
+func (r *standardRenderer) insertTop(lines []string, topBoundary, bottomBoundary int) {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ buf := &bytes.Buffer{}
+
+ buf.WriteString(ansi.SetTopBottomMargins(topBoundary, bottomBoundary))
+ buf.WriteString(ansi.CursorPosition(0, topBoundary))
+ buf.WriteString(ansi.InsertLine(len(lines)))
+ _, _ = buf.WriteString(strings.Join(lines, "\r\n"))
+ buf.WriteString(ansi.SetTopBottomMargins(0, r.height))
+
+ // Move cursor back to where the main rendering routine expects it to be
+ buf.WriteString(ansi.CursorPosition(0, r.lastLinesRendered()))
+
+ _, _ = r.out.Write(buf.Bytes())
+}
+
+// insertBottom effectively scrolls down. It inserts lines at the bottom of
+// a given area designated to be a scrollable region, pushing everything else
+// up. This is roughly how ncurses does it.
+//
+// To call this function use the command ScrollDown().
+//
+// See note in insertTop() for caveats, how this function only makes sense for
+// full-window applications, and how it differs from the normal way we do
+// rendering in Bubble Tea.
+//
+// Deprecated: This option is deprecated and will be removed in a future
+// version of this package.
+func (r *standardRenderer) insertBottom(lines []string, topBoundary, bottomBoundary int) {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ buf := &bytes.Buffer{}
+
+ buf.WriteString(ansi.SetTopBottomMargins(topBoundary, bottomBoundary))
+ buf.WriteString(ansi.CursorPosition(0, bottomBoundary))
+ _, _ = buf.WriteString("\r\n" + strings.Join(lines, "\r\n"))
+ buf.WriteString(ansi.SetTopBottomMargins(0, r.height))
+
+ // Move cursor back to where the main rendering routine expects it to be
+ buf.WriteString(ansi.CursorPosition(0, r.lastLinesRendered()))
+
+ _, _ = r.out.Write(buf.Bytes())
+}
+
+// handleMessages handles internal messages for the renderer.
+func (r *standardRenderer) handleMessages(msg Msg) {
+ switch msg := msg.(type) {
+ case repaintMsg:
+ // Force a repaint by clearing the render cache as we slide into a
+ // render.
+ r.mtx.Lock()
+ r.repaint()
+ r.mtx.Unlock()
+
+ case WindowSizeMsg:
+ r.mtx.Lock()
+ r.width = msg.Width
+ r.height = msg.Height
+ r.repaint()
+ r.mtx.Unlock()
+
+ case clearScrollAreaMsg:
+ r.clearIgnoredLines()
+
+ // Force a repaint on the area where the scrollable stuff was in this
+ // update cycle
+ r.mtx.Lock()
+ r.repaint()
+ r.mtx.Unlock()
+
+ case syncScrollAreaMsg:
+ // Re-render scrolling area
+ r.clearIgnoredLines()
+ r.setIgnoredLines(msg.topBoundary, msg.bottomBoundary)
+ r.insertTop(msg.lines, msg.topBoundary, msg.bottomBoundary)
+
+ // Force non-scrolling stuff to repaint in this update cycle
+ r.mtx.Lock()
+ r.repaint()
+ r.mtx.Unlock()
+
+ case scrollUpMsg:
+ r.insertTop(msg.lines, msg.topBoundary, msg.bottomBoundary)
+
+ case scrollDownMsg:
+ r.insertBottom(msg.lines, msg.topBoundary, msg.bottomBoundary)
+
+ case printLineMessage:
+ if !r.altScreenActive {
+ lines := strings.Split(msg.messageBody, "\n")
+ r.mtx.Lock()
+ r.queuedMessageLines = append(r.queuedMessageLines, lines...)
+ r.repaint()
+ r.mtx.Unlock()
+ }
+ }
+}
+
+// HIGH-PERFORMANCE RENDERING STUFF
+
+type syncScrollAreaMsg struct {
+ lines []string
+ topBoundary int
+ bottomBoundary int
+}
+
+// SyncScrollArea performs a paint of the entire region designated to be the
+// scrollable area. This is required to initialize the scrollable region and
+// should also be called on resize (WindowSizeMsg).
+//
+// For high-performance, scroll-based rendering only.
+//
+// Deprecated: This option will be removed in a future version of this package.
+func SyncScrollArea(lines []string, topBoundary int, bottomBoundary int) Cmd {
+ return func() Msg {
+ return syncScrollAreaMsg{
+ lines: lines,
+ topBoundary: topBoundary,
+ bottomBoundary: bottomBoundary,
+ }
+ }
+}
+
+type clearScrollAreaMsg struct{}
+
+// ClearScrollArea deallocates the scrollable region and returns the control of
+// those lines to the main rendering routine.
+//
+// For high-performance, scroll-based rendering only.
+//
+// Deprecated: This option will be removed in a future version of this package.
+func ClearScrollArea() Msg {
+ return clearScrollAreaMsg{}
+}
+
+type scrollUpMsg struct {
+ lines []string
+ topBoundary int
+ bottomBoundary int
+}
+
+// ScrollUp adds lines to the top of the scrollable region, pushing existing
+// lines below down. Lines that are pushed out the scrollable region disappear
+// from view.
+//
+// For high-performance, scroll-based rendering only.
+//
+// Deprecated: This option will be removed in a future version of this package.
+func ScrollUp(newLines []string, topBoundary, bottomBoundary int) Cmd {
+ return func() Msg {
+ return scrollUpMsg{
+ lines: newLines,
+ topBoundary: topBoundary,
+ bottomBoundary: bottomBoundary,
+ }
+ }
+}
+
+type scrollDownMsg struct {
+ lines []string
+ topBoundary int
+ bottomBoundary int
+}
+
+// ScrollDown adds lines to the bottom of the scrollable region, pushing
+// existing lines above up. Lines that are pushed out of the scrollable region
+// disappear from view.
+//
+// For high-performance, scroll-based rendering only.
+//
+// Deprecated: This option will be removed in a future version of this package.
+func ScrollDown(newLines []string, topBoundary, bottomBoundary int) Cmd {
+ return func() Msg {
+ return scrollDownMsg{
+ lines: newLines,
+ topBoundary: topBoundary,
+ bottomBoundary: bottomBoundary,
+ }
+ }
+}
+
+type printLineMessage struct {
+ messageBody string
+}
+
+// Println prints above the Program. This output is unmanaged by the program and
+// will persist across renders by the Program.
+//
+// Unlike fmt.Println (but similar to log.Println) the message will be print on
+// its own line.
+//
+// If the altscreen is active no output will be printed.
+func Println(args ...interface{}) Cmd {
+ return func() Msg {
+ return printLineMessage{
+ messageBody: fmt.Sprint(args...),
+ }
+ }
+}
+
+// Printf prints above the Program. It takes a format template followed by
+// values similar to fmt.Printf. This output is unmanaged by the program and
+// will persist across renders by the Program.
+//
+// Unlike fmt.Printf (but similar to log.Printf) the message will be print on
+// its own line.
+//
+// If the altscreen is active no output will be printed.
+func Printf(template string, args ...interface{}) Cmd {
+ return func() Msg {
+ return printLineMessage{
+ messageBody: fmt.Sprintf(template, args...),
+ }
+ }
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/tea.go b/vendor/github.com/charmbracelet/bubbletea/tea.go
new file mode 100644
index 0000000..743a866
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/tea.go
@@ -0,0 +1,816 @@
+// Package tea provides a framework for building rich terminal user interfaces
+// based on the paradigms of The Elm Architecture. It's well-suited for simple
+// and complex terminal applications, either inline, full-window, or a mix of
+// both. It's been battle-tested in several large projects and is
+// production-ready.
+//
+// A tutorial is available at https://github.com/charmbracelet/bubbletea/tree/master/tutorials
+//
+// Example programs can be found at https://github.com/charmbracelet/bubbletea/tree/master/examples
+package tea
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "os/signal"
+ "runtime/debug"
+ "sync"
+ "sync/atomic"
+ "syscall"
+
+ "github.com/charmbracelet/x/term"
+ "github.com/muesli/cancelreader"
+ "golang.org/x/sync/errgroup"
+)
+
+// ErrProgramKilled is returned by [Program.Run] when the program gets killed.
+var ErrProgramKilled = errors.New("program was killed")
+
+// ErrInterrupted is returned by [Program.Run] when the program get a SIGINT
+// signal, or when it receives a [InterruptMsg].
+var ErrInterrupted = errors.New("program was interrupted")
+
+// Msg contain data from the result of a IO operation. Msgs trigger the update
+// function and, henceforth, the UI.
+type Msg interface{}
+
+// Model contains the program's state as well as its core functions.
+type Model interface {
+ // Init is the first function that will be called. It returns an optional
+ // initial command. To not perform an initial command return nil.
+ Init() Cmd
+
+ // Update is called when a message is received. Use it to inspect messages
+ // and, in response, update the model and/or send a command.
+ Update(Msg) (Model, Cmd)
+
+ // View renders the program's UI, which is just a string. The view is
+ // rendered after every Update.
+ View() string
+}
+
+// Cmd is an IO operation that returns a message when it's complete. If it's
+// nil it's considered a no-op. Use it for things like HTTP requests, timers,
+// saving and loading from disk, and so on.
+//
+// Note that there's almost never a reason to use a command to send a message
+// to another part of your program. That can almost always be done in the
+// update function.
+type Cmd func() Msg
+
+type inputType int
+
+const (
+ defaultInput inputType = iota
+ ttyInput
+ customInput
+)
+
+// String implements the stringer interface for [inputType]. It is inteded to
+// be used in testing.
+func (i inputType) String() string {
+ return [...]string{
+ "default input",
+ "tty input",
+ "custom input",
+ }[i]
+}
+
+// Options to customize the program during its initialization. These are
+// generally set with ProgramOptions.
+//
+// The options here are treated as bits.
+type startupOptions int16
+
+func (s startupOptions) has(option startupOptions) bool {
+ return s&option != 0
+}
+
+const (
+ withAltScreen startupOptions = 1 << iota
+ withMouseCellMotion
+ withMouseAllMotion
+ withANSICompressor
+ withoutSignalHandler
+ // Catching panics is incredibly useful for restoring the terminal to a
+ // usable state after a panic occurs. When this is set, Bubble Tea will
+ // recover from panics, print the stack trace, and disable raw mode. This
+ // feature is on by default.
+ withoutCatchPanics
+ withoutBracketedPaste
+ withReportFocus
+)
+
+// channelHandlers manages the series of channels returned by various processes.
+// It allows us to wait for those processes to terminate before exiting the
+// program.
+type channelHandlers []chan struct{}
+
+// Adds a channel to the list of handlers. We wait for all handlers to terminate
+// gracefully on shutdown.
+func (h *channelHandlers) add(ch chan struct{}) {
+ *h = append(*h, ch)
+}
+
+// shutdown waits for all handlers to terminate.
+func (h channelHandlers) shutdown() {
+ var wg sync.WaitGroup
+ for _, ch := range h {
+ wg.Add(1)
+ go func(ch chan struct{}) {
+ <-ch
+ wg.Done()
+ }(ch)
+ }
+ wg.Wait()
+}
+
+// Program is a terminal user interface.
+type Program struct {
+ initialModel Model
+
+ // handlers is a list of channels that need to be waited on before the
+ // program can exit.
+ handlers channelHandlers
+
+ // Configuration options that will set as the program is initializing,
+ // treated as bits. These options can be set via various ProgramOptions.
+ startupOptions startupOptions
+
+ // startupTitle is the title that will be set on the terminal when the
+ // program starts.
+ startupTitle string
+
+ inputType inputType
+
+ ctx context.Context
+ cancel context.CancelFunc
+
+ msgs chan Msg
+ errs chan error
+ finished chan struct{}
+
+ // where to send output, this will usually be os.Stdout.
+ output io.Writer
+ // ttyOutput is null if output is not a TTY.
+ ttyOutput term.File
+ previousOutputState *term.State
+ renderer renderer
+
+ // the environment variables for the program, defaults to os.Environ().
+ environ []string
+
+ // where to read inputs from, this will usually be os.Stdin.
+ input io.Reader
+ // ttyInput is null if input is not a TTY.
+ ttyInput term.File
+ previousTtyInputState *term.State
+ cancelReader cancelreader.CancelReader
+ readLoopDone chan struct{}
+
+ // was the altscreen active before releasing the terminal?
+ altScreenWasActive bool
+ ignoreSignals uint32
+
+ bpWasActive bool // was the bracketed paste mode active before releasing the terminal?
+ reportFocus bool // was focus reporting active before releasing the terminal?
+
+ filter func(Model, Msg) Msg
+
+ // fps is the frames per second we should set on the renderer, if
+ // applicable,
+ fps int
+}
+
+// Quit is a special command that tells the Bubble Tea program to exit.
+func Quit() Msg {
+ return QuitMsg{}
+}
+
+// QuitMsg signals that the program should quit. You can send a [QuitMsg] with
+// [Quit].
+type QuitMsg struct{}
+
+// Suspend is a special command that tells the Bubble Tea program to suspend.
+func Suspend() Msg {
+ return SuspendMsg{}
+}
+
+// SuspendMsg signals the program should suspend.
+// This usually happens when ctrl+z is pressed on common programs, but since
+// bubbletea puts the terminal in raw mode, we need to handle it in a
+// per-program basis.
+//
+// You can send this message with [Suspend()].
+type SuspendMsg struct{}
+
+// ResumeMsg can be listen to to do something once a program is resumed back
+// from a suspend state.
+type ResumeMsg struct{}
+
+// InterruptMsg signals the program should suspend.
+// This usually happens when ctrl+c is pressed on common programs, but since
+// bubbletea puts the terminal in raw mode, we need to handle it in a
+// per-program basis.
+//
+// You can send this message with [Interrupt()].
+type InterruptMsg struct{}
+
+// Interrupt is a special command that tells the Bubble Tea program to
+// interrupt.
+func Interrupt() Msg {
+ return InterruptMsg{}
+}
+
+// NewProgram creates a new Program.
+func NewProgram(model Model, opts ...ProgramOption) *Program {
+ p := &Program{
+ initialModel: model,
+ msgs: make(chan Msg),
+ }
+
+ // Apply all options to the program.
+ for _, opt := range opts {
+ opt(p)
+ }
+
+ // A context can be provided with a ProgramOption, but if none was provided
+ // we'll use the default background context.
+ if p.ctx == nil {
+ p.ctx = context.Background()
+ }
+ // Initialize context and teardown channel.
+ p.ctx, p.cancel = context.WithCancel(p.ctx)
+
+ // if no output was set, set it to stdout
+ if p.output == nil {
+ p.output = os.Stdout
+ }
+
+ // if no environment was set, set it to os.Environ()
+ if p.environ == nil {
+ p.environ = os.Environ()
+ }
+
+ return p
+}
+
+func (p *Program) handleSignals() chan struct{} {
+ ch := make(chan struct{})
+
+ // Listen for SIGINT and SIGTERM.
+ //
+ // In most cases ^C will not send an interrupt because the terminal will be
+ // in raw mode and ^C will be captured as a keystroke and sent along to
+ // Program.Update as a KeyMsg. When input is not a TTY, however, ^C will be
+ // caught here.
+ //
+ // SIGTERM is sent by unix utilities (like kill) to terminate a process.
+ go func() {
+ sig := make(chan os.Signal, 1)
+ signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
+ defer func() {
+ signal.Stop(sig)
+ close(ch)
+ }()
+
+ for {
+ select {
+ case <-p.ctx.Done():
+ return
+
+ case s := <-sig:
+ if atomic.LoadUint32(&p.ignoreSignals) == 0 {
+ switch s {
+ case syscall.SIGINT:
+ p.msgs <- InterruptMsg{}
+ default:
+ p.msgs <- QuitMsg{}
+ }
+ return
+ }
+ }
+ }
+ }()
+
+ return ch
+}
+
+// handleResize handles terminal resize events.
+func (p *Program) handleResize() chan struct{} {
+ ch := make(chan struct{})
+
+ if p.ttyOutput != nil {
+ // Get the initial terminal size and send it to the program.
+ go p.checkResize()
+
+ // Listen for window resizes.
+ go p.listenForResize(ch)
+ } else {
+ close(ch)
+ }
+
+ return ch
+}
+
+// handleCommands runs commands in a goroutine and sends the result to the
+// program's message channel.
+func (p *Program) handleCommands(cmds chan Cmd) chan struct{} {
+ ch := make(chan struct{})
+
+ go func() {
+ defer close(ch)
+
+ for {
+ select {
+ case <-p.ctx.Done():
+ return
+
+ case cmd := <-cmds:
+ if cmd == nil {
+ continue
+ }
+
+ // Don't wait on these goroutines, otherwise the shutdown
+ // latency would get too large as a Cmd can run for some time
+ // (e.g. tick commands that sleep for half a second). It's not
+ // possible to cancel them so we'll have to leak the goroutine
+ // until Cmd returns.
+ go func() {
+ // Recover from panics.
+ if !p.startupOptions.has(withoutCatchPanics) {
+ defer p.recoverFromPanic()
+ }
+
+ msg := cmd() // this can be long.
+ p.Send(msg)
+ }()
+ }
+ }
+ }()
+
+ return ch
+}
+
+func (p *Program) disableMouse() {
+ p.renderer.disableMouseCellMotion()
+ p.renderer.disableMouseAllMotion()
+ p.renderer.disableMouseSGRMode()
+}
+
+// eventLoop is the central message loop. It receives and handles the default
+// Bubble Tea messages, update the model and triggers redraws.
+func (p *Program) eventLoop(model Model, cmds chan Cmd) (Model, error) {
+ for {
+ select {
+ case <-p.ctx.Done():
+ return model, nil
+
+ case err := <-p.errs:
+ return model, err
+
+ case msg := <-p.msgs:
+ // Filter messages.
+ if p.filter != nil {
+ msg = p.filter(model, msg)
+ }
+ if msg == nil {
+ continue
+ }
+
+ // Handle special internal messages.
+ switch msg := msg.(type) {
+ case QuitMsg:
+ return model, nil
+
+ case InterruptMsg:
+ return model, ErrInterrupted
+
+ case SuspendMsg:
+ if suspendSupported {
+ p.suspend()
+ }
+
+ case clearScreenMsg:
+ p.renderer.clearScreen()
+
+ case enterAltScreenMsg:
+ p.renderer.enterAltScreen()
+
+ case exitAltScreenMsg:
+ p.renderer.exitAltScreen()
+
+ case enableMouseCellMotionMsg, enableMouseAllMotionMsg:
+ switch msg.(type) {
+ case enableMouseCellMotionMsg:
+ p.renderer.enableMouseCellMotion()
+ case enableMouseAllMotionMsg:
+ p.renderer.enableMouseAllMotion()
+ }
+ // mouse mode (1006) is a no-op if the terminal doesn't support it.
+ p.renderer.enableMouseSGRMode()
+
+ case disableMouseMsg:
+ p.disableMouse()
+
+ case showCursorMsg:
+ p.renderer.showCursor()
+
+ case hideCursorMsg:
+ p.renderer.hideCursor()
+
+ case enableBracketedPasteMsg:
+ p.renderer.enableBracketedPaste()
+
+ case disableBracketedPasteMsg:
+ p.renderer.disableBracketedPaste()
+
+ case enableReportFocusMsg:
+ p.renderer.enableReportFocus()
+
+ case disableReportFocusMsg:
+ p.renderer.disableReportFocus()
+
+ case execMsg:
+ // NB: this blocks.
+ p.exec(msg.cmd, msg.fn)
+
+ case BatchMsg:
+ for _, cmd := range msg {
+ cmds <- cmd
+ }
+ continue
+
+ case sequenceMsg:
+ go func() {
+ // Execute commands one at a time, in order.
+ for _, cmd := range msg {
+ if cmd == nil {
+ continue
+ }
+
+ msg := cmd()
+ if batchMsg, ok := msg.(BatchMsg); ok {
+ g, _ := errgroup.WithContext(p.ctx)
+ for _, cmd := range batchMsg {
+ cmd := cmd
+ g.Go(func() error {
+ p.Send(cmd())
+ return nil
+ })
+ }
+
+ //nolint:errcheck
+ g.Wait() // wait for all commands from batch msg to finish
+ continue
+ }
+
+ p.Send(msg)
+ }
+ }()
+
+ case setWindowTitleMsg:
+ p.SetWindowTitle(string(msg))
+
+ case windowSizeMsg:
+ go p.checkResize()
+ }
+
+ // Process internal messages for the renderer.
+ if r, ok := p.renderer.(*standardRenderer); ok {
+ r.handleMessages(msg)
+ }
+
+ var cmd Cmd
+ model, cmd = model.Update(msg) // run update
+ cmds <- cmd // process command (if any)
+ p.renderer.write(model.View()) // send view to renderer
+ }
+ }
+}
+
+// Run initializes the program and runs its event loops, blocking until it gets
+// terminated by either [Program.Quit], [Program.Kill], or its signal handler.
+// Returns the final model.
+func (p *Program) Run() (Model, error) {
+ p.handlers = channelHandlers{}
+ cmds := make(chan Cmd)
+ p.errs = make(chan error)
+ p.finished = make(chan struct{}, 1)
+
+ defer p.cancel()
+
+ switch p.inputType {
+ case defaultInput:
+ p.input = os.Stdin
+
+ // The user has not set a custom input, so we need to check whether or
+ // not standard input is a terminal. If it's not, we open a new TTY for
+ // input. This will allow things to "just work" in cases where data was
+ // piped in or redirected to the application.
+ //
+ // To disable input entirely pass nil to the [WithInput] program option.
+ f, isFile := p.input.(term.File)
+ if !isFile {
+ break
+ }
+ if term.IsTerminal(f.Fd()) {
+ break
+ }
+
+ f, err := openInputTTY()
+ if err != nil {
+ return p.initialModel, err
+ }
+ defer f.Close() //nolint:errcheck
+ p.input = f
+
+ case ttyInput:
+ // Open a new TTY, by request
+ f, err := openInputTTY()
+ if err != nil {
+ return p.initialModel, err
+ }
+ defer f.Close() //nolint:errcheck
+ p.input = f
+
+ case customInput:
+ // (There is nothing extra to do.)
+ }
+
+ // Handle signals.
+ if !p.startupOptions.has(withoutSignalHandler) {
+ p.handlers.add(p.handleSignals())
+ }
+
+ // Recover from panics.
+ if !p.startupOptions.has(withoutCatchPanics) {
+ defer p.recoverFromPanic()
+ }
+
+ // If no renderer is set use the standard one.
+ if p.renderer == nil {
+ p.renderer = newRenderer(p.output, p.startupOptions.has(withANSICompressor), p.fps)
+ }
+
+ // Check if output is a TTY before entering raw mode, hiding the cursor and
+ // so on.
+ if err := p.initTerminal(); err != nil {
+ return p.initialModel, err
+ }
+
+ // Honor program startup options.
+ if p.startupTitle != "" {
+ p.renderer.setWindowTitle(p.startupTitle)
+ }
+ if p.startupOptions&withAltScreen != 0 {
+ p.renderer.enterAltScreen()
+ }
+ if p.startupOptions&withoutBracketedPaste == 0 {
+ p.renderer.enableBracketedPaste()
+ }
+ if p.startupOptions&withMouseCellMotion != 0 {
+ p.renderer.enableMouseCellMotion()
+ p.renderer.enableMouseSGRMode()
+ } else if p.startupOptions&withMouseAllMotion != 0 {
+ p.renderer.enableMouseAllMotion()
+ p.renderer.enableMouseSGRMode()
+ }
+ if p.startupOptions&withReportFocus != 0 {
+ p.renderer.enableReportFocus()
+ }
+
+ // Start the renderer.
+ p.renderer.start()
+
+ // Initialize the program.
+ model := p.initialModel
+ if initCmd := model.Init(); initCmd != nil {
+ ch := make(chan struct{})
+ p.handlers.add(ch)
+
+ go func() {
+ defer close(ch)
+
+ select {
+ case cmds <- initCmd:
+ case <-p.ctx.Done():
+ }
+ }()
+ }
+
+ // Render the initial view.
+ p.renderer.write(model.View())
+
+ // Subscribe to user input.
+ if p.input != nil {
+ if err := p.initCancelReader(); err != nil {
+ return model, err
+ }
+ }
+
+ // Handle resize events.
+ p.handlers.add(p.handleResize())
+
+ // Process commands.
+ p.handlers.add(p.handleCommands(cmds))
+
+ // Run event loop, handle updates and draw.
+ model, err := p.eventLoop(model, cmds)
+ killed := p.ctx.Err() != nil || err != nil
+ if killed && err == nil {
+ err = fmt.Errorf("%w: %s", ErrProgramKilled, p.ctx.Err())
+ }
+ if err == nil {
+ // Ensure we rendered the final state of the model.
+ p.renderer.write(model.View())
+ }
+
+ // Restore terminal state.
+ p.shutdown(killed)
+
+ return model, err
+}
+
+// StartReturningModel initializes the program and runs its event loops,
+// blocking until it gets terminated by either [Program.Quit], [Program.Kill],
+// or its signal handler. Returns the final model.
+//
+// Deprecated: please use [Program.Run] instead.
+func (p *Program) StartReturningModel() (Model, error) {
+ return p.Run()
+}
+
+// Start initializes the program and runs its event loops, blocking until it
+// gets terminated by either [Program.Quit], [Program.Kill], or its signal
+// handler.
+//
+// Deprecated: please use [Program.Run] instead.
+func (p *Program) Start() error {
+ _, err := p.Run()
+ return err
+}
+
+// Send sends a message to the main update function, effectively allowing
+// messages to be injected from outside the program for interoperability
+// purposes.
+//
+// If the program hasn't started yet this will be a blocking operation.
+// If the program has already been terminated this will be a no-op, so it's safe
+// to send messages after the program has exited.
+func (p *Program) Send(msg Msg) {
+ select {
+ case <-p.ctx.Done():
+ case p.msgs <- msg:
+ }
+}
+
+// Quit is a convenience function for quitting Bubble Tea programs. Use it
+// when you need to shut down a Bubble Tea program from the outside.
+//
+// If you wish to quit from within a Bubble Tea program use the Quit command.
+//
+// If the program is not running this will be a no-op, so it's safe to call
+// if the program is unstarted or has already exited.
+func (p *Program) Quit() {
+ p.Send(Quit())
+}
+
+// Kill stops the program immediately and restores the former terminal state.
+// The final render that you would normally see when quitting will be skipped.
+// [program.Run] returns a [ErrProgramKilled] error.
+func (p *Program) Kill() {
+ p.shutdown(true)
+}
+
+// Wait waits/blocks until the underlying Program finished shutting down.
+func (p *Program) Wait() {
+ <-p.finished
+}
+
+// shutdown performs operations to free up resources and restore the terminal
+// to its original state.
+func (p *Program) shutdown(kill bool) {
+ p.cancel()
+
+ // Wait for all handlers to finish.
+ p.handlers.shutdown()
+
+ // Check if the cancel reader has been setup before waiting and closing.
+ if p.cancelReader != nil {
+ // Wait for input loop to finish.
+ if p.cancelReader.Cancel() {
+ if !kill {
+ p.waitForReadLoop()
+ }
+ }
+ _ = p.cancelReader.Close()
+ }
+
+ if p.renderer != nil {
+ if kill {
+ p.renderer.kill()
+ } else {
+ p.renderer.stop()
+ }
+ }
+
+ _ = p.restoreTerminalState()
+ if !kill {
+ p.finished <- struct{}{}
+ }
+}
+
+// recoverFromPanic recovers from a panic, prints the stack trace, and restores
+// the terminal to a usable state.
+func (p *Program) recoverFromPanic() {
+ if r := recover(); r != nil {
+ p.shutdown(true)
+ fmt.Printf("Caught panic:\n\n%s\n\nRestoring terminal...\n\n", r)
+ debug.PrintStack()
+ }
+}
+
+// ReleaseTerminal restores the original terminal state and cancels the input
+// reader. You can return control to the Program with RestoreTerminal.
+func (p *Program) ReleaseTerminal() error {
+ atomic.StoreUint32(&p.ignoreSignals, 1)
+ if p.cancelReader != nil {
+ p.cancelReader.Cancel()
+ }
+
+ p.waitForReadLoop()
+
+ if p.renderer != nil {
+ p.renderer.stop()
+ p.altScreenWasActive = p.renderer.altScreen()
+ p.bpWasActive = p.renderer.bracketedPasteActive()
+ p.reportFocus = p.renderer.reportFocus()
+ }
+
+ return p.restoreTerminalState()
+}
+
+// RestoreTerminal reinitializes the Program's input reader, restores the
+// terminal to the former state when the program was running, and repaints.
+// Use it to reinitialize a Program after running ReleaseTerminal.
+func (p *Program) RestoreTerminal() error {
+ atomic.StoreUint32(&p.ignoreSignals, 0)
+
+ if err := p.initTerminal(); err != nil {
+ return err
+ }
+ if err := p.initCancelReader(); err != nil {
+ return err
+ }
+ if p.altScreenWasActive {
+ p.renderer.enterAltScreen()
+ } else {
+ // entering alt screen already causes a repaint.
+ go p.Send(repaintMsg{})
+ }
+ if p.renderer != nil {
+ p.renderer.start()
+ }
+ if p.bpWasActive {
+ p.renderer.enableBracketedPaste()
+ }
+ if p.reportFocus {
+ p.renderer.enableReportFocus()
+ }
+
+ // If the output is a terminal, it may have been resized while another
+ // process was at the foreground, in which case we may not have received
+ // SIGWINCH. Detect any size change now and propagate the new size as
+ // needed.
+ go p.checkResize()
+
+ return nil
+}
+
+// Println prints above the Program. This output is unmanaged by the program
+// and will persist across renders by the Program.
+//
+// If the altscreen is active no output will be printed.
+func (p *Program) Println(args ...interface{}) {
+ p.msgs <- printLineMessage{
+ messageBody: fmt.Sprint(args...),
+ }
+}
+
+// Printf prints above the Program. It takes a format template followed by
+// values similar to fmt.Printf. This output is unmanaged by the program and
+// will persist across renders by the Program.
+//
+// Unlike fmt.Printf (but similar to log.Printf) the message will be print on
+// its own line.
+//
+// If the altscreen is active no output will be printed.
+func (p *Program) Printf(template string, args ...interface{}) {
+ p.msgs <- printLineMessage{
+ messageBody: fmt.Sprintf(template, args...),
+ }
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/tea_init.go b/vendor/github.com/charmbracelet/bubbletea/tea_init.go
new file mode 100644
index 0000000..19b6cc3
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/tea_init.go
@@ -0,0 +1,22 @@
+package tea
+
+import (
+ "github.com/charmbracelet/lipgloss"
+)
+
+func init() {
+ // XXX: This is a workaround to make assure that Lip Gloss and Termenv
+ // query the terminal before any Bubble Tea Program runs and acquires the
+ // terminal. Without this, Programs that use Lip Gloss/Termenv might hang
+ // while waiting for a a [termenv.OSCTimeout] while querying the terminal
+ // for its background/foreground colors.
+ //
+ // This happens because Bubble Tea acquires the terminal before termenv
+ // reads any responses.
+ //
+ // Note that this will only affect programs running on the default IO i.e.
+ // [os.Stdout] and [os.Stdin].
+ //
+ // This workaround will be removed in v2.
+ _ = lipgloss.HasDarkBackground()
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/tty.go b/vendor/github.com/charmbracelet/bubbletea/tty.go
new file mode 100644
index 0000000..0250778
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/tty.go
@@ -0,0 +1,136 @@
+package tea
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "time"
+
+ "github.com/charmbracelet/x/term"
+ "github.com/muesli/cancelreader"
+)
+
+func (p *Program) suspend() {
+ if err := p.ReleaseTerminal(); err != nil {
+ // If we can't release input, abort.
+ return
+ }
+
+ suspendProcess()
+
+ _ = p.RestoreTerminal()
+ go p.Send(ResumeMsg{})
+}
+
+func (p *Program) initTerminal() error {
+ if _, ok := p.renderer.(*nilRenderer); ok {
+ // No need to initialize the terminal if we're not rendering
+ return nil
+ }
+
+ if err := p.initInput(); err != nil {
+ return err
+ }
+
+ p.renderer.hideCursor()
+ return nil
+}
+
+// restoreTerminalState restores the terminal to the state prior to running the
+// Bubble Tea program.
+func (p *Program) restoreTerminalState() error {
+ if p.renderer != nil {
+ p.renderer.disableBracketedPaste()
+ p.renderer.showCursor()
+ p.disableMouse()
+
+ if p.renderer.reportFocus() {
+ p.renderer.disableReportFocus()
+ }
+
+ if p.renderer.altScreen() {
+ p.renderer.exitAltScreen()
+
+ // give the terminal a moment to catch up
+ time.Sleep(time.Millisecond * 10) //nolint:gomnd
+ }
+ }
+
+ return p.restoreInput()
+}
+
+// restoreInput restores the tty input to its original state.
+func (p *Program) restoreInput() error {
+ if p.ttyInput != nil && p.previousTtyInputState != nil {
+ if err := term.Restore(p.ttyInput.Fd(), p.previousTtyInputState); err != nil {
+ return fmt.Errorf("error restoring console: %w", err)
+ }
+ }
+ if p.ttyOutput != nil && p.previousOutputState != nil {
+ if err := term.Restore(p.ttyOutput.Fd(), p.previousOutputState); err != nil {
+ return fmt.Errorf("error restoring console: %w", err)
+ }
+ }
+ return nil
+}
+
+// initCancelReader (re)commences reading inputs.
+func (p *Program) initCancelReader() error {
+ var err error
+ p.cancelReader, err = newInputReader(p.input)
+ if err != nil {
+ return fmt.Errorf("error creating cancelreader: %w", err)
+ }
+
+ p.readLoopDone = make(chan struct{})
+ go p.readLoop()
+
+ return nil
+}
+
+func (p *Program) readLoop() {
+ defer close(p.readLoopDone)
+
+ err := readInputs(p.ctx, p.msgs, p.cancelReader)
+ if !errors.Is(err, io.EOF) && !errors.Is(err, cancelreader.ErrCanceled) {
+ select {
+ case <-p.ctx.Done():
+ case p.errs <- err:
+ }
+ }
+}
+
+// waitForReadLoop waits for the cancelReader to finish its read loop.
+func (p *Program) waitForReadLoop() {
+ select {
+ case <-p.readLoopDone:
+ case <-time.After(500 * time.Millisecond): //nolint:gomnd
+ // The read loop hangs, which means the input
+ // cancelReader's cancel function has returned true even
+ // though it was not able to cancel the read.
+ }
+}
+
+// checkResize detects the current size of the output and informs the program
+// via a WindowSizeMsg.
+func (p *Program) checkResize() {
+ if p.ttyOutput == nil {
+ // can't query window size
+ return
+ }
+
+ w, h, err := term.GetSize(p.ttyOutput.Fd())
+ if err != nil {
+ select {
+ case <-p.ctx.Done():
+ case p.errs <- err:
+ }
+
+ return
+ }
+
+ p.Send(WindowSizeMsg{
+ Width: w,
+ Height: h,
+ })
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/tty_unix.go b/vendor/github.com/charmbracelet/bubbletea/tty_unix.go
new file mode 100644
index 0000000..5cbb4fe
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/tty_unix.go
@@ -0,0 +1,49 @@
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || aix || zos
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris aix zos
+
+package tea
+
+import (
+ "fmt"
+ "os"
+ "os/signal"
+ "syscall"
+
+ "github.com/charmbracelet/x/term"
+)
+
+func (p *Program) initInput() (err error) {
+ // Check if input is a terminal
+ if f, ok := p.input.(term.File); ok && term.IsTerminal(f.Fd()) {
+ p.ttyInput = f
+ p.previousTtyInputState, err = term.MakeRaw(p.ttyInput.Fd())
+ if err != nil {
+ return fmt.Errorf("error entering raw mode: %w", err)
+ }
+ }
+
+ if f, ok := p.output.(term.File); ok && term.IsTerminal(f.Fd()) {
+ p.ttyOutput = f
+ }
+
+ return nil
+}
+
+func openInputTTY() (*os.File, error) {
+ f, err := os.Open("/dev/tty")
+ if err != nil {
+ return nil, fmt.Errorf("could not open a new TTY: %w", err)
+ }
+ return f, nil
+}
+
+const suspendSupported = true
+
+// Send SIGTSTP to the entire process group.
+func suspendProcess() {
+ c := make(chan os.Signal, 1)
+ signal.Notify(c, syscall.SIGCONT)
+ _ = syscall.Kill(0, syscall.SIGTSTP)
+ // blocks until a CONT happens...
+ <-c
+}
diff --git a/vendor/github.com/charmbracelet/bubbletea/tty_windows.go b/vendor/github.com/charmbracelet/bubbletea/tty_windows.go
new file mode 100644
index 0000000..a3a2525
--- /dev/null
+++ b/vendor/github.com/charmbracelet/bubbletea/tty_windows.go
@@ -0,0 +1,68 @@
+//go:build windows
+// +build windows
+
+package tea
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/charmbracelet/x/term"
+ "golang.org/x/sys/windows"
+)
+
+func (p *Program) initInput() (err error) {
+ // Save stdin state and enable VT input
+ // We also need to enable VT
+ // input here.
+ if f, ok := p.input.(term.File); ok && term.IsTerminal(f.Fd()) {
+ p.ttyInput = f
+ p.previousTtyInputState, err = term.MakeRaw(p.ttyInput.Fd())
+ if err != nil {
+ return err
+ }
+
+ // Enable VT input
+ var mode uint32
+ if err := windows.GetConsoleMode(windows.Handle(p.ttyInput.Fd()), &mode); err != nil {
+ return fmt.Errorf("error getting console mode: %w", err)
+ }
+
+ if err := windows.SetConsoleMode(windows.Handle(p.ttyInput.Fd()), mode|windows.ENABLE_VIRTUAL_TERMINAL_INPUT); err != nil {
+ return fmt.Errorf("error setting console mode: %w", err)
+ }
+ }
+
+ // Save output screen buffer state and enable VT processing.
+ if f, ok := p.output.(term.File); ok && term.IsTerminal(f.Fd()) {
+ p.ttyOutput = f
+ p.previousOutputState, err = term.GetState(f.Fd())
+ if err != nil {
+ return err
+ }
+
+ var mode uint32
+ if err := windows.GetConsoleMode(windows.Handle(p.ttyOutput.Fd()), &mode); err != nil {
+ return fmt.Errorf("error getting console mode: %w", err)
+ }
+
+ if err := windows.SetConsoleMode(windows.Handle(p.ttyOutput.Fd()), mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err != nil {
+ return fmt.Errorf("error setting console mode: %w", err)
+ }
+ }
+
+ return
+}
+
+// Open the Windows equivalent of a TTY.
+func openInputTTY() (*os.File, error) {
+ f, err := os.OpenFile("CONIN$", os.O_RDWR, 0o644)
+ if err != nil {
+ return nil, err
+ }
+ return f, nil
+}
+
+const suspendSupported = false
+
+func suspendProcess() {}
diff --git a/vendor/github.com/charmbracelet/lipgloss/.gitignore b/vendor/github.com/charmbracelet/lipgloss/.gitignore
new file mode 100644
index 0000000..53e1c2b
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/.gitignore
@@ -0,0 +1 @@
+ssh_example_ed25519*
diff --git a/vendor/github.com/charmbracelet/lipgloss/.golangci-soft.yml b/vendor/github.com/charmbracelet/lipgloss/.golangci-soft.yml
new file mode 100644
index 0000000..8783713
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/.golangci-soft.yml
@@ -0,0 +1,40 @@
+run:
+ tests: false
+
+issues:
+ include:
+ - EXC0001
+ - EXC0005
+ - EXC0011
+ - EXC0012
+ - EXC0013
+
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ enable:
+ - exhaustive
+ - goconst
+ - godot
+ - godox
+ - mnd
+ - gomoddirectives
+ - goprintffuncname
+ - misspell
+ - nakedret
+ - nestif
+ - noctx
+ - nolintlint
+ - prealloc
+ - wrapcheck
+
+ # disable default linters, they are already enabled in .golangci.yml
+ disable:
+ - errcheck
+ - gosimple
+ - govet
+ - ineffassign
+ - staticcheck
+ - typecheck
+ - unused
diff --git a/vendor/github.com/charmbracelet/lipgloss/.golangci.yml b/vendor/github.com/charmbracelet/lipgloss/.golangci.yml
new file mode 100644
index 0000000..d6789e0
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/.golangci.yml
@@ -0,0 +1,28 @@
+run:
+ tests: false
+
+issues:
+ include:
+ - EXC0001
+ - EXC0005
+ - EXC0011
+ - EXC0012
+ - EXC0013
+
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ enable:
+ - bodyclose
+ - gofumpt
+ - goimports
+ - gosec
+ - nilerr
+ - revive
+ - rowserrcheck
+ - sqlclosecheck
+ - tparallel
+ - unconvert
+ - unparam
+ - whitespace
diff --git a/vendor/github.com/charmbracelet/lipgloss/.goreleaser.yml b/vendor/github.com/charmbracelet/lipgloss/.goreleaser.yml
new file mode 100644
index 0000000..c61970e
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/.goreleaser.yml
@@ -0,0 +1,5 @@
+includes:
+ - from_url:
+ url: charmbracelet/meta/main/goreleaser-lib.yaml
+# yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json
+
diff --git a/vendor/github.com/charmbracelet/lipgloss/LICENSE b/vendor/github.com/charmbracelet/lipgloss/LICENSE
new file mode 100644
index 0000000..6f5b1fa
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021-2023 Charmbracelet, Inc
+
+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/vendor/github.com/charmbracelet/lipgloss/README.md b/vendor/github.com/charmbracelet/lipgloss/README.md
new file mode 100644
index 0000000..f171e7d
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/README.md
@@ -0,0 +1,765 @@
+# Lip Gloss
+
+
+
+Style definitions for nice terminal layouts. Built with TUIs in mind.
+
+
+
+Lip Gloss takes an expressive, declarative approach to terminal rendering.
+Users familiar with CSS will feel at home with Lip Gloss.
+
+```go
+
+import "github.com/charmbracelet/lipgloss"
+
+var style = lipgloss.NewStyle().
+ Bold(true).
+ Foreground(lipgloss.Color("#FAFAFA")).
+ Background(lipgloss.Color("#7D56F4")).
+ PaddingTop(2).
+ PaddingLeft(4).
+ Width(22)
+
+fmt.Println(style.Render("Hello, kitty"))
+```
+
+## Colors
+
+Lip Gloss supports the following color profiles:
+
+### ANSI 16 colors (4-bit)
+
+```go
+lipgloss.Color("5") // magenta
+lipgloss.Color("9") // red
+lipgloss.Color("12") // light blue
+```
+
+### ANSI 256 Colors (8-bit)
+
+```go
+lipgloss.Color("86") // aqua
+lipgloss.Color("201") // hot pink
+lipgloss.Color("202") // orange
+```
+
+### True Color (16,777,216 colors; 24-bit)
+
+```go
+lipgloss.Color("#0000FF") // good ol' 100% blue
+lipgloss.Color("#04B575") // a green
+lipgloss.Color("#3C3C3C") // a dark gray
+```
+
+...as well as a 1-bit ASCII profile, which is black and white only.
+
+The terminal's color profile will be automatically detected, and colors outside
+the gamut of the current palette will be automatically coerced to their closest
+available value.
+
+### Adaptive Colors
+
+You can also specify color options for light and dark backgrounds:
+
+```go
+lipgloss.AdaptiveColor{Light: "236", Dark: "248"}
+```
+
+The terminal's background color will automatically be detected and the
+appropriate color will be chosen at runtime.
+
+### Complete Colors
+
+CompleteColor specifies exact values for True Color, ANSI256, and ANSI color
+profiles.
+
+```go
+lipgloss.CompleteColor{TrueColor: "#0000FF", ANSI256: "86", ANSI: "5"}
+```
+
+Automatic color degradation will not be performed in this case and it will be
+based on the color specified.
+
+### Complete Adaptive Colors
+
+You can use `CompleteColor` with `AdaptiveColor` to specify the exact values for
+light and dark backgrounds without automatic color degradation.
+
+```go
+lipgloss.CompleteAdaptiveColor{
+ Light: CompleteColor{TrueColor: "#d7ffae", ANSI256: "193", ANSI: "11"},
+ Dark: CompleteColor{TrueColor: "#d75fee", ANSI256: "163", ANSI: "5"},
+}
+```
+
+## Inline Formatting
+
+Lip Gloss supports the usual ANSI text formatting options:
+
+```go
+var style = lipgloss.NewStyle().
+ Bold(true).
+ Italic(true).
+ Faint(true).
+ Blink(true).
+ Strikethrough(true).
+ Underline(true).
+ Reverse(true)
+```
+
+## Block-Level Formatting
+
+Lip Gloss also supports rules for block-level formatting:
+
+```go
+// Padding
+var style = lipgloss.NewStyle().
+ PaddingTop(2).
+ PaddingRight(4).
+ PaddingBottom(2).
+ PaddingLeft(4)
+
+// Margins
+var style = lipgloss.NewStyle().
+ MarginTop(2).
+ MarginRight(4).
+ MarginBottom(2).
+ MarginLeft(4)
+```
+
+There is also shorthand syntax for margins and padding, which follows the same
+format as CSS:
+
+```go
+// 2 cells on all sides
+lipgloss.NewStyle().Padding(2)
+
+// 2 cells on the top and bottom, 4 cells on the left and right
+lipgloss.NewStyle().Margin(2, 4)
+
+// 1 cell on the top, 4 cells on the sides, 2 cells on the bottom
+lipgloss.NewStyle().Padding(1, 4, 2)
+
+// Clockwise, starting from the top: 2 cells on the top, 4 on the right, 3 on
+// the bottom, and 1 on the left
+lipgloss.NewStyle().Margin(2, 4, 3, 1)
+```
+
+## Aligning Text
+
+You can align paragraphs of text to the left, right, or center.
+
+```go
+var style = lipgloss.NewStyle().
+ Width(24).
+ Align(lipgloss.Left). // align it left
+ Align(lipgloss.Right). // no wait, align it right
+ Align(lipgloss.Center) // just kidding, align it in the center
+```
+
+## Width and Height
+
+Setting a minimum width and height is simple and straightforward.
+
+```go
+var style = lipgloss.NewStyle().
+ SetString("What’s for lunch?").
+ Width(24).
+ Height(32).
+ Foreground(lipgloss.Color("63"))
+```
+
+## Borders
+
+Adding borders is easy:
+
+```go
+// Add a purple, rectangular border
+var style = lipgloss.NewStyle().
+ BorderStyle(lipgloss.NormalBorder()).
+ BorderForeground(lipgloss.Color("63"))
+
+// Set a rounded, yellow-on-purple border to the top and left
+var anotherStyle = lipgloss.NewStyle().
+ BorderStyle(lipgloss.RoundedBorder()).
+ BorderForeground(lipgloss.Color("228")).
+ BorderBackground(lipgloss.Color("63")).
+ BorderTop(true).
+ BorderLeft(true)
+
+// Make your own border
+var myCuteBorder = lipgloss.Border{
+ Top: "._.:*:",
+ Bottom: "._.:*:",
+ Left: "|*",
+ Right: "|*",
+ TopLeft: "*",
+ TopRight: "*",
+ BottomLeft: "*",
+ BottomRight: "*",
+}
+```
+
+There are also shorthand functions for defining borders, which follow a similar
+pattern to the margin and padding shorthand functions.
+
+```go
+// Add a thick border to the top and bottom
+lipgloss.NewStyle().
+ Border(lipgloss.ThickBorder(), true, false)
+
+// Add a double border to the top and left sides. Rules are set clockwise
+// from top.
+lipgloss.NewStyle().
+ Border(lipgloss.DoubleBorder(), true, false, false, true)
+```
+
+For more on borders see [the docs][docs].
+
+## Copying Styles
+
+Just use assignment:
+
+```go
+style := lipgloss.NewStyle().Foreground(lipgloss.Color("219"))
+
+copiedStyle := style // this is a true copy
+
+wildStyle := style.Blink(true) // this is also true copy, with blink added
+
+```
+
+Since `Style` data structures contains only primitive types, assigning a style
+to another effectively creates a new copy of the style without mutating the
+original.
+
+## Inheritance
+
+Styles can inherit rules from other styles. When inheriting, only unset rules
+on the receiver are inherited.
+
+```go
+var styleA = lipgloss.NewStyle().
+ Foreground(lipgloss.Color("229")).
+ Background(lipgloss.Color("63"))
+
+// Only the background color will be inherited here, because the foreground
+// color will have been already set:
+var styleB = lipgloss.NewStyle().
+ Foreground(lipgloss.Color("201")).
+ Inherit(styleA)
+```
+
+## Unsetting Rules
+
+All rules can be unset:
+
+```go
+var style = lipgloss.NewStyle().
+ Bold(true). // make it bold
+ UnsetBold(). // jk don't make it bold
+ Background(lipgloss.Color("227")). // yellow background
+ UnsetBackground() // never mind
+```
+
+When a rule is unset, it won't be inherited or copied.
+
+## Enforcing Rules
+
+Sometimes, such as when developing a component, you want to make sure style
+definitions respect their intended purpose in the UI. This is where `Inline`
+and `MaxWidth`, and `MaxHeight` come in:
+
+```go
+// Force rendering onto a single line, ignoring margins, padding, and borders.
+someStyle.Inline(true).Render("yadda yadda")
+
+// Also limit rendering to five cells
+someStyle.Inline(true).MaxWidth(5).Render("yadda yadda")
+
+// Limit rendering to a 5x5 cell block
+someStyle.MaxWidth(5).MaxHeight(5).Render("yadda yadda")
+```
+
+## Tabs
+
+The tab character (`\t`) is rendered differently in different terminals (often
+as 8 spaces, sometimes 4). Because of this inconsistency, Lip Gloss converts
+tabs to 4 spaces at render time. This behavior can be changed on a per-style
+basis, however:
+
+```go
+style := lipgloss.NewStyle() // tabs will render as 4 spaces, the default
+style = style.TabWidth(2) // render tabs as 2 spaces
+style = style.TabWidth(0) // remove tabs entirely
+style = style.TabWidth(lipgloss.NoTabConversion) // leave tabs intact
+```
+
+## Rendering
+
+Generally, you just call the `Render(string...)` method on a `lipgloss.Style`:
+
+```go
+style := lipgloss.NewStyle().Bold(true).SetString("Hello,")
+fmt.Println(style.Render("kitty.")) // Hello, kitty.
+fmt.Println(style.Render("puppy.")) // Hello, puppy.
+```
+
+But you could also use the Stringer interface:
+
+```go
+var style = lipgloss.NewStyle().SetString("你好,猫咪。").Bold(true)
+fmt.Println(style) // 你好,猫咪。
+```
+
+### Custom Renderers
+
+Custom renderers allow you to render to a specific outputs. This is
+particularly important when you want to render to different outputs and
+correctly detect the color profile and dark background status for each, such as
+in a server-client situation.
+
+```go
+func myLittleHandler(sess ssh.Session) {
+ // Create a renderer for the client.
+ renderer := lipgloss.NewRenderer(sess)
+
+ // Create a new style on the renderer.
+ style := renderer.NewStyle().Background(lipgloss.AdaptiveColor{Light: "63", Dark: "228"})
+
+ // Render. The color profile and dark background state will be correctly detected.
+ io.WriteString(sess, style.Render("Heyyyyyyy"))
+}
+```
+
+For an example on using a custom renderer over SSH with [Wish][wish] see the
+[SSH example][ssh-example].
+
+## Utilities
+
+In addition to pure styling, Lip Gloss also ships with some utilities to help
+assemble your layouts.
+
+### Joining Paragraphs
+
+Horizontally and vertically joining paragraphs is a cinch.
+
+```go
+// Horizontally join three paragraphs along their bottom edges
+lipgloss.JoinHorizontal(lipgloss.Bottom, paragraphA, paragraphB, paragraphC)
+
+// Vertically join two paragraphs along their center axes
+lipgloss.JoinVertical(lipgloss.Center, paragraphA, paragraphB)
+
+// Horizontally join three paragraphs, with the shorter ones aligning 20%
+// from the top of the tallest
+lipgloss.JoinHorizontal(0.2, paragraphA, paragraphB, paragraphC)
+```
+
+### Measuring Width and Height
+
+Sometimes you’ll want to know the width and height of text blocks when building
+your layouts.
+
+```go
+// Render a block of text.
+var style = lipgloss.NewStyle().
+ Width(40).
+ Padding(2)
+var block string = style.Render(someLongString)
+
+// Get the actual, physical dimensions of the text block.
+width := lipgloss.Width(block)
+height := lipgloss.Height(block)
+
+// Here's a shorthand function.
+w, h := lipgloss.Size(block)
+```
+
+### Placing Text in Whitespace
+
+Sometimes you’ll simply want to place a block of text in whitespace.
+
+```go
+// Center a paragraph horizontally in a space 80 cells wide. The height of
+// the block returned will be as tall as the input paragraph.
+block := lipgloss.PlaceHorizontal(80, lipgloss.Center, fancyStyledParagraph)
+
+// Place a paragraph at the bottom of a space 30 cells tall. The width of
+// the text block returned will be as wide as the input paragraph.
+block := lipgloss.PlaceVertical(30, lipgloss.Bottom, fancyStyledParagraph)
+
+// Place a paragraph in the bottom right corner of a 30x80 cell space.
+block := lipgloss.Place(30, 80, lipgloss.Right, lipgloss.Bottom, fancyStyledParagraph)
+```
+
+You can also style the whitespace. For details, see [the docs][docs].
+
+## Rendering Tables
+
+Lip Gloss ships with a table rendering sub-package.
+
+```go
+import "github.com/charmbracelet/lipgloss/table"
+```
+
+Define some rows of data.
+
+```go
+rows := [][]string{
+ {"Chinese", "您好", "你好"},
+ {"Japanese", "こんにちは", "やあ"},
+ {"Arabic", "أهلين", "أهلا"},
+ {"Russian", "Здравствуйте", "Привет"},
+ {"Spanish", "Hola", "¿Qué tal?"},
+}
+```
+
+Use the table package to style and render the table.
+
+```go
+t := table.New().
+ Border(lipgloss.NormalBorder()).
+ BorderStyle(lipgloss.NewStyle().Foreground(lipgloss.Color("99"))).
+ StyleFunc(func(row, col int) lipgloss.Style {
+ switch {
+ case row == 0:
+ return HeaderStyle
+ case row%2 == 0:
+ return EvenRowStyle
+ default:
+ return OddRowStyle
+ }
+ }).
+ Headers("LANGUAGE", "FORMAL", "INFORMAL").
+ Rows(rows...)
+
+// You can also add tables row-by-row
+t.Row("English", "You look absolutely fabulous.", "How's it going?")
+```
+
+Print the table.
+
+```go
+fmt.Println(t)
+```
+
+
+
+For more on tables see [the docs](https://pkg.go.dev/github.com/charmbracelet/lipgloss?tab=doc) and [examples](https://github.com/charmbracelet/lipgloss/tree/master/examples/table).
+
+## Rendering Lists
+
+Lip Gloss ships with a list rendering sub-package.
+
+```go
+import "github.com/charmbracelet/lipgloss/list"
+```
+
+Define a new list.
+
+```go
+l := list.New("A", "B", "C")
+```
+
+Print the list.
+
+```go
+fmt.Println(l)
+
+// • A
+// • B
+// • C
+```
+
+Lists have the ability to nest.
+
+```go
+l := list.New(
+ "A", list.New("Artichoke"),
+ "B", list.New("Baking Flour", "Bananas", "Barley", "Bean Sprouts"),
+ "C", list.New("Cashew Apple", "Cashews", "Coconut Milk", "Curry Paste", "Currywurst"),
+ "D", list.New("Dill", "Dragonfruit", "Dried Shrimp"),
+ "E", list.New("Eggs"),
+ "F", list.New("Fish Cake", "Furikake"),
+ "J", list.New("Jicama"),
+ "K", list.New("Kohlrabi"),
+ "L", list.New("Leeks", "Lentils", "Licorice Root"),
+)
+```
+
+Print the list.
+
+```go
+fmt.Println(l)
+```
+
+
+
+
+
+Lists can be customized via their enumeration function as well as using
+`lipgloss.Style`s.
+
+```go
+enumeratorStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("99")).MarginRight(1)
+itemStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("212")).MarginRight(1)
+
+l := list.New(
+ "Glossier",
+ "Claire’s Boutique",
+ "Nyx",
+ "Mac",
+ "Milk",
+ ).
+ Enumerator(list.Roman).
+ EnumeratorStyle(enumeratorStyle).
+ ItemStyle(itemStyle)
+```
+
+Print the list.
+
+
+
+
+
+In addition to the predefined enumerators (`Arabic`, `Alphabet`, `Roman`, `Bullet`, `Tree`),
+you may also define your own custom enumerator:
+
+```go
+l := list.New("Duck", "Duck", "Duck", "Duck", "Goose", "Duck", "Duck")
+
+func DuckDuckGooseEnumerator(l list.Items, i int) string {
+ if l.At(i).Value() == "Goose" {
+ return "Honk →"
+ }
+ return ""
+}
+
+l = l.Enumerator(DuckDuckGooseEnumerator)
+```
+
+Print the list:
+
+
+
+
+
+If you need, you can also build lists incrementally:
+
+```go
+l := list.New()
+
+for i := 0; i < repeat; i++ {
+ l.Item("Lip Gloss")
+}
+```
+
+## Rendering Trees
+
+Lip Gloss ships with a tree rendering sub-package.
+
+```go
+import "github.com/charmbracelet/lipgloss/tree"
+```
+
+Define a new tree.
+
+```go
+t := tree.Root(".").
+ Child("A", "B", "C")
+```
+
+Print the tree.
+
+```go
+fmt.Println(t)
+
+// .
+// ├── A
+// ├── B
+// └── C
+```
+
+Trees have the ability to nest.
+
+```go
+t := tree.Root(".").
+ Child("macOS").
+ Child(
+ tree.New().
+ Root("Linux").
+ Child("NixOS").
+ Child("Arch Linux (btw)").
+ Child("Void Linux"),
+ ).
+ Child(
+ tree.New().
+ Root("BSD").
+ Child("FreeBSD").
+ Child("OpenBSD"),
+ )
+```
+
+Print the tree.
+
+```go
+fmt.Println(t)
+```
+
+
+
+
+
+Trees can be customized via their enumeration function as well as using
+`lipgloss.Style`s.
+
+```go
+enumeratorStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("63")).MarginRight(1)
+rootStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("35"))
+itemStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("212"))
+
+t := tree.
+ Root("⁜ Makeup").
+ Child(
+ "Glossier",
+ "Fenty Beauty",
+ tree.New().Child(
+ "Gloss Bomb Universal Lip Luminizer",
+ "Hot Cheeks Velour Blushlighter",
+ ),
+ "Nyx",
+ "Mac",
+ "Milk",
+ ).
+ Enumerator(tree.RoundedEnumerator).
+ EnumeratorStyle(enumeratorStyle).
+ RootStyle(rootStyle).
+ ItemStyle(itemStyle)
+```
+
+Print the tree.
+
+
+
+
+
+The predefined enumerators for trees are `DefaultEnumerator` and `RoundedEnumerator`.
+
+If you need, you can also build trees incrementally:
+
+```go
+t := tree.New()
+
+for i := 0; i < repeat; i++ {
+ t.Child("Lip Gloss")
+}
+```
+
+---
+
+## FAQ
+
+
+
+Why are things misaligning? Why are borders at the wrong widths?
+
+This is most likely due to your locale and encoding, particularly with
+regard to Chinese, Japanese, and Korean (for example, zh_CN.UTF-8
+or ja_JP.UTF-8). The most direct way to fix this is to set
+RUNEWIDTH_EASTASIAN=0 in your environment.
+
+For details see https://github.com/charmbracelet/lipgloss/issues/40.
+
+
+
+
+Why isn't Lip Gloss displaying colors?
+
+Lip Gloss automatically degrades colors to the best available option in the
+given terminal, and if output's not a TTY it will remove color output entirely.
+This is common when running tests, CI, or when piping output elsewhere.
+
+If necessary, you can force a color profile in your tests with
+SetColorProfile.
+
+```go
+import (
+ "github.com/charmbracelet/lipgloss"
+ "github.com/muesli/termenv"
+)
+
+lipgloss.SetColorProfile(termenv.TrueColor)
+```
+
+_Note:_ this option limits the flexibility of your application and can cause
+ANSI escape codes to be output in cases where that might not be desired. Take
+careful note of your use case and environment before choosing to force a color
+profile.
+
+
+
+## What about [Bubble Tea][tea]?
+
+Lip Gloss doesn’t replace Bubble Tea. Rather, it is an excellent Bubble Tea
+companion. It was designed to make assembling terminal user interface views as
+simple and fun as possible so that you can focus on building your application
+instead of concerning yourself with low-level layout details.
+
+In simple terms, you can use Lip Gloss to help build your Bubble Tea views.
+
+[tea]: https://github.com/charmbracelet/tea
+
+## Under the Hood
+
+Lip Gloss is built on the excellent [Termenv][termenv] and [Reflow][reflow]
+libraries which deal with color and ANSI-aware text operations, respectively.
+For many use cases Termenv and Reflow will be sufficient for your needs.
+
+[termenv]: https://github.com/muesli/termenv
+[reflow]: https://github.com/muesli/reflow
+
+## Rendering Markdown
+
+For a more document-centric rendering solution with support for things like
+lists, tables, and syntax-highlighted code have a look at [Glamour][glamour],
+the stylesheet-based Markdown renderer.
+
+[glamour]: https://github.com/charmbracelet/glamour
+
+## Contributing
+
+See [contributing][contribute].
+
+[contribute]: https://github.com/charmbracelet/lipgloss/contribute
+
+## Feedback
+
+We’d love to hear your thoughts on this project. Feel free to drop us a note!
+
+- [Twitter](https://twitter.com/charmcli)
+- [The Fediverse](https://mastodon.social/@charmcli)
+- [Discord](https://charm.sh/chat)
+
+## License
+
+[MIT](https://github.com/charmbracelet/lipgloss/raw/master/LICENSE)
+
+---
+
+Part of [Charm](https://charm.sh).
+
+
+
+Charm热爱开源 • Charm loves open source
+
+[docs]: https://pkg.go.dev/github.com/charmbracelet/lipgloss?tab=doc
+[wish]: https://github.com/charmbracelet/wish
+[ssh-example]: examples/ssh
diff --git a/vendor/github.com/charmbracelet/lipgloss/align.go b/vendor/github.com/charmbracelet/lipgloss/align.go
new file mode 100644
index 0000000..805d1e0
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/align.go
@@ -0,0 +1,83 @@
+package lipgloss
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+ "github.com/muesli/termenv"
+)
+
+// Perform text alignment. If the string is multi-lined, we also make all lines
+// the same width by padding them with spaces. If a termenv style is passed,
+// use that to style the spaces added.
+func alignTextHorizontal(str string, pos Position, width int, style *termenv.Style) string {
+ lines, widestLine := getLines(str)
+ var b strings.Builder
+
+ for i, l := range lines {
+ lineWidth := ansi.StringWidth(l)
+
+ shortAmount := widestLine - lineWidth // difference from the widest line
+ shortAmount += max(0, width-(shortAmount+lineWidth)) // difference from the total width, if set
+
+ if shortAmount > 0 {
+ switch pos { //nolint:exhaustive
+ case Right:
+ s := strings.Repeat(" ", shortAmount)
+ if style != nil {
+ s = style.Styled(s)
+ }
+ l = s + l
+ case Center:
+ // Note: remainder goes on the right.
+ left := shortAmount / 2 //nolint:gomnd
+ right := left + shortAmount%2 //nolint:gomnd
+
+ leftSpaces := strings.Repeat(" ", left)
+ rightSpaces := strings.Repeat(" ", right)
+
+ if style != nil {
+ leftSpaces = style.Styled(leftSpaces)
+ rightSpaces = style.Styled(rightSpaces)
+ }
+ l = leftSpaces + l + rightSpaces
+ default: // Left
+ s := strings.Repeat(" ", shortAmount)
+ if style != nil {
+ s = style.Styled(s)
+ }
+ l += s
+ }
+ }
+
+ b.WriteString(l)
+ if i < len(lines)-1 {
+ b.WriteRune('\n')
+ }
+ }
+
+ return b.String()
+}
+
+func alignTextVertical(str string, pos Position, height int, _ *termenv.Style) string {
+ strHeight := strings.Count(str, "\n") + 1
+ if height < strHeight {
+ return str
+ }
+
+ switch pos {
+ case Top:
+ return str + strings.Repeat("\n", height-strHeight)
+ case Center:
+ topPadding, bottomPadding := (height-strHeight)/2, (height-strHeight)/2 //nolint:gomnd
+ if strHeight+topPadding+bottomPadding > height {
+ topPadding--
+ } else if strHeight+topPadding+bottomPadding < height {
+ bottomPadding++
+ }
+ return strings.Repeat("\n", topPadding) + str + strings.Repeat("\n", bottomPadding)
+ case Bottom:
+ return strings.Repeat("\n", height-strHeight) + str
+ }
+ return str
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/ansi_unix.go b/vendor/github.com/charmbracelet/lipgloss/ansi_unix.go
new file mode 100644
index 0000000..d416b8c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/ansi_unix.go
@@ -0,0 +1,7 @@
+//go:build !windows
+// +build !windows
+
+package lipgloss
+
+// enableLegacyWindowsANSI is only needed on Windows.
+func enableLegacyWindowsANSI() {}
diff --git a/vendor/github.com/charmbracelet/lipgloss/ansi_windows.go b/vendor/github.com/charmbracelet/lipgloss/ansi_windows.go
new file mode 100644
index 0000000..0cf56e4
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/ansi_windows.go
@@ -0,0 +1,22 @@
+//go:build windows
+// +build windows
+
+package lipgloss
+
+import (
+ "sync"
+
+ "github.com/muesli/termenv"
+)
+
+var enableANSI sync.Once
+
+// enableANSIColors enables support for ANSI color sequences in the Windows
+// default console (cmd.exe and the PowerShell application). Note that this
+// only works with Windows 10. Also note that Windows Terminal supports colors
+// by default.
+func enableLegacyWindowsANSI() {
+ enableANSI.Do(func() {
+ _, _ = termenv.EnableWindowsANSIConsole()
+ })
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/borders.go b/vendor/github.com/charmbracelet/lipgloss/borders.go
new file mode 100644
index 0000000..deb6b35
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/borders.go
@@ -0,0 +1,443 @@
+package lipgloss
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+ "github.com/muesli/termenv"
+ "github.com/rivo/uniseg"
+)
+
+// Border contains a series of values which comprise the various parts of a
+// border.
+type Border struct {
+ Top string
+ Bottom string
+ Left string
+ Right string
+ TopLeft string
+ TopRight string
+ BottomLeft string
+ BottomRight string
+ MiddleLeft string
+ MiddleRight string
+ Middle string
+ MiddleTop string
+ MiddleBottom string
+}
+
+// GetTopSize returns the width of the top border. If borders contain runes of
+// varying widths, the widest rune is returned. If no border exists on the top
+// edge, 0 is returned.
+func (b Border) GetTopSize() int {
+ return getBorderEdgeWidth(b.TopLeft, b.Top, b.TopRight)
+}
+
+// GetRightSize returns the width of the right border. If borders contain
+// runes of varying widths, the widest rune is returned. If no border exists on
+// the right edge, 0 is returned.
+func (b Border) GetRightSize() int {
+ return getBorderEdgeWidth(b.TopRight, b.Right, b.BottomRight)
+}
+
+// GetBottomSize returns the width of the bottom border. If borders contain
+// runes of varying widths, the widest rune is returned. If no border exists on
+// the bottom edge, 0 is returned.
+func (b Border) GetBottomSize() int {
+ return getBorderEdgeWidth(b.BottomLeft, b.Bottom, b.BottomRight)
+}
+
+// GetLeftSize returns the width of the left border. If borders contain runes
+// of varying widths, the widest rune is returned. If no border exists on the
+// left edge, 0 is returned.
+func (b Border) GetLeftSize() int {
+ return getBorderEdgeWidth(b.TopLeft, b.Left, b.BottomLeft)
+}
+
+func getBorderEdgeWidth(borderParts ...string) (maxWidth int) {
+ for _, piece := range borderParts {
+ w := maxRuneWidth(piece)
+ if w > maxWidth {
+ maxWidth = w
+ }
+ }
+ return maxWidth
+}
+
+var (
+ noBorder = Border{}
+
+ normalBorder = Border{
+ Top: "─",
+ Bottom: "─",
+ Left: "│",
+ Right: "│",
+ TopLeft: "┌",
+ TopRight: "┐",
+ BottomLeft: "└",
+ BottomRight: "┘",
+ MiddleLeft: "├",
+ MiddleRight: "┤",
+ Middle: "┼",
+ MiddleTop: "┬",
+ MiddleBottom: "┴",
+ }
+
+ roundedBorder = Border{
+ Top: "─",
+ Bottom: "─",
+ Left: "│",
+ Right: "│",
+ TopLeft: "╭",
+ TopRight: "╮",
+ BottomLeft: "╰",
+ BottomRight: "╯",
+ MiddleLeft: "├",
+ MiddleRight: "┤",
+ Middle: "┼",
+ MiddleTop: "┬",
+ MiddleBottom: "┴",
+ }
+
+ blockBorder = Border{
+ Top: "█",
+ Bottom: "█",
+ Left: "█",
+ Right: "█",
+ TopLeft: "█",
+ TopRight: "█",
+ BottomLeft: "█",
+ BottomRight: "█",
+ }
+
+ outerHalfBlockBorder = Border{
+ Top: "▀",
+ Bottom: "▄",
+ Left: "▌",
+ Right: "▐",
+ TopLeft: "▛",
+ TopRight: "▜",
+ BottomLeft: "▙",
+ BottomRight: "▟",
+ }
+
+ innerHalfBlockBorder = Border{
+ Top: "▄",
+ Bottom: "▀",
+ Left: "▐",
+ Right: "▌",
+ TopLeft: "▗",
+ TopRight: "▖",
+ BottomLeft: "▝",
+ BottomRight: "▘",
+ }
+
+ thickBorder = Border{
+ Top: "━",
+ Bottom: "━",
+ Left: "┃",
+ Right: "┃",
+ TopLeft: "┏",
+ TopRight: "┓",
+ BottomLeft: "┗",
+ BottomRight: "┛",
+ MiddleLeft: "┣",
+ MiddleRight: "┫",
+ Middle: "╋",
+ MiddleTop: "┳",
+ MiddleBottom: "┻",
+ }
+
+ doubleBorder = Border{
+ Top: "═",
+ Bottom: "═",
+ Left: "║",
+ Right: "║",
+ TopLeft: "╔",
+ TopRight: "╗",
+ BottomLeft: "╚",
+ BottomRight: "╝",
+ MiddleLeft: "╠",
+ MiddleRight: "╣",
+ Middle: "╬",
+ MiddleTop: "╦",
+ MiddleBottom: "╩",
+ }
+
+ hiddenBorder = Border{
+ Top: " ",
+ Bottom: " ",
+ Left: " ",
+ Right: " ",
+ TopLeft: " ",
+ TopRight: " ",
+ BottomLeft: " ",
+ BottomRight: " ",
+ MiddleLeft: " ",
+ MiddleRight: " ",
+ Middle: " ",
+ MiddleTop: " ",
+ MiddleBottom: " ",
+ }
+)
+
+// NormalBorder returns a standard-type border with a normal weight and 90
+// degree corners.
+func NormalBorder() Border {
+ return normalBorder
+}
+
+// RoundedBorder returns a border with rounded corners.
+func RoundedBorder() Border {
+ return roundedBorder
+}
+
+// BlockBorder returns a border that takes the whole block.
+func BlockBorder() Border {
+ return blockBorder
+}
+
+// OuterHalfBlockBorder returns a half-block border that sits outside the frame.
+func OuterHalfBlockBorder() Border {
+ return outerHalfBlockBorder
+}
+
+// InnerHalfBlockBorder returns a half-block border that sits inside the frame.
+func InnerHalfBlockBorder() Border {
+ return innerHalfBlockBorder
+}
+
+// ThickBorder returns a border that's thicker than the one returned by
+// NormalBorder.
+func ThickBorder() Border {
+ return thickBorder
+}
+
+// DoubleBorder returns a border comprised of two thin strokes.
+func DoubleBorder() Border {
+ return doubleBorder
+}
+
+// HiddenBorder returns a border that renders as a series of single-cell
+// spaces. It's useful for cases when you want to remove a standard border but
+// maintain layout positioning. This said, you can still apply a background
+// color to a hidden border.
+func HiddenBorder() Border {
+ return hiddenBorder
+}
+
+func (s Style) applyBorder(str string) string {
+ var (
+ topSet = s.isSet(borderTopKey)
+ rightSet = s.isSet(borderRightKey)
+ bottomSet = s.isSet(borderBottomKey)
+ leftSet = s.isSet(borderLeftKey)
+
+ border = s.getBorderStyle()
+ hasTop = s.getAsBool(borderTopKey, false)
+ hasRight = s.getAsBool(borderRightKey, false)
+ hasBottom = s.getAsBool(borderBottomKey, false)
+ hasLeft = s.getAsBool(borderLeftKey, false)
+
+ topFG = s.getAsColor(borderTopForegroundKey)
+ rightFG = s.getAsColor(borderRightForegroundKey)
+ bottomFG = s.getAsColor(borderBottomForegroundKey)
+ leftFG = s.getAsColor(borderLeftForegroundKey)
+
+ topBG = s.getAsColor(borderTopBackgroundKey)
+ rightBG = s.getAsColor(borderRightBackgroundKey)
+ bottomBG = s.getAsColor(borderBottomBackgroundKey)
+ leftBG = s.getAsColor(borderLeftBackgroundKey)
+ )
+
+ // If a border is set and no sides have been specifically turned on or off
+ // render borders on all sides.
+ if border != noBorder && !(topSet || rightSet || bottomSet || leftSet) {
+ hasTop = true
+ hasRight = true
+ hasBottom = true
+ hasLeft = true
+ }
+
+ // If no border is set or all borders are been disabled, abort.
+ if border == noBorder || (!hasTop && !hasRight && !hasBottom && !hasLeft) {
+ return str
+ }
+
+ lines, width := getLines(str)
+
+ if hasLeft {
+ if border.Left == "" {
+ border.Left = " "
+ }
+ width += maxRuneWidth(border.Left)
+ }
+
+ if hasRight && border.Right == "" {
+ border.Right = " "
+ }
+
+ // If corners should be rendered but are set with the empty string, fill them
+ // with a single space.
+ if hasTop && hasLeft && border.TopLeft == "" {
+ border.TopLeft = " "
+ }
+ if hasTop && hasRight && border.TopRight == "" {
+ border.TopRight = " "
+ }
+ if hasBottom && hasLeft && border.BottomLeft == "" {
+ border.BottomLeft = " "
+ }
+ if hasBottom && hasRight && border.BottomRight == "" {
+ border.BottomRight = " "
+ }
+
+ // Figure out which corners we should actually be using based on which
+ // sides are set to show.
+ if hasTop {
+ switch {
+ case !hasLeft && !hasRight:
+ border.TopLeft = ""
+ border.TopRight = ""
+ case !hasLeft:
+ border.TopLeft = ""
+ case !hasRight:
+ border.TopRight = ""
+ }
+ }
+ if hasBottom {
+ switch {
+ case !hasLeft && !hasRight:
+ border.BottomLeft = ""
+ border.BottomRight = ""
+ case !hasLeft:
+ border.BottomLeft = ""
+ case !hasRight:
+ border.BottomRight = ""
+ }
+ }
+
+ // For now, limit corners to one rune.
+ border.TopLeft = getFirstRuneAsString(border.TopLeft)
+ border.TopRight = getFirstRuneAsString(border.TopRight)
+ border.BottomRight = getFirstRuneAsString(border.BottomRight)
+ border.BottomLeft = getFirstRuneAsString(border.BottomLeft)
+
+ var out strings.Builder
+
+ // Render top
+ if hasTop {
+ top := renderHorizontalEdge(border.TopLeft, border.Top, border.TopRight, width)
+ top = s.styleBorder(top, topFG, topBG)
+ out.WriteString(top)
+ out.WriteRune('\n')
+ }
+
+ leftRunes := []rune(border.Left)
+ leftIndex := 0
+
+ rightRunes := []rune(border.Right)
+ rightIndex := 0
+
+ // Render sides
+ for i, l := range lines {
+ if hasLeft {
+ r := string(leftRunes[leftIndex])
+ leftIndex++
+ if leftIndex >= len(leftRunes) {
+ leftIndex = 0
+ }
+ out.WriteString(s.styleBorder(r, leftFG, leftBG))
+ }
+ out.WriteString(l)
+ if hasRight {
+ r := string(rightRunes[rightIndex])
+ rightIndex++
+ if rightIndex >= len(rightRunes) {
+ rightIndex = 0
+ }
+ out.WriteString(s.styleBorder(r, rightFG, rightBG))
+ }
+ if i < len(lines)-1 {
+ out.WriteRune('\n')
+ }
+ }
+
+ // Render bottom
+ if hasBottom {
+ bottom := renderHorizontalEdge(border.BottomLeft, border.Bottom, border.BottomRight, width)
+ bottom = s.styleBorder(bottom, bottomFG, bottomBG)
+ out.WriteRune('\n')
+ out.WriteString(bottom)
+ }
+
+ return out.String()
+}
+
+// Render the horizontal (top or bottom) portion of a border.
+func renderHorizontalEdge(left, middle, right string, width int) string {
+ if middle == "" {
+ middle = " "
+ }
+
+ leftWidth := ansi.StringWidth(left)
+ rightWidth := ansi.StringWidth(right)
+
+ runes := []rune(middle)
+ j := 0
+
+ out := strings.Builder{}
+ out.WriteString(left)
+ for i := leftWidth + rightWidth; i < width+rightWidth; {
+ out.WriteRune(runes[j])
+ j++
+ if j >= len(runes) {
+ j = 0
+ }
+ i += ansi.StringWidth(string(runes[j]))
+ }
+ out.WriteString(right)
+
+ return out.String()
+}
+
+// Apply foreground and background styling to a border.
+func (s Style) styleBorder(border string, fg, bg TerminalColor) string {
+ if fg == noColor && bg == noColor {
+ return border
+ }
+
+ style := termenv.Style{}
+
+ if fg != noColor {
+ style = style.Foreground(fg.color(s.r))
+ }
+ if bg != noColor {
+ style = style.Background(bg.color(s.r))
+ }
+
+ return style.Styled(border)
+}
+
+func maxRuneWidth(str string) int {
+ var width int
+
+ state := -1
+ for len(str) > 0 {
+ var w int
+ _, str, w, state = uniseg.FirstGraphemeClusterInString(str, state)
+ if w > width {
+ width = w
+ }
+ }
+
+ return width
+}
+
+func getFirstRuneAsString(str string) string {
+ if str == "" {
+ return str
+ }
+ r := []rune(str)
+ return string(r[0])
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/color.go b/vendor/github.com/charmbracelet/lipgloss/color.go
new file mode 100644
index 0000000..5dfb3cf
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/color.go
@@ -0,0 +1,172 @@
+package lipgloss
+
+import (
+ "strconv"
+
+ "github.com/muesli/termenv"
+)
+
+// TerminalColor is a color intended to be rendered in the terminal.
+type TerminalColor interface {
+ color(*Renderer) termenv.Color
+ RGBA() (r, g, b, a uint32)
+}
+
+var noColor = NoColor{}
+
+// NoColor is used to specify the absence of color styling. When this is active
+// foreground colors will be rendered with the terminal's default text color,
+// and background colors will not be drawn at all.
+//
+// Example usage:
+//
+// var style = someStyle.Background(lipgloss.NoColor{})
+type NoColor struct{}
+
+func (NoColor) color(*Renderer) termenv.Color {
+ return termenv.NoColor{}
+}
+
+// RGBA returns the RGBA value of this color. Because we have to return
+// something, despite this color being the absence of color, we're returning
+// black with 100% opacity.
+//
+// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF.
+//
+// Deprecated.
+func (n NoColor) RGBA() (r, g, b, a uint32) {
+ return 0x0, 0x0, 0x0, 0xFFFF //nolint:gomnd
+}
+
+// Color specifies a color by hex or ANSI value. For example:
+//
+// ansiColor := lipgloss.Color("21")
+// hexColor := lipgloss.Color("#0000ff")
+type Color string
+
+func (c Color) color(r *Renderer) termenv.Color {
+ return r.ColorProfile().Color(string(c))
+}
+
+// RGBA returns the RGBA value of this color. This satisfies the Go Color
+// interface. Note that on error we return black with 100% opacity, or:
+//
+// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF.
+//
+// Deprecated.
+func (c Color) RGBA() (r, g, b, a uint32) {
+ return termenv.ConvertToRGB(c.color(renderer)).RGBA()
+}
+
+// ANSIColor is a color specified by an ANSI color value. It's merely syntactic
+// sugar for the more general Color function. Invalid colors will render as
+// black.
+//
+// Example usage:
+//
+// // These two statements are equivalent.
+// colorA := lipgloss.ANSIColor(21)
+// colorB := lipgloss.Color("21")
+type ANSIColor uint
+
+func (ac ANSIColor) color(r *Renderer) termenv.Color {
+ return Color(strconv.FormatUint(uint64(ac), 10)).color(r)
+}
+
+// RGBA returns the RGBA value of this color. This satisfies the Go Color
+// interface. Note that on error we return black with 100% opacity, or:
+//
+// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF.
+//
+// Deprecated.
+func (ac ANSIColor) RGBA() (r, g, b, a uint32) {
+ cf := Color(strconv.FormatUint(uint64(ac), 10))
+ return cf.RGBA()
+}
+
+// AdaptiveColor provides color options for light and dark backgrounds. The
+// appropriate color will be returned at runtime based on the darkness of the
+// terminal background color.
+//
+// Example usage:
+//
+// color := lipgloss.AdaptiveColor{Light: "#0000ff", Dark: "#000099"}
+type AdaptiveColor struct {
+ Light string
+ Dark string
+}
+
+func (ac AdaptiveColor) color(r *Renderer) termenv.Color {
+ if r.HasDarkBackground() {
+ return Color(ac.Dark).color(r)
+ }
+ return Color(ac.Light).color(r)
+}
+
+// RGBA returns the RGBA value of this color. This satisfies the Go Color
+// interface. Note that on error we return black with 100% opacity, or:
+//
+// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF.
+//
+// Deprecated.
+func (ac AdaptiveColor) RGBA() (r, g, b, a uint32) {
+ return termenv.ConvertToRGB(ac.color(renderer)).RGBA()
+}
+
+// CompleteColor specifies exact values for truecolor, ANSI256, and ANSI color
+// profiles. Automatic color degradation will not be performed.
+type CompleteColor struct {
+ TrueColor string
+ ANSI256 string
+ ANSI string
+}
+
+func (c CompleteColor) color(r *Renderer) termenv.Color {
+ p := r.ColorProfile()
+ switch p { //nolint:exhaustive
+ case termenv.TrueColor:
+ return p.Color(c.TrueColor)
+ case termenv.ANSI256:
+ return p.Color(c.ANSI256)
+ case termenv.ANSI:
+ return p.Color(c.ANSI)
+ default:
+ return termenv.NoColor{}
+ }
+}
+
+// RGBA returns the RGBA value of this color. This satisfies the Go Color
+// interface. Note that on error we return black with 100% opacity, or:
+//
+// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF.
+// CompleteAdaptiveColor specifies exact values for truecolor, ANSI256, and ANSI color
+//
+// Deprecated.
+func (c CompleteColor) RGBA() (r, g, b, a uint32) {
+ return termenv.ConvertToRGB(c.color(renderer)).RGBA()
+}
+
+// CompleteAdaptiveColor specifies exact values for truecolor, ANSI256, and ANSI color
+// profiles, with separate options for light and dark backgrounds. Automatic
+// color degradation will not be performed.
+type CompleteAdaptiveColor struct {
+ Light CompleteColor
+ Dark CompleteColor
+}
+
+func (cac CompleteAdaptiveColor) color(r *Renderer) termenv.Color {
+ if r.HasDarkBackground() {
+ return cac.Dark.color(r)
+ }
+ return cac.Light.color(r)
+}
+
+// RGBA returns the RGBA value of this color. This satisfies the Go Color
+// interface. Note that on error we return black with 100% opacity, or:
+//
+// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF.
+//
+// Deprecated.
+func (cac CompleteAdaptiveColor) RGBA() (r, g, b, a uint32) {
+ return termenv.ConvertToRGB(cac.color(renderer)).RGBA()
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/get.go b/vendor/github.com/charmbracelet/lipgloss/get.go
new file mode 100644
index 0000000..9c2f06f
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/get.go
@@ -0,0 +1,542 @@
+package lipgloss
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+// GetBold returns the style's bold value. If no value is set false is returned.
+func (s Style) GetBold() bool {
+ return s.getAsBool(boldKey, false)
+}
+
+// GetItalic returns the style's italic value. If no value is set false is
+// returned.
+func (s Style) GetItalic() bool {
+ return s.getAsBool(italicKey, false)
+}
+
+// GetUnderline returns the style's underline value. If no value is set false is
+// returned.
+func (s Style) GetUnderline() bool {
+ return s.getAsBool(underlineKey, false)
+}
+
+// GetStrikethrough returns the style's strikethrough value. If no value is set false
+// is returned.
+func (s Style) GetStrikethrough() bool {
+ return s.getAsBool(strikethroughKey, false)
+}
+
+// GetReverse returns the style's reverse value. If no value is set false is
+// returned.
+func (s Style) GetReverse() bool {
+ return s.getAsBool(reverseKey, false)
+}
+
+// GetBlink returns the style's blink value. If no value is set false is
+// returned.
+func (s Style) GetBlink() bool {
+ return s.getAsBool(blinkKey, false)
+}
+
+// GetFaint returns the style's faint value. If no value is set false is
+// returned.
+func (s Style) GetFaint() bool {
+ return s.getAsBool(faintKey, false)
+}
+
+// GetForeground returns the style's foreground color. If no value is set
+// NoColor{} is returned.
+func (s Style) GetForeground() TerminalColor {
+ return s.getAsColor(foregroundKey)
+}
+
+// GetBackground returns the style's background color. If no value is set
+// NoColor{} is returned.
+func (s Style) GetBackground() TerminalColor {
+ return s.getAsColor(backgroundKey)
+}
+
+// GetWidth returns the style's width setting. If no width is set 0 is
+// returned.
+func (s Style) GetWidth() int {
+ return s.getAsInt(widthKey)
+}
+
+// GetHeight returns the style's height setting. If no height is set 0 is
+// returned.
+func (s Style) GetHeight() int {
+ return s.getAsInt(heightKey)
+}
+
+// GetAlign returns the style's implicit horizontal alignment setting.
+// If no alignment is set Position.Left is returned.
+func (s Style) GetAlign() Position {
+ v := s.getAsPosition(alignHorizontalKey)
+ if v == Position(0) {
+ return Left
+ }
+ return v
+}
+
+// GetAlignHorizontal returns the style's implicit horizontal alignment setting.
+// If no alignment is set Position.Left is returned.
+func (s Style) GetAlignHorizontal() Position {
+ v := s.getAsPosition(alignHorizontalKey)
+ if v == Position(0) {
+ return Left
+ }
+ return v
+}
+
+// GetAlignVertical returns the style's implicit vertical alignment setting.
+// If no alignment is set Position.Top is returned.
+func (s Style) GetAlignVertical() Position {
+ v := s.getAsPosition(alignVerticalKey)
+ if v == Position(0) {
+ return Top
+ }
+ return v
+}
+
+// GetPadding returns the style's top, right, bottom, and left padding values,
+// in that order. 0 is returned for unset values.
+func (s Style) GetPadding() (top, right, bottom, left int) {
+ return s.getAsInt(paddingTopKey),
+ s.getAsInt(paddingRightKey),
+ s.getAsInt(paddingBottomKey),
+ s.getAsInt(paddingLeftKey)
+}
+
+// GetPaddingTop returns the style's top padding. If no value is set 0 is
+// returned.
+func (s Style) GetPaddingTop() int {
+ return s.getAsInt(paddingTopKey)
+}
+
+// GetPaddingRight returns the style's right padding. If no value is set 0 is
+// returned.
+func (s Style) GetPaddingRight() int {
+ return s.getAsInt(paddingRightKey)
+}
+
+// GetPaddingBottom returns the style's bottom padding. If no value is set 0 is
+// returned.
+func (s Style) GetPaddingBottom() int {
+ return s.getAsInt(paddingBottomKey)
+}
+
+// GetPaddingLeft returns the style's left padding. If no value is set 0 is
+// returned.
+func (s Style) GetPaddingLeft() int {
+ return s.getAsInt(paddingLeftKey)
+}
+
+// GetHorizontalPadding returns the style's left and right padding. Unset
+// values are measured as 0.
+func (s Style) GetHorizontalPadding() int {
+ return s.getAsInt(paddingLeftKey) + s.getAsInt(paddingRightKey)
+}
+
+// GetVerticalPadding returns the style's top and bottom padding. Unset values
+// are measured as 0.
+func (s Style) GetVerticalPadding() int {
+ return s.getAsInt(paddingTopKey) + s.getAsInt(paddingBottomKey)
+}
+
+// GetColorWhitespace returns the style's whitespace coloring setting. If no
+// value is set false is returned.
+func (s Style) GetColorWhitespace() bool {
+ return s.getAsBool(colorWhitespaceKey, false)
+}
+
+// GetMargin returns the style's top, right, bottom, and left margins, in that
+// order. 0 is returned for unset values.
+func (s Style) GetMargin() (top, right, bottom, left int) {
+ return s.getAsInt(marginTopKey),
+ s.getAsInt(marginRightKey),
+ s.getAsInt(marginBottomKey),
+ s.getAsInt(marginLeftKey)
+}
+
+// GetMarginTop returns the style's top margin. If no value is set 0 is
+// returned.
+func (s Style) GetMarginTop() int {
+ return s.getAsInt(marginTopKey)
+}
+
+// GetMarginRight returns the style's right margin. If no value is set 0 is
+// returned.
+func (s Style) GetMarginRight() int {
+ return s.getAsInt(marginRightKey)
+}
+
+// GetMarginBottom returns the style's bottom margin. If no value is set 0 is
+// returned.
+func (s Style) GetMarginBottom() int {
+ return s.getAsInt(marginBottomKey)
+}
+
+// GetMarginLeft returns the style's left margin. If no value is set 0 is
+// returned.
+func (s Style) GetMarginLeft() int {
+ return s.getAsInt(marginLeftKey)
+}
+
+// GetHorizontalMargins returns the style's left and right margins. Unset
+// values are measured as 0.
+func (s Style) GetHorizontalMargins() int {
+ return s.getAsInt(marginLeftKey) + s.getAsInt(marginRightKey)
+}
+
+// GetVerticalMargins returns the style's top and bottom margins. Unset values
+// are measured as 0.
+func (s Style) GetVerticalMargins() int {
+ return s.getAsInt(marginTopKey) + s.getAsInt(marginBottomKey)
+}
+
+// GetBorder returns the style's border style (type Border) and value for the
+// top, right, bottom, and left in that order. If no value is set for the
+// border style, Border{} is returned. For all other unset values false is
+// returned.
+func (s Style) GetBorder() (b Border, top, right, bottom, left bool) {
+ return s.getBorderStyle(),
+ s.getAsBool(borderTopKey, false),
+ s.getAsBool(borderRightKey, false),
+ s.getAsBool(borderBottomKey, false),
+ s.getAsBool(borderLeftKey, false)
+}
+
+// GetBorderStyle returns the style's border style (type Border). If no value
+// is set Border{} is returned.
+func (s Style) GetBorderStyle() Border {
+ return s.getBorderStyle()
+}
+
+// GetBorderTop returns the style's top border setting. If no value is set
+// false is returned.
+func (s Style) GetBorderTop() bool {
+ return s.getAsBool(borderTopKey, false)
+}
+
+// GetBorderRight returns the style's right border setting. If no value is set
+// false is returned.
+func (s Style) GetBorderRight() bool {
+ return s.getAsBool(borderRightKey, false)
+}
+
+// GetBorderBottom returns the style's bottom border setting. If no value is
+// set false is returned.
+func (s Style) GetBorderBottom() bool {
+ return s.getAsBool(borderBottomKey, false)
+}
+
+// GetBorderLeft returns the style's left border setting. If no value is
+// set false is returned.
+func (s Style) GetBorderLeft() bool {
+ return s.getAsBool(borderLeftKey, false)
+}
+
+// GetBorderTopForeground returns the style's border top foreground color. If
+// no value is set NoColor{} is returned.
+func (s Style) GetBorderTopForeground() TerminalColor {
+ return s.getAsColor(borderTopForegroundKey)
+}
+
+// GetBorderRightForeground returns the style's border right foreground color.
+// If no value is set NoColor{} is returned.
+func (s Style) GetBorderRightForeground() TerminalColor {
+ return s.getAsColor(borderRightForegroundKey)
+}
+
+// GetBorderBottomForeground returns the style's border bottom foreground
+// color. If no value is set NoColor{} is returned.
+func (s Style) GetBorderBottomForeground() TerminalColor {
+ return s.getAsColor(borderBottomForegroundKey)
+}
+
+// GetBorderLeftForeground returns the style's border left foreground
+// color. If no value is set NoColor{} is returned.
+func (s Style) GetBorderLeftForeground() TerminalColor {
+ return s.getAsColor(borderLeftForegroundKey)
+}
+
+// GetBorderTopBackground returns the style's border top background color. If
+// no value is set NoColor{} is returned.
+func (s Style) GetBorderTopBackground() TerminalColor {
+ return s.getAsColor(borderTopBackgroundKey)
+}
+
+// GetBorderRightBackground returns the style's border right background color.
+// If no value is set NoColor{} is returned.
+func (s Style) GetBorderRightBackground() TerminalColor {
+ return s.getAsColor(borderRightBackgroundKey)
+}
+
+// GetBorderBottomBackground returns the style's border bottom background
+// color. If no value is set NoColor{} is returned.
+func (s Style) GetBorderBottomBackground() TerminalColor {
+ return s.getAsColor(borderBottomBackgroundKey)
+}
+
+// GetBorderLeftBackground returns the style's border left background
+// color. If no value is set NoColor{} is returned.
+func (s Style) GetBorderLeftBackground() TerminalColor {
+ return s.getAsColor(borderLeftBackgroundKey)
+}
+
+// GetBorderTopWidth returns the width of the top border. If borders contain
+// runes of varying widths, the widest rune is returned. If no border exists on
+// the top edge, 0 is returned.
+//
+// Deprecated: This function simply calls Style.GetBorderTopSize.
+func (s Style) GetBorderTopWidth() int {
+ return s.GetBorderTopSize()
+}
+
+// GetBorderTopSize returns the width of the top border. If borders contain
+// runes of varying widths, the widest rune is returned. If no border exists on
+// the top edge, 0 is returned.
+func (s Style) GetBorderTopSize() int {
+ if !s.getAsBool(borderTopKey, false) {
+ return 0
+ }
+ return s.getBorderStyle().GetTopSize()
+}
+
+// GetBorderLeftSize returns the width of the left border. If borders contain
+// runes of varying widths, the widest rune is returned. If no border exists on
+// the left edge, 0 is returned.
+func (s Style) GetBorderLeftSize() int {
+ if !s.getAsBool(borderLeftKey, false) {
+ return 0
+ }
+ return s.getBorderStyle().GetLeftSize()
+}
+
+// GetBorderBottomSize returns the width of the bottom border. If borders
+// contain runes of varying widths, the widest rune is returned. If no border
+// exists on the left edge, 0 is returned.
+func (s Style) GetBorderBottomSize() int {
+ if !s.getAsBool(borderBottomKey, false) {
+ return 0
+ }
+ return s.getBorderStyle().GetBottomSize()
+}
+
+// GetBorderRightSize returns the width of the right border. If borders
+// contain runes of varying widths, the widest rune is returned. If no border
+// exists on the right edge, 0 is returned.
+func (s Style) GetBorderRightSize() int {
+ if !s.getAsBool(borderRightKey, false) {
+ return 0
+ }
+ return s.getBorderStyle().GetRightSize()
+}
+
+// GetHorizontalBorderSize returns the width of the horizontal borders. If
+// borders contain runes of varying widths, the widest rune is returned. If no
+// border exists on the horizontal edges, 0 is returned.
+func (s Style) GetHorizontalBorderSize() int {
+ return s.GetBorderLeftSize() + s.GetBorderRightSize()
+}
+
+// GetVerticalBorderSize returns the width of the vertical borders. If
+// borders contain runes of varying widths, the widest rune is returned. If no
+// border exists on the vertical edges, 0 is returned.
+func (s Style) GetVerticalBorderSize() int {
+ return s.GetBorderTopSize() + s.GetBorderBottomSize()
+}
+
+// GetInline returns the style's inline setting. If no value is set false is
+// returned.
+func (s Style) GetInline() bool {
+ return s.getAsBool(inlineKey, false)
+}
+
+// GetMaxWidth returns the style's max width setting. If no value is set 0 is
+// returned.
+func (s Style) GetMaxWidth() int {
+ return s.getAsInt(maxWidthKey)
+}
+
+// GetMaxHeight returns the style's max height setting. If no value is set 0 is
+// returned.
+func (s Style) GetMaxHeight() int {
+ return s.getAsInt(maxHeightKey)
+}
+
+// GetTabWidth returns the style's tab width setting. If no value is set 4 is
+// returned which is the implicit default.
+func (s Style) GetTabWidth() int {
+ return s.getAsInt(tabWidthKey)
+}
+
+// GetUnderlineSpaces returns whether or not the style is set to underline
+// spaces. If not value is set false is returned.
+func (s Style) GetUnderlineSpaces() bool {
+ return s.getAsBool(underlineSpacesKey, false)
+}
+
+// GetStrikethroughSpaces returns whether or not the style is set to strikethrough
+// spaces. If not value is set false is returned.
+func (s Style) GetStrikethroughSpaces() bool {
+ return s.getAsBool(strikethroughSpacesKey, false)
+}
+
+// GetHorizontalFrameSize returns the sum of the style's horizontal margins, padding
+// and border widths.
+//
+// Provisional: this method may be renamed.
+func (s Style) GetHorizontalFrameSize() int {
+ return s.GetHorizontalMargins() + s.GetHorizontalPadding() + s.GetHorizontalBorderSize()
+}
+
+// GetVerticalFrameSize returns the sum of the style's vertical margins, padding
+// and border widths.
+//
+// Provisional: this method may be renamed.
+func (s Style) GetVerticalFrameSize() int {
+ return s.GetVerticalMargins() + s.GetVerticalPadding() + s.GetVerticalBorderSize()
+}
+
+// GetFrameSize returns the sum of the margins, padding and border width for
+// both the horizontal and vertical margins.
+func (s Style) GetFrameSize() (x, y int) {
+ return s.GetHorizontalFrameSize(), s.GetVerticalFrameSize()
+}
+
+// GetTransform returns the transform set on the style. If no transform is set
+// nil is returned.
+func (s Style) GetTransform() func(string) string {
+ return s.getAsTransform(transformKey)
+}
+
+// Returns whether or not the given property is set.
+func (s Style) isSet(k propKey) bool {
+ return s.props.has(k)
+}
+
+func (s Style) getAsBool(k propKey, defaultVal bool) bool {
+ if !s.isSet(k) {
+ return defaultVal
+ }
+ return s.attrs&int(k) != 0
+}
+
+func (s Style) getAsColor(k propKey) TerminalColor {
+ if !s.isSet(k) {
+ return noColor
+ }
+
+ var c TerminalColor
+ switch k { //nolint:exhaustive
+ case foregroundKey:
+ c = s.fgColor
+ case backgroundKey:
+ c = s.bgColor
+ case marginBackgroundKey:
+ c = s.marginBgColor
+ case borderTopForegroundKey:
+ c = s.borderTopFgColor
+ case borderRightForegroundKey:
+ c = s.borderRightFgColor
+ case borderBottomForegroundKey:
+ c = s.borderBottomFgColor
+ case borderLeftForegroundKey:
+ c = s.borderLeftFgColor
+ case borderTopBackgroundKey:
+ c = s.borderTopBgColor
+ case borderRightBackgroundKey:
+ c = s.borderRightBgColor
+ case borderBottomBackgroundKey:
+ c = s.borderBottomBgColor
+ case borderLeftBackgroundKey:
+ c = s.borderLeftBgColor
+ }
+
+ if c != nil {
+ return c
+ }
+
+ return noColor
+}
+
+func (s Style) getAsInt(k propKey) int {
+ if !s.isSet(k) {
+ return 0
+ }
+ switch k { //nolint:exhaustive
+ case widthKey:
+ return s.width
+ case heightKey:
+ return s.height
+ case paddingTopKey:
+ return s.paddingTop
+ case paddingRightKey:
+ return s.paddingRight
+ case paddingBottomKey:
+ return s.paddingBottom
+ case paddingLeftKey:
+ return s.paddingLeft
+ case marginTopKey:
+ return s.marginTop
+ case marginRightKey:
+ return s.marginRight
+ case marginBottomKey:
+ return s.marginBottom
+ case marginLeftKey:
+ return s.marginLeft
+ case maxWidthKey:
+ return s.maxWidth
+ case maxHeightKey:
+ return s.maxHeight
+ case tabWidthKey:
+ return s.tabWidth
+ }
+ return 0
+}
+
+func (s Style) getAsPosition(k propKey) Position {
+ if !s.isSet(k) {
+ return Position(0)
+ }
+ switch k { //nolint:exhaustive
+ case alignHorizontalKey:
+ return s.alignHorizontal
+ case alignVerticalKey:
+ return s.alignVertical
+ }
+ return Position(0)
+}
+
+func (s Style) getBorderStyle() Border {
+ if !s.isSet(borderStyleKey) {
+ return noBorder
+ }
+ return s.borderStyle
+}
+
+func (s Style) getAsTransform(propKey) func(string) string {
+ if !s.isSet(transformKey) {
+ return nil
+ }
+ return s.transform
+}
+
+// Split a string into lines, additionally returning the size of the widest
+// line.
+func getLines(s string) (lines []string, widest int) {
+ lines = strings.Split(s, "\n")
+
+ for _, l := range lines {
+ w := ansi.StringWidth(l)
+ if widest < w {
+ widest = w
+ }
+ }
+
+ return lines, widest
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/join.go b/vendor/github.com/charmbracelet/lipgloss/join.go
new file mode 100644
index 0000000..b0a23a5
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/join.go
@@ -0,0 +1,175 @@
+package lipgloss
+
+import (
+ "math"
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+// JoinHorizontal is a utility function for horizontally joining two
+// potentially multi-lined strings along a vertical axis. The first argument is
+// the position, with 0 being all the way at the top and 1 being all the way
+// at the bottom.
+//
+// If you just want to align to the top, center or bottom you may as well just
+// use the helper constants Top, Center, and Bottom.
+//
+// Example:
+//
+// blockB := "...\n...\n..."
+// blockA := "...\n...\n...\n...\n..."
+//
+// // Join 20% from the top
+// str := lipgloss.JoinHorizontal(0.2, blockA, blockB)
+//
+// // Join on the top edge
+// str := lipgloss.JoinHorizontal(lipgloss.Top, blockA, blockB)
+func JoinHorizontal(pos Position, strs ...string) string {
+ if len(strs) == 0 {
+ return ""
+ }
+ if len(strs) == 1 {
+ return strs[0]
+ }
+
+ var (
+ // Groups of strings broken into multiple lines
+ blocks = make([][]string, len(strs))
+
+ // Max line widths for the above text blocks
+ maxWidths = make([]int, len(strs))
+
+ // Height of the tallest block
+ maxHeight int
+ )
+
+ // Break text blocks into lines and get max widths for each text block
+ for i, str := range strs {
+ blocks[i], maxWidths[i] = getLines(str)
+ if len(blocks[i]) > maxHeight {
+ maxHeight = len(blocks[i])
+ }
+ }
+
+ // Add extra lines to make each side the same height
+ for i := range blocks {
+ if len(blocks[i]) >= maxHeight {
+ continue
+ }
+
+ extraLines := make([]string, maxHeight-len(blocks[i]))
+
+ switch pos { //nolint:exhaustive
+ case Top:
+ blocks[i] = append(blocks[i], extraLines...)
+
+ case Bottom:
+ blocks[i] = append(extraLines, blocks[i]...)
+
+ default: // Somewhere in the middle
+ n := len(extraLines)
+ split := int(math.Round(float64(n) * pos.value()))
+ top := n - split
+ bottom := n - top
+
+ blocks[i] = append(extraLines[top:], blocks[i]...)
+ blocks[i] = append(blocks[i], extraLines[bottom:]...)
+ }
+ }
+
+ // Merge lines
+ var b strings.Builder
+ for i := range blocks[0] { // remember, all blocks have the same number of members now
+ for j, block := range blocks {
+ b.WriteString(block[i])
+
+ // Also make lines the same length
+ b.WriteString(strings.Repeat(" ", maxWidths[j]-ansi.StringWidth(block[i])))
+ }
+ if i < len(blocks[0])-1 {
+ b.WriteRune('\n')
+ }
+ }
+
+ return b.String()
+}
+
+// JoinVertical is a utility function for vertically joining two potentially
+// multi-lined strings along a horizontal axis. The first argument is the
+// position, with 0 being all the way to the left and 1 being all the way to
+// the right.
+//
+// If you just want to align to the left, right or center you may as well just
+// use the helper constants Left, Center, and Right.
+//
+// Example:
+//
+// blockB := "...\n...\n..."
+// blockA := "...\n...\n...\n...\n..."
+//
+// // Join 20% from the top
+// str := lipgloss.JoinVertical(0.2, blockA, blockB)
+//
+// // Join on the right edge
+// str := lipgloss.JoinVertical(lipgloss.Right, blockA, blockB)
+func JoinVertical(pos Position, strs ...string) string {
+ if len(strs) == 0 {
+ return ""
+ }
+ if len(strs) == 1 {
+ return strs[0]
+ }
+
+ var (
+ blocks = make([][]string, len(strs))
+ maxWidth int
+ )
+
+ for i := range strs {
+ var w int
+ blocks[i], w = getLines(strs[i])
+ if w > maxWidth {
+ maxWidth = w
+ }
+ }
+
+ var b strings.Builder
+ for i, block := range blocks {
+ for j, line := range block {
+ w := maxWidth - ansi.StringWidth(line)
+
+ switch pos { //nolint:exhaustive
+ case Left:
+ b.WriteString(line)
+ b.WriteString(strings.Repeat(" ", w))
+
+ case Right:
+ b.WriteString(strings.Repeat(" ", w))
+ b.WriteString(line)
+
+ default: // Somewhere in the middle
+ if w < 1 {
+ b.WriteString(line)
+ break
+ }
+
+ split := int(math.Round(float64(w) * pos.value()))
+ right := w - split
+ left := w - right
+
+ b.WriteString(strings.Repeat(" ", left))
+ b.WriteString(line)
+ b.WriteString(strings.Repeat(" ", right))
+ }
+
+ // Write a newline as long as we're not on the last line of the
+ // last block.
+ if !(i == len(blocks)-1 && j == len(block)-1) {
+ b.WriteRune('\n')
+ }
+ }
+ }
+
+ return b.String()
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/position.go b/vendor/github.com/charmbracelet/lipgloss/position.go
new file mode 100644
index 0000000..185f5af
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/position.go
@@ -0,0 +1,154 @@
+package lipgloss
+
+import (
+ "math"
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+// Position represents a position along a horizontal or vertical axis. It's in
+// situations where an axis is involved, like alignment, joining, placement and
+// so on.
+//
+// A value of 0 represents the start (the left or top) and 1 represents the end
+// (the right or bottom). 0.5 represents the center.
+//
+// There are constants Top, Bottom, Center, Left and Right in this package that
+// can be used to aid readability.
+type Position float64
+
+func (p Position) value() float64 {
+ return math.Min(1, math.Max(0, float64(p)))
+}
+
+// Position aliases.
+const (
+ Top Position = 0.0
+ Bottom Position = 1.0
+ Center Position = 0.5
+ Left Position = 0.0
+ Right Position = 1.0
+)
+
+// Place places a string or text block vertically in an unstyled box of a given
+// width or height.
+func Place(width, height int, hPos, vPos Position, str string, opts ...WhitespaceOption) string {
+ return renderer.Place(width, height, hPos, vPos, str, opts...)
+}
+
+// Place places a string or text block vertically in an unstyled box of a given
+// width or height.
+func (r *Renderer) Place(width, height int, hPos, vPos Position, str string, opts ...WhitespaceOption) string {
+ return r.PlaceVertical(height, vPos, r.PlaceHorizontal(width, hPos, str, opts...), opts...)
+}
+
+// PlaceHorizontal places a string or text block horizontally in an unstyled
+// block of a given width. If the given width is shorter than the max width of
+// the string (measured by its longest line) this will be a noop.
+func PlaceHorizontal(width int, pos Position, str string, opts ...WhitespaceOption) string {
+ return renderer.PlaceHorizontal(width, pos, str, opts...)
+}
+
+// PlaceHorizontal places a string or text block horizontally in an unstyled
+// block of a given width. If the given width is shorter than the max width of
+// the string (measured by its longest line) this will be a noöp.
+func (r *Renderer) PlaceHorizontal(width int, pos Position, str string, opts ...WhitespaceOption) string {
+ lines, contentWidth := getLines(str)
+ gap := width - contentWidth
+
+ if gap <= 0 {
+ return str
+ }
+
+ ws := newWhitespace(r, opts...)
+
+ var b strings.Builder
+ for i, l := range lines {
+ // Is this line shorter than the longest line?
+ short := max(0, contentWidth-ansi.StringWidth(l))
+
+ switch pos { //nolint:exhaustive
+ case Left:
+ b.WriteString(l)
+ b.WriteString(ws.render(gap + short))
+
+ case Right:
+ b.WriteString(ws.render(gap + short))
+ b.WriteString(l)
+
+ default: // somewhere in the middle
+ totalGap := gap + short
+
+ split := int(math.Round(float64(totalGap) * pos.value()))
+ left := totalGap - split
+ right := totalGap - left
+
+ b.WriteString(ws.render(left))
+ b.WriteString(l)
+ b.WriteString(ws.render(right))
+ }
+
+ if i < len(lines)-1 {
+ b.WriteRune('\n')
+ }
+ }
+
+ return b.String()
+}
+
+// PlaceVertical places a string or text block vertically in an unstyled block
+// of a given height. If the given height is shorter than the height of the
+// string (measured by its newlines) then this will be a noop.
+func PlaceVertical(height int, pos Position, str string, opts ...WhitespaceOption) string {
+ return renderer.PlaceVertical(height, pos, str, opts...)
+}
+
+// PlaceVertical places a string or text block vertically in an unstyled block
+// of a given height. If the given height is shorter than the height of the
+// string (measured by its newlines) then this will be a noöp.
+func (r *Renderer) PlaceVertical(height int, pos Position, str string, opts ...WhitespaceOption) string {
+ contentHeight := strings.Count(str, "\n") + 1
+ gap := height - contentHeight
+
+ if gap <= 0 {
+ return str
+ }
+
+ ws := newWhitespace(r, opts...)
+
+ _, width := getLines(str)
+ emptyLine := ws.render(width)
+ b := strings.Builder{}
+
+ switch pos { //nolint:exhaustive
+ case Top:
+ b.WriteString(str)
+ b.WriteRune('\n')
+ for i := 0; i < gap; i++ {
+ b.WriteString(emptyLine)
+ if i < gap-1 {
+ b.WriteRune('\n')
+ }
+ }
+
+ case Bottom:
+ b.WriteString(strings.Repeat(emptyLine+"\n", gap))
+ b.WriteString(str)
+
+ default: // Somewhere in the middle
+ split := int(math.Round(float64(gap) * pos.value()))
+ top := gap - split
+ bottom := gap - top
+
+ b.WriteString(strings.Repeat(emptyLine+"\n", top))
+ b.WriteString(str)
+
+ for i := 0; i < bottom; i++ {
+ b.WriteRune('\n')
+ b.WriteString(emptyLine)
+ }
+ }
+
+ return b.String()
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/renderer.go b/vendor/github.com/charmbracelet/lipgloss/renderer.go
new file mode 100644
index 0000000..233aa7c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/renderer.go
@@ -0,0 +1,181 @@
+package lipgloss
+
+import (
+ "io"
+ "sync"
+
+ "github.com/muesli/termenv"
+)
+
+// We're manually creating the struct here to avoid initializing the output and
+// query the terminal multiple times.
+var renderer = &Renderer{
+ output: termenv.DefaultOutput(),
+}
+
+// Renderer is a lipgloss terminal renderer.
+type Renderer struct {
+ output *termenv.Output
+ colorProfile termenv.Profile
+ hasDarkBackground bool
+
+ getColorProfile sync.Once
+ explicitColorProfile bool
+
+ getBackgroundColor sync.Once
+ explicitBackgroundColor bool
+
+ mtx sync.RWMutex
+}
+
+// DefaultRenderer returns the default renderer.
+func DefaultRenderer() *Renderer {
+ return renderer
+}
+
+// SetDefaultRenderer sets the default global renderer.
+func SetDefaultRenderer(r *Renderer) {
+ renderer = r
+}
+
+// NewRenderer creates a new Renderer.
+//
+// w will be used to determine the terminal's color capabilities.
+func NewRenderer(w io.Writer, opts ...termenv.OutputOption) *Renderer {
+ r := &Renderer{
+ output: termenv.NewOutput(w, opts...),
+ }
+ return r
+}
+
+// Output returns the termenv output.
+func (r *Renderer) Output() *termenv.Output {
+ r.mtx.RLock()
+ defer r.mtx.RUnlock()
+ return r.output
+}
+
+// SetOutput sets the termenv output.
+func (r *Renderer) SetOutput(o *termenv.Output) {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+ r.output = o
+}
+
+// ColorProfile returns the detected termenv color profile.
+func (r *Renderer) ColorProfile() termenv.Profile {
+ r.mtx.RLock()
+ defer r.mtx.RUnlock()
+
+ if !r.explicitColorProfile {
+ r.getColorProfile.Do(func() {
+ // NOTE: we don't need to lock here because sync.Once provides its
+ // own locking mechanism.
+ r.colorProfile = r.output.EnvColorProfile()
+ })
+ }
+
+ return r.colorProfile
+}
+
+// ColorProfile returns the detected termenv color profile.
+func ColorProfile() termenv.Profile {
+ return renderer.ColorProfile()
+}
+
+// SetColorProfile sets the color profile on the renderer. This function exists
+// mostly for testing purposes so that you can assure you're testing against
+// a specific profile.
+//
+// Outside of testing you likely won't want to use this function as the color
+// profile will detect and cache the terminal's color capabilities and choose
+// the best available profile.
+//
+// Available color profiles are:
+//
+// termenv.Ascii // no color, 1-bit
+// termenv.ANSI //16 colors, 4-bit
+// termenv.ANSI256 // 256 colors, 8-bit
+// termenv.TrueColor // 16,777,216 colors, 24-bit
+//
+// This function is thread-safe.
+func (r *Renderer) SetColorProfile(p termenv.Profile) {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.colorProfile = p
+ r.explicitColorProfile = true
+}
+
+// SetColorProfile sets the color profile on the default renderer. This
+// function exists mostly for testing purposes so that you can assure you're
+// testing against a specific profile.
+//
+// Outside of testing you likely won't want to use this function as the color
+// profile will detect and cache the terminal's color capabilities and choose
+// the best available profile.
+//
+// Available color profiles are:
+//
+// termenv.Ascii // no color, 1-bit
+// termenv.ANSI //16 colors, 4-bit
+// termenv.ANSI256 // 256 colors, 8-bit
+// termenv.TrueColor // 16,777,216 colors, 24-bit
+//
+// This function is thread-safe.
+func SetColorProfile(p termenv.Profile) {
+ renderer.SetColorProfile(p)
+}
+
+// HasDarkBackground returns whether or not the terminal has a dark background.
+func HasDarkBackground() bool {
+ return renderer.HasDarkBackground()
+}
+
+// HasDarkBackground returns whether or not the renderer will render to a dark
+// background. A dark background can either be auto-detected, or set explicitly
+// on the renderer.
+func (r *Renderer) HasDarkBackground() bool {
+ r.mtx.RLock()
+ defer r.mtx.RUnlock()
+
+ if !r.explicitBackgroundColor {
+ r.getBackgroundColor.Do(func() {
+ // NOTE: we don't need to lock here because sync.Once provides its
+ // own locking mechanism.
+ r.hasDarkBackground = r.output.HasDarkBackground()
+ })
+ }
+
+ return r.hasDarkBackground
+}
+
+// SetHasDarkBackground sets the background color detection value for the
+// default renderer. This function exists mostly for testing purposes so that
+// you can assure you're testing against a specific background color setting.
+//
+// Outside of testing you likely won't want to use this function as the
+// backgrounds value will be automatically detected and cached against the
+// terminal's current background color setting.
+//
+// This function is thread-safe.
+func SetHasDarkBackground(b bool) {
+ renderer.SetHasDarkBackground(b)
+}
+
+// SetHasDarkBackground sets the background color detection value on the
+// renderer. This function exists mostly for testing purposes so that you can
+// assure you're testing against a specific background color setting.
+//
+// Outside of testing you likely won't want to use this function as the
+// backgrounds value will be automatically detected and cached against the
+// terminal's current background color setting.
+//
+// This function is thread-safe.
+func (r *Renderer) SetHasDarkBackground(b bool) {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.hasDarkBackground = b
+ r.explicitBackgroundColor = true
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/runes.go b/vendor/github.com/charmbracelet/lipgloss/runes.go
new file mode 100644
index 0000000..7a49e32
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/runes.go
@@ -0,0 +1,43 @@
+package lipgloss
+
+import (
+ "strings"
+)
+
+// StyleRunes apply a given style to runes at the given indices in the string.
+// Note that you must provide styling options for both matched and unmatched
+// runes. Indices out of bounds will be ignored.
+func StyleRunes(str string, indices []int, matched, unmatched Style) string {
+ // Convert slice of indices to a map for easier lookups
+ m := make(map[int]struct{})
+ for _, i := range indices {
+ m[i] = struct{}{}
+ }
+
+ var (
+ out strings.Builder
+ group strings.Builder
+ style Style
+ runes = []rune(str)
+ )
+
+ for i, r := range runes {
+ group.WriteRune(r)
+
+ _, matches := m[i]
+ _, nextMatches := m[i+1]
+
+ if matches != nextMatches || i == len(runes)-1 {
+ // Flush
+ if matches {
+ style = matched
+ } else {
+ style = unmatched
+ }
+ out.WriteString(style.Render(group.String()))
+ group.Reset()
+ }
+ }
+
+ return out.String()
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/set.go b/vendor/github.com/charmbracelet/lipgloss/set.go
new file mode 100644
index 0000000..ed6e272
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/set.go
@@ -0,0 +1,799 @@
+package lipgloss
+
+// Set a value on the underlying rules map.
+func (s *Style) set(key propKey, value interface{}) {
+ // We don't allow negative integers on any of our other values, so just keep
+ // them at zero or above. We could use uints instead, but the
+ // conversions are a little tedious, so we're sticking with ints for
+ // sake of usability.
+ switch key { //nolint:exhaustive
+ case foregroundKey:
+ s.fgColor = colorOrNil(value)
+ case backgroundKey:
+ s.bgColor = colorOrNil(value)
+ case widthKey:
+ s.width = max(0, value.(int))
+ case heightKey:
+ s.height = max(0, value.(int))
+ case alignHorizontalKey:
+ s.alignHorizontal = value.(Position)
+ case alignVerticalKey:
+ s.alignVertical = value.(Position)
+ case paddingTopKey:
+ s.paddingTop = max(0, value.(int))
+ case paddingRightKey:
+ s.paddingRight = max(0, value.(int))
+ case paddingBottomKey:
+ s.paddingBottom = max(0, value.(int))
+ case paddingLeftKey:
+ s.paddingLeft = max(0, value.(int))
+ case marginTopKey:
+ s.marginTop = max(0, value.(int))
+ case marginRightKey:
+ s.marginRight = max(0, value.(int))
+ case marginBottomKey:
+ s.marginBottom = max(0, value.(int))
+ case marginLeftKey:
+ s.marginLeft = max(0, value.(int))
+ case marginBackgroundKey:
+ s.marginBgColor = colorOrNil(value)
+ case borderStyleKey:
+ s.borderStyle = value.(Border)
+ case borderTopForegroundKey:
+ s.borderTopFgColor = colorOrNil(value)
+ case borderRightForegroundKey:
+ s.borderRightFgColor = colorOrNil(value)
+ case borderBottomForegroundKey:
+ s.borderBottomFgColor = colorOrNil(value)
+ case borderLeftForegroundKey:
+ s.borderLeftFgColor = colorOrNil(value)
+ case borderTopBackgroundKey:
+ s.borderTopBgColor = colorOrNil(value)
+ case borderRightBackgroundKey:
+ s.borderRightBgColor = colorOrNil(value)
+ case borderBottomBackgroundKey:
+ s.borderBottomBgColor = colorOrNil(value)
+ case borderLeftBackgroundKey:
+ s.borderLeftBgColor = colorOrNil(value)
+ case maxWidthKey:
+ s.maxWidth = max(0, value.(int))
+ case maxHeightKey:
+ s.maxHeight = max(0, value.(int))
+ case tabWidthKey:
+ // TabWidth is the only property that may have a negative value (and
+ // that negative value can be no less than -1).
+ s.tabWidth = value.(int)
+ case transformKey:
+ s.transform = value.(func(string) string)
+ default:
+ if v, ok := value.(bool); ok { //nolint:nestif
+ if v {
+ s.attrs |= int(key)
+ } else {
+ s.attrs &^= int(key)
+ }
+ } else if attrs, ok := value.(int); ok {
+ // bool attrs
+ if attrs&int(key) != 0 {
+ s.attrs |= int(key)
+ } else {
+ s.attrs &^= int(key)
+ }
+ }
+ }
+
+ // Set the prop on
+ s.props = s.props.set(key)
+}
+
+// setFrom sets the property from another style.
+func (s *Style) setFrom(key propKey, i Style) {
+ switch key { //nolint:exhaustive
+ case foregroundKey:
+ s.set(foregroundKey, i.fgColor)
+ case backgroundKey:
+ s.set(backgroundKey, i.bgColor)
+ case widthKey:
+ s.set(widthKey, i.width)
+ case heightKey:
+ s.set(heightKey, i.height)
+ case alignHorizontalKey:
+ s.set(alignHorizontalKey, i.alignHorizontal)
+ case alignVerticalKey:
+ s.set(alignVerticalKey, i.alignVertical)
+ case paddingTopKey:
+ s.set(paddingTopKey, i.paddingTop)
+ case paddingRightKey:
+ s.set(paddingRightKey, i.paddingRight)
+ case paddingBottomKey:
+ s.set(paddingBottomKey, i.paddingBottom)
+ case paddingLeftKey:
+ s.set(paddingLeftKey, i.paddingLeft)
+ case marginTopKey:
+ s.set(marginTopKey, i.marginTop)
+ case marginRightKey:
+ s.set(marginRightKey, i.marginRight)
+ case marginBottomKey:
+ s.set(marginBottomKey, i.marginBottom)
+ case marginLeftKey:
+ s.set(marginLeftKey, i.marginLeft)
+ case marginBackgroundKey:
+ s.set(marginBackgroundKey, i.marginBgColor)
+ case borderStyleKey:
+ s.set(borderStyleKey, i.borderStyle)
+ case borderTopForegroundKey:
+ s.set(borderTopForegroundKey, i.borderTopFgColor)
+ case borderRightForegroundKey:
+ s.set(borderRightForegroundKey, i.borderRightFgColor)
+ case borderBottomForegroundKey:
+ s.set(borderBottomForegroundKey, i.borderBottomFgColor)
+ case borderLeftForegroundKey:
+ s.set(borderLeftForegroundKey, i.borderLeftFgColor)
+ case borderTopBackgroundKey:
+ s.set(borderTopBackgroundKey, i.borderTopBgColor)
+ case borderRightBackgroundKey:
+ s.set(borderRightBackgroundKey, i.borderRightBgColor)
+ case borderBottomBackgroundKey:
+ s.set(borderBottomBackgroundKey, i.borderBottomBgColor)
+ case borderLeftBackgroundKey:
+ s.set(borderLeftBackgroundKey, i.borderLeftBgColor)
+ case maxWidthKey:
+ s.set(maxWidthKey, i.maxWidth)
+ case maxHeightKey:
+ s.set(maxHeightKey, i.maxHeight)
+ case tabWidthKey:
+ s.set(tabWidthKey, i.tabWidth)
+ case transformKey:
+ s.set(transformKey, i.transform)
+ default:
+ // Set attributes for set bool properties
+ s.set(key, i.attrs)
+ }
+}
+
+func colorOrNil(c interface{}) TerminalColor {
+ if c, ok := c.(TerminalColor); ok {
+ return c
+ }
+ return nil
+}
+
+// Bold sets a bold formatting rule.
+func (s Style) Bold(v bool) Style {
+ s.set(boldKey, v)
+ return s
+}
+
+// Italic sets an italic formatting rule. In some terminal emulators this will
+// render with "reverse" coloring if not italic font variant is available.
+func (s Style) Italic(v bool) Style {
+ s.set(italicKey, v)
+ return s
+}
+
+// Underline sets an underline rule. By default, underlines will not be drawn on
+// whitespace like margins and padding. To change this behavior set
+// UnderlineSpaces.
+func (s Style) Underline(v bool) Style {
+ s.set(underlineKey, v)
+ return s
+}
+
+// Strikethrough sets a strikethrough rule. By default, strikes will not be
+// drawn on whitespace like margins and padding. To change this behavior set
+// StrikethroughSpaces.
+func (s Style) Strikethrough(v bool) Style {
+ s.set(strikethroughKey, v)
+ return s
+}
+
+// Reverse sets a rule for inverting foreground and background colors.
+func (s Style) Reverse(v bool) Style {
+ s.set(reverseKey, v)
+ return s
+}
+
+// Blink sets a rule for blinking foreground text.
+func (s Style) Blink(v bool) Style {
+ s.set(blinkKey, v)
+ return s
+}
+
+// Faint sets a rule for rendering the foreground color in a dimmer shade.
+func (s Style) Faint(v bool) Style {
+ s.set(faintKey, v)
+ return s
+}
+
+// Foreground sets a foreground color.
+//
+// // Sets the foreground to blue
+// s := lipgloss.NewStyle().Foreground(lipgloss.Color("#0000ff"))
+//
+// // Removes the foreground color
+// s.Foreground(lipgloss.NoColor)
+func (s Style) Foreground(c TerminalColor) Style {
+ s.set(foregroundKey, c)
+ return s
+}
+
+// Background sets a background color.
+func (s Style) Background(c TerminalColor) Style {
+ s.set(backgroundKey, c)
+ return s
+}
+
+// Width sets the width of the block before applying margins. The width, if
+// set, also determines where text will wrap.
+func (s Style) Width(i int) Style {
+ s.set(widthKey, i)
+ return s
+}
+
+// Height sets the height of the block before applying margins. If the height of
+// the text block is less than this value after applying padding (or not), the
+// block will be set to this height.
+func (s Style) Height(i int) Style {
+ s.set(heightKey, i)
+ return s
+}
+
+// Align is a shorthand method for setting horizontal and vertical alignment.
+//
+// With one argument, the position value is applied to the horizontal alignment.
+//
+// With two arguments, the value is applied to the horizontal and vertical
+// alignments, in that order.
+func (s Style) Align(p ...Position) Style {
+ if len(p) > 0 {
+ s.set(alignHorizontalKey, p[0])
+ }
+ if len(p) > 1 {
+ s.set(alignVerticalKey, p[1])
+ }
+ return s
+}
+
+// AlignHorizontal sets a horizontal text alignment rule.
+func (s Style) AlignHorizontal(p Position) Style {
+ s.set(alignHorizontalKey, p)
+ return s
+}
+
+// AlignVertical sets a vertical text alignment rule.
+func (s Style) AlignVertical(p Position) Style {
+ s.set(alignVerticalKey, p)
+ return s
+}
+
+// Padding is a shorthand method for setting padding on all sides at once.
+//
+// With one argument, the value is applied to all sides.
+//
+// With two arguments, the value is applied to the vertical and horizontal
+// sides, in that order.
+//
+// With three arguments, the value is applied to the top side, the horizontal
+// sides, and the bottom side, in that order.
+//
+// With four arguments, the value is applied clockwise starting from the top
+// side, followed by the right side, then the bottom, and finally the left.
+//
+// With more than four arguments no padding will be added.
+func (s Style) Padding(i ...int) Style {
+ top, right, bottom, left, ok := whichSidesInt(i...)
+ if !ok {
+ return s
+ }
+
+ s.set(paddingTopKey, top)
+ s.set(paddingRightKey, right)
+ s.set(paddingBottomKey, bottom)
+ s.set(paddingLeftKey, left)
+ return s
+}
+
+// PaddingLeft adds padding on the left.
+func (s Style) PaddingLeft(i int) Style {
+ s.set(paddingLeftKey, i)
+ return s
+}
+
+// PaddingRight adds padding on the right.
+func (s Style) PaddingRight(i int) Style {
+ s.set(paddingRightKey, i)
+ return s
+}
+
+// PaddingTop adds padding to the top of the block.
+func (s Style) PaddingTop(i int) Style {
+ s.set(paddingTopKey, i)
+ return s
+}
+
+// PaddingBottom adds padding to the bottom of the block.
+func (s Style) PaddingBottom(i int) Style {
+ s.set(paddingBottomKey, i)
+ return s
+}
+
+// ColorWhitespace determines whether or not the background color should be
+// applied to the padding. This is true by default as it's more than likely the
+// desired and expected behavior, but it can be disabled for certain graphic
+// effects.
+//
+// Deprecated: Just use margins and padding.
+func (s Style) ColorWhitespace(v bool) Style {
+ s.set(colorWhitespaceKey, v)
+ return s
+}
+
+// Margin is a shorthand method for setting margins on all sides at once.
+//
+// With one argument, the value is applied to all sides.
+//
+// With two arguments, the value is applied to the vertical and horizontal
+// sides, in that order.
+//
+// With three arguments, the value is applied to the top side, the horizontal
+// sides, and the bottom side, in that order.
+//
+// With four arguments, the value is applied clockwise starting from the top
+// side, followed by the right side, then the bottom, and finally the left.
+//
+// With more than four arguments no margin will be added.
+func (s Style) Margin(i ...int) Style {
+ top, right, bottom, left, ok := whichSidesInt(i...)
+ if !ok {
+ return s
+ }
+
+ s.set(marginTopKey, top)
+ s.set(marginRightKey, right)
+ s.set(marginBottomKey, bottom)
+ s.set(marginLeftKey, left)
+ return s
+}
+
+// MarginLeft sets the value of the left margin.
+func (s Style) MarginLeft(i int) Style {
+ s.set(marginLeftKey, i)
+ return s
+}
+
+// MarginRight sets the value of the right margin.
+func (s Style) MarginRight(i int) Style {
+ s.set(marginRightKey, i)
+ return s
+}
+
+// MarginTop sets the value of the top margin.
+func (s Style) MarginTop(i int) Style {
+ s.set(marginTopKey, i)
+ return s
+}
+
+// MarginBottom sets the value of the bottom margin.
+func (s Style) MarginBottom(i int) Style {
+ s.set(marginBottomKey, i)
+ return s
+}
+
+// MarginBackground sets the background color of the margin. Note that this is
+// also set when inheriting from a style with a background color. In that case
+// the background color on that style will set the margin color on this style.
+func (s Style) MarginBackground(c TerminalColor) Style {
+ s.set(marginBackgroundKey, c)
+ return s
+}
+
+// Border is shorthand for setting the border style and which sides should
+// have a border at once. The variadic argument sides works as follows:
+//
+// With one value, the value is applied to all sides.
+//
+// With two values, the values are applied to the vertical and horizontal
+// sides, in that order.
+//
+// With three values, the values are applied to the top side, the horizontal
+// sides, and the bottom side, in that order.
+//
+// With four values, the values are applied clockwise starting from the top
+// side, followed by the right side, then the bottom, and finally the left.
+//
+// With more than four arguments the border will be applied to all sides.
+//
+// Examples:
+//
+// // Applies borders to the top and bottom only
+// lipgloss.NewStyle().Border(lipgloss.NormalBorder(), true, false)
+//
+// // Applies rounded borders to the right and bottom only
+// lipgloss.NewStyle().Border(lipgloss.RoundedBorder(), false, true, true, false)
+func (s Style) Border(b Border, sides ...bool) Style {
+ s.set(borderStyleKey, b)
+
+ top, right, bottom, left, ok := whichSidesBool(sides...)
+ if !ok {
+ top = true
+ right = true
+ bottom = true
+ left = true
+ }
+
+ s.set(borderTopKey, top)
+ s.set(borderRightKey, right)
+ s.set(borderBottomKey, bottom)
+ s.set(borderLeftKey, left)
+
+ return s
+}
+
+// BorderStyle defines the Border on a style. A Border contains a series of
+// definitions for the sides and corners of a border.
+//
+// Note that if border visibility has not been set for any sides when setting
+// the border style, the border will be enabled for all sides during rendering.
+//
+// You can define border characters as you'd like, though several default
+// styles are included: NormalBorder(), RoundedBorder(), BlockBorder(),
+// OuterHalfBlockBorder(), InnerHalfBlockBorder(), ThickBorder(),
+// and DoubleBorder().
+//
+// Example:
+//
+// lipgloss.NewStyle().BorderStyle(lipgloss.ThickBorder())
+func (s Style) BorderStyle(b Border) Style {
+ s.set(borderStyleKey, b)
+ return s
+}
+
+// BorderTop determines whether or not to draw a top border.
+func (s Style) BorderTop(v bool) Style {
+ s.set(borderTopKey, v)
+ return s
+}
+
+// BorderRight determines whether or not to draw a right border.
+func (s Style) BorderRight(v bool) Style {
+ s.set(borderRightKey, v)
+ return s
+}
+
+// BorderBottom determines whether or not to draw a bottom border.
+func (s Style) BorderBottom(v bool) Style {
+ s.set(borderBottomKey, v)
+ return s
+}
+
+// BorderLeft determines whether or not to draw a left border.
+func (s Style) BorderLeft(v bool) Style {
+ s.set(borderLeftKey, v)
+ return s
+}
+
+// BorderForeground is a shorthand function for setting all of the
+// foreground colors of the borders at once. The arguments work as follows:
+//
+// With one argument, the argument is applied to all sides.
+//
+// With two arguments, the arguments are applied to the vertical and horizontal
+// sides, in that order.
+//
+// With three arguments, the arguments are applied to the top side, the
+// horizontal sides, and the bottom side, in that order.
+//
+// With four arguments, the arguments are applied clockwise starting from the
+// top side, followed by the right side, then the bottom, and finally the left.
+//
+// With more than four arguments nothing will be set.
+func (s Style) BorderForeground(c ...TerminalColor) Style {
+ if len(c) == 0 {
+ return s
+ }
+
+ top, right, bottom, left, ok := whichSidesColor(c...)
+ if !ok {
+ return s
+ }
+
+ s.set(borderTopForegroundKey, top)
+ s.set(borderRightForegroundKey, right)
+ s.set(borderBottomForegroundKey, bottom)
+ s.set(borderLeftForegroundKey, left)
+
+ return s
+}
+
+// BorderTopForeground set the foreground color for the top of the border.
+func (s Style) BorderTopForeground(c TerminalColor) Style {
+ s.set(borderTopForegroundKey, c)
+ return s
+}
+
+// BorderRightForeground sets the foreground color for the right side of the
+// border.
+func (s Style) BorderRightForeground(c TerminalColor) Style {
+ s.set(borderRightForegroundKey, c)
+ return s
+}
+
+// BorderBottomForeground sets the foreground color for the bottom of the
+// border.
+func (s Style) BorderBottomForeground(c TerminalColor) Style {
+ s.set(borderBottomForegroundKey, c)
+ return s
+}
+
+// BorderLeftForeground sets the foreground color for the left side of the
+// border.
+func (s Style) BorderLeftForeground(c TerminalColor) Style {
+ s.set(borderLeftForegroundKey, c)
+ return s
+}
+
+// BorderBackground is a shorthand function for setting all of the
+// background colors of the borders at once. The arguments work as follows:
+//
+// With one argument, the argument is applied to all sides.
+//
+// With two arguments, the arguments are applied to the vertical and horizontal
+// sides, in that order.
+//
+// With three arguments, the arguments are applied to the top side, the
+// horizontal sides, and the bottom side, in that order.
+//
+// With four arguments, the arguments are applied clockwise starting from the
+// top side, followed by the right side, then the bottom, and finally the left.
+//
+// With more than four arguments nothing will be set.
+func (s Style) BorderBackground(c ...TerminalColor) Style {
+ if len(c) == 0 {
+ return s
+ }
+
+ top, right, bottom, left, ok := whichSidesColor(c...)
+ if !ok {
+ return s
+ }
+
+ s.set(borderTopBackgroundKey, top)
+ s.set(borderRightBackgroundKey, right)
+ s.set(borderBottomBackgroundKey, bottom)
+ s.set(borderLeftBackgroundKey, left)
+
+ return s
+}
+
+// BorderTopBackground sets the background color of the top of the border.
+func (s Style) BorderTopBackground(c TerminalColor) Style {
+ s.set(borderTopBackgroundKey, c)
+ return s
+}
+
+// BorderRightBackground sets the background color of right side the border.
+func (s Style) BorderRightBackground(c TerminalColor) Style {
+ s.set(borderRightBackgroundKey, c)
+ return s
+}
+
+// BorderBottomBackground sets the background color of the bottom of the
+// border.
+func (s Style) BorderBottomBackground(c TerminalColor) Style {
+ s.set(borderBottomBackgroundKey, c)
+ return s
+}
+
+// BorderLeftBackground set the background color of the left side of the
+// border.
+func (s Style) BorderLeftBackground(c TerminalColor) Style {
+ s.set(borderLeftBackgroundKey, c)
+ return s
+}
+
+// Inline makes rendering output one line and disables the rendering of
+// margins, padding and borders. This is useful when you need a style to apply
+// only to font rendering and don't want it to change any physical dimensions.
+// It works well with Style.MaxWidth.
+//
+// Because this in intended to be used at the time of render, this method will
+// not mutate the style and instead return a copy.
+//
+// Example:
+//
+// var userInput string = "..."
+// var userStyle = text.Style{ /* ... */ }
+// fmt.Println(userStyle.Inline(true).Render(userInput))
+func (s Style) Inline(v bool) Style {
+ o := s // copy
+ o.set(inlineKey, v)
+ return o
+}
+
+// MaxWidth applies a max width to a given style. This is useful in enforcing
+// a certain width at render time, particularly with arbitrary strings and
+// styles.
+//
+// Because this in intended to be used at the time of render, this method will
+// not mutate the style and instead return a copy.
+//
+// Example:
+//
+// var userInput string = "..."
+// var userStyle = text.Style{ /* ... */ }
+// fmt.Println(userStyle.MaxWidth(16).Render(userInput))
+func (s Style) MaxWidth(n int) Style {
+ o := s // copy
+ o.set(maxWidthKey, n)
+ return o
+}
+
+// MaxHeight applies a max height to a given style. This is useful in enforcing
+// a certain height at render time, particularly with arbitrary strings and
+// styles.
+//
+// Because this in intended to be used at the time of render, this method will
+// not mutate the style and instead returns a copy.
+func (s Style) MaxHeight(n int) Style {
+ o := s // copy
+ o.set(maxHeightKey, n)
+ return o
+}
+
+// NoTabConversion can be passed to [Style.TabWidth] to disable the replacement
+// of tabs with spaces at render time.
+const NoTabConversion = -1
+
+// TabWidth sets the number of spaces that a tab (/t) should be rendered as.
+// When set to 0, tabs will be removed. To disable the replacement of tabs with
+// spaces entirely, set this to [NoTabConversion].
+//
+// By default, tabs will be replaced with 4 spaces.
+func (s Style) TabWidth(n int) Style {
+ if n <= -1 {
+ n = -1
+ }
+ s.set(tabWidthKey, n)
+ return s
+}
+
+// UnderlineSpaces determines whether to underline spaces between words. By
+// default, this is true. Spaces can also be underlined without underlining the
+// text itself.
+func (s Style) UnderlineSpaces(v bool) Style {
+ s.set(underlineSpacesKey, v)
+ return s
+}
+
+// StrikethroughSpaces determines whether to apply strikethroughs to spaces
+// between words. By default, this is true. Spaces can also be struck without
+// underlining the text itself.
+func (s Style) StrikethroughSpaces(v bool) Style {
+ s.set(strikethroughSpacesKey, v)
+ return s
+}
+
+// Transform applies a given function to a string at render time, allowing for
+// the string being rendered to be manipuated.
+//
+// Example:
+//
+// s := NewStyle().Transform(strings.ToUpper)
+// fmt.Println(s.Render("raow!") // "RAOW!"
+func (s Style) Transform(fn func(string) string) Style {
+ s.set(transformKey, fn)
+ return s
+}
+
+// Renderer sets the renderer for the style. This is useful for changing the
+// renderer for a style that is being used in a different context.
+func (s Style) Renderer(r *Renderer) Style {
+ s.r = r
+ return s
+}
+
+// whichSidesInt is a helper method for setting values on sides of a block based
+// on the number of arguments. It follows the CSS shorthand rules for blocks
+// like margin, padding. and borders. Here are how the rules work:
+//
+// 0 args: do nothing
+// 1 arg: all sides
+// 2 args: top -> bottom
+// 3 args: top -> horizontal -> bottom
+// 4 args: top -> right -> bottom -> left
+// 5+ args: do nothing.
+func whichSidesInt(i ...int) (top, right, bottom, left int, ok bool) {
+ switch len(i) {
+ case 1:
+ top = i[0]
+ bottom = i[0]
+ left = i[0]
+ right = i[0]
+ ok = true
+ case 2: //nolint:gomnd
+ top = i[0]
+ bottom = i[0]
+ left = i[1]
+ right = i[1]
+ ok = true
+ case 3: //nolint:gomnd
+ top = i[0]
+ left = i[1]
+ right = i[1]
+ bottom = i[2]
+ ok = true
+ case 4: //nolint:gomnd
+ top = i[0]
+ right = i[1]
+ bottom = i[2]
+ left = i[3]
+ ok = true
+ }
+ return top, right, bottom, left, ok
+}
+
+// whichSidesBool is like whichSidesInt, except it operates on a series of
+// boolean values. See the comment on whichSidesInt for details on how this
+// works.
+func whichSidesBool(i ...bool) (top, right, bottom, left bool, ok bool) {
+ switch len(i) {
+ case 1:
+ top = i[0]
+ bottom = i[0]
+ left = i[0]
+ right = i[0]
+ ok = true
+ case 2: //nolint:gomnd
+ top = i[0]
+ bottom = i[0]
+ left = i[1]
+ right = i[1]
+ ok = true
+ case 3: //nolint:gomnd
+ top = i[0]
+ left = i[1]
+ right = i[1]
+ bottom = i[2]
+ ok = true
+ case 4: //nolint:gomnd
+ top = i[0]
+ right = i[1]
+ bottom = i[2]
+ left = i[3]
+ ok = true
+ }
+ return top, right, bottom, left, ok
+}
+
+// whichSidesColor is like whichSides, except it operates on a series of
+// boolean values. See the comment on whichSidesInt for details on how this
+// works.
+func whichSidesColor(i ...TerminalColor) (top, right, bottom, left TerminalColor, ok bool) {
+ switch len(i) {
+ case 1:
+ top = i[0]
+ bottom = i[0]
+ left = i[0]
+ right = i[0]
+ ok = true
+ case 2: //nolint:gomnd
+ top = i[0]
+ bottom = i[0]
+ left = i[1]
+ right = i[1]
+ ok = true
+ case 3: //nolint:gomnd
+ top = i[0]
+ left = i[1]
+ right = i[1]
+ bottom = i[2]
+ ok = true
+ case 4: //nolint:gomnd
+ top = i[0]
+ right = i[1]
+ bottom = i[2]
+ left = i[3]
+ ok = true
+ }
+ return top, right, bottom, left, ok
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/size.go b/vendor/github.com/charmbracelet/lipgloss/size.go
new file mode 100644
index 0000000..e169ff5
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/size.go
@@ -0,0 +1,41 @@
+package lipgloss
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+// Width returns the cell width of characters in the string. ANSI sequences are
+// ignored and characters wider than one cell (such as Chinese characters and
+// emojis) are appropriately measured.
+//
+// You should use this instead of len(string) len([]rune(string) as neither
+// will give you accurate results.
+func Width(str string) (width int) {
+ for _, l := range strings.Split(str, "\n") {
+ w := ansi.StringWidth(l)
+ if w > width {
+ width = w
+ }
+ }
+
+ return width
+}
+
+// Height returns height of a string in cells. This is done simply by
+// counting \n characters. If your strings use \r\n for newlines you should
+// convert them to \n first, or simply write a separate function for measuring
+// height.
+func Height(str string) int {
+ return strings.Count(str, "\n") + 1
+}
+
+// Size returns the width and height of the string in cells. ANSI sequences are
+// ignored and characters wider than one cell (such as Chinese characters and
+// emojis) are appropriately measured.
+func Size(str string) (width, height int) {
+ width = Width(str)
+ height = Height(str)
+ return width, height
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/style.go b/vendor/github.com/charmbracelet/lipgloss/style.go
new file mode 100644
index 0000000..0eb5c01
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/style.go
@@ -0,0 +1,587 @@
+package lipgloss
+
+import (
+ "strings"
+ "unicode"
+
+ "github.com/charmbracelet/x/ansi"
+ "github.com/muesli/termenv"
+)
+
+const tabWidthDefault = 4
+
+// Property for a key.
+type propKey int64
+
+// Available properties.
+const (
+ // Boolean props come first.
+ boldKey propKey = 1 << iota
+ italicKey
+ underlineKey
+ strikethroughKey
+ reverseKey
+ blinkKey
+ faintKey
+ underlineSpacesKey
+ strikethroughSpacesKey
+ colorWhitespaceKey
+
+ // Non-boolean props.
+ foregroundKey
+ backgroundKey
+ widthKey
+ heightKey
+ alignHorizontalKey
+ alignVerticalKey
+
+ // Padding.
+ paddingTopKey
+ paddingRightKey
+ paddingBottomKey
+ paddingLeftKey
+
+ // Margins.
+ marginTopKey
+ marginRightKey
+ marginBottomKey
+ marginLeftKey
+ marginBackgroundKey
+
+ // Border runes.
+ borderStyleKey
+
+ // Border edges.
+ borderTopKey
+ borderRightKey
+ borderBottomKey
+ borderLeftKey
+
+ // Border foreground colors.
+ borderTopForegroundKey
+ borderRightForegroundKey
+ borderBottomForegroundKey
+ borderLeftForegroundKey
+
+ // Border background colors.
+ borderTopBackgroundKey
+ borderRightBackgroundKey
+ borderBottomBackgroundKey
+ borderLeftBackgroundKey
+
+ inlineKey
+ maxWidthKey
+ maxHeightKey
+ tabWidthKey
+
+ transformKey
+)
+
+// props is a set of properties.
+type props int64
+
+// set sets a property.
+func (p props) set(k propKey) props {
+ return p | props(k)
+}
+
+// unset unsets a property.
+func (p props) unset(k propKey) props {
+ return p &^ props(k)
+}
+
+// has checks if a property is set.
+func (p props) has(k propKey) bool {
+ return p&props(k) != 0
+}
+
+// NewStyle returns a new, empty Style. While it's syntactic sugar for the
+// Style{} primitive, it's recommended to use this function for creating styles
+// in case the underlying implementation changes. It takes an optional string
+// value to be set as the underlying string value for this style.
+func NewStyle() Style {
+ return renderer.NewStyle()
+}
+
+// NewStyle returns a new, empty Style. While it's syntactic sugar for the
+// Style{} primitive, it's recommended to use this function for creating styles
+// in case the underlying implementation changes. It takes an optional string
+// value to be set as the underlying string value for this style.
+func (r *Renderer) NewStyle() Style {
+ s := Style{r: r}
+ return s
+}
+
+// Style contains a set of rules that comprise a style as a whole.
+type Style struct {
+ r *Renderer
+ props props
+ value string
+
+ // we store bool props values here
+ attrs int
+
+ // props that have values
+ fgColor TerminalColor
+ bgColor TerminalColor
+
+ width int
+ height int
+
+ alignHorizontal Position
+ alignVertical Position
+
+ paddingTop int
+ paddingRight int
+ paddingBottom int
+ paddingLeft int
+
+ marginTop int
+ marginRight int
+ marginBottom int
+ marginLeft int
+ marginBgColor TerminalColor
+
+ borderStyle Border
+ borderTopFgColor TerminalColor
+ borderRightFgColor TerminalColor
+ borderBottomFgColor TerminalColor
+ borderLeftFgColor TerminalColor
+ borderTopBgColor TerminalColor
+ borderRightBgColor TerminalColor
+ borderBottomBgColor TerminalColor
+ borderLeftBgColor TerminalColor
+
+ maxWidth int
+ maxHeight int
+ tabWidth int
+
+ transform func(string) string
+}
+
+// joinString joins a list of strings into a single string separated with a
+// space.
+func joinString(strs ...string) string {
+ return strings.Join(strs, " ")
+}
+
+// SetString sets the underlying string value for this style. To render once
+// the underlying string is set, use the Style.String. This method is
+// a convenience for cases when having a stringer implementation is handy, such
+// as when using fmt.Sprintf. You can also simply define a style and render out
+// strings directly with Style.Render.
+func (s Style) SetString(strs ...string) Style {
+ s.value = joinString(strs...)
+ return s
+}
+
+// Value returns the raw, unformatted, underlying string value for this style.
+func (s Style) Value() string {
+ return s.value
+}
+
+// String implements stringer for a Style, returning the rendered result based
+// on the rules in this style. An underlying string value must be set with
+// Style.SetString prior to using this method.
+func (s Style) String() string {
+ return s.Render()
+}
+
+// Copy returns a copy of this style, including any underlying string values.
+//
+// Deprecated: to copy just use assignment (i.e. a := b). All methods also
+// return a new style.
+func (s Style) Copy() Style {
+ return s
+}
+
+// Inherit overlays the style in the argument onto this style by copying each explicitly
+// set value from the argument style onto this style if it is not already explicitly set.
+// Existing set values are kept intact and not overwritten.
+//
+// Margins, padding, and underlying string values are not inherited.
+func (s Style) Inherit(i Style) Style {
+ for k := boldKey; k <= transformKey; k <<= 1 {
+ if !i.isSet(k) {
+ continue
+ }
+
+ switch k { //nolint:exhaustive
+ case marginTopKey, marginRightKey, marginBottomKey, marginLeftKey:
+ // Margins are not inherited
+ continue
+ case paddingTopKey, paddingRightKey, paddingBottomKey, paddingLeftKey:
+ // Padding is not inherited
+ continue
+ case backgroundKey:
+ // The margins also inherit the background color
+ if !s.isSet(marginBackgroundKey) && !i.isSet(marginBackgroundKey) {
+ s.set(marginBackgroundKey, i.bgColor)
+ }
+ }
+
+ if s.isSet(k) {
+ continue
+ }
+
+ s.setFrom(k, i)
+ }
+ return s
+}
+
+// Render applies the defined style formatting to a given string.
+func (s Style) Render(strs ...string) string {
+ if s.r == nil {
+ s.r = renderer
+ }
+ if s.value != "" {
+ strs = append([]string{s.value}, strs...)
+ }
+
+ var (
+ str = joinString(strs...)
+
+ p = s.r.ColorProfile()
+ te = p.String()
+ teSpace = p.String()
+ teWhitespace = p.String()
+
+ bold = s.getAsBool(boldKey, false)
+ italic = s.getAsBool(italicKey, false)
+ underline = s.getAsBool(underlineKey, false)
+ strikethrough = s.getAsBool(strikethroughKey, false)
+ reverse = s.getAsBool(reverseKey, false)
+ blink = s.getAsBool(blinkKey, false)
+ faint = s.getAsBool(faintKey, false)
+
+ fg = s.getAsColor(foregroundKey)
+ bg = s.getAsColor(backgroundKey)
+
+ width = s.getAsInt(widthKey)
+ height = s.getAsInt(heightKey)
+ horizontalAlign = s.getAsPosition(alignHorizontalKey)
+ verticalAlign = s.getAsPosition(alignVerticalKey)
+
+ topPadding = s.getAsInt(paddingTopKey)
+ rightPadding = s.getAsInt(paddingRightKey)
+ bottomPadding = s.getAsInt(paddingBottomKey)
+ leftPadding = s.getAsInt(paddingLeftKey)
+
+ colorWhitespace = s.getAsBool(colorWhitespaceKey, true)
+ inline = s.getAsBool(inlineKey, false)
+ maxWidth = s.getAsInt(maxWidthKey)
+ maxHeight = s.getAsInt(maxHeightKey)
+
+ underlineSpaces = s.getAsBool(underlineSpacesKey, false) || (underline && s.getAsBool(underlineSpacesKey, true))
+ strikethroughSpaces = s.getAsBool(strikethroughSpacesKey, false) || (strikethrough && s.getAsBool(strikethroughSpacesKey, true))
+
+ // Do we need to style whitespace (padding and space outside
+ // paragraphs) separately?
+ styleWhitespace = reverse
+
+ // Do we need to style spaces separately?
+ useSpaceStyler = (underline && !underlineSpaces) || (strikethrough && !strikethroughSpaces) || underlineSpaces || strikethroughSpaces
+
+ transform = s.getAsTransform(transformKey)
+ )
+
+ if transform != nil {
+ str = transform(str)
+ }
+
+ if s.props == 0 {
+ return s.maybeConvertTabs(str)
+ }
+
+ // Enable support for ANSI on the legacy Windows cmd.exe console. This is a
+ // no-op on non-Windows systems and on Windows runs only once.
+ enableLegacyWindowsANSI()
+
+ if bold {
+ te = te.Bold()
+ }
+ if italic {
+ te = te.Italic()
+ }
+ if underline {
+ te = te.Underline()
+ }
+ if reverse {
+ teWhitespace = teWhitespace.Reverse()
+ te = te.Reverse()
+ }
+ if blink {
+ te = te.Blink()
+ }
+ if faint {
+ te = te.Faint()
+ }
+
+ if fg != noColor {
+ te = te.Foreground(fg.color(s.r))
+ if styleWhitespace {
+ teWhitespace = teWhitespace.Foreground(fg.color(s.r))
+ }
+ if useSpaceStyler {
+ teSpace = teSpace.Foreground(fg.color(s.r))
+ }
+ }
+
+ if bg != noColor {
+ te = te.Background(bg.color(s.r))
+ if colorWhitespace {
+ teWhitespace = teWhitespace.Background(bg.color(s.r))
+ }
+ if useSpaceStyler {
+ teSpace = teSpace.Background(bg.color(s.r))
+ }
+ }
+
+ if underline {
+ te = te.Underline()
+ }
+ if strikethrough {
+ te = te.CrossOut()
+ }
+
+ if underlineSpaces {
+ teSpace = teSpace.Underline()
+ }
+ if strikethroughSpaces {
+ teSpace = teSpace.CrossOut()
+ }
+
+ // Potentially convert tabs to spaces
+ str = s.maybeConvertTabs(str)
+ // carriage returns can cause strange behaviour when rendering.
+ str = strings.ReplaceAll(str, "\r\n", "\n")
+
+ // Strip newlines in single line mode
+ if inline {
+ str = strings.ReplaceAll(str, "\n", "")
+ }
+
+ // Word wrap
+ if !inline && width > 0 {
+ wrapAt := width - leftPadding - rightPadding
+ str = ansi.Wrap(str, wrapAt, "")
+ }
+
+ // Render core text
+ {
+ var b strings.Builder
+
+ l := strings.Split(str, "\n")
+ for i := range l {
+ if useSpaceStyler {
+ // Look for spaces and apply a different styler
+ for _, r := range l[i] {
+ if unicode.IsSpace(r) {
+ b.WriteString(teSpace.Styled(string(r)))
+ continue
+ }
+ b.WriteString(te.Styled(string(r)))
+ }
+ } else {
+ b.WriteString(te.Styled(l[i]))
+ }
+ if i != len(l)-1 {
+ b.WriteRune('\n')
+ }
+ }
+
+ str = b.String()
+ }
+
+ // Padding
+ if !inline { //nolint:nestif
+ if leftPadding > 0 {
+ var st *termenv.Style
+ if colorWhitespace || styleWhitespace {
+ st = &teWhitespace
+ }
+ str = padLeft(str, leftPadding, st)
+ }
+
+ if rightPadding > 0 {
+ var st *termenv.Style
+ if colorWhitespace || styleWhitespace {
+ st = &teWhitespace
+ }
+ str = padRight(str, rightPadding, st)
+ }
+
+ if topPadding > 0 {
+ str = strings.Repeat("\n", topPadding) + str
+ }
+
+ if bottomPadding > 0 {
+ str += strings.Repeat("\n", bottomPadding)
+ }
+ }
+
+ // Height
+ if height > 0 {
+ str = alignTextVertical(str, verticalAlign, height, nil)
+ }
+
+ // Set alignment. This will also pad short lines with spaces so that all
+ // lines are the same length, so we run it under a few different conditions
+ // beyond alignment.
+ {
+ numLines := strings.Count(str, "\n")
+
+ if !(numLines == 0 && width == 0) {
+ var st *termenv.Style
+ if colorWhitespace || styleWhitespace {
+ st = &teWhitespace
+ }
+ str = alignTextHorizontal(str, horizontalAlign, width, st)
+ }
+ }
+
+ if !inline {
+ str = s.applyBorder(str)
+ str = s.applyMargins(str, inline)
+ }
+
+ // Truncate according to MaxWidth
+ if maxWidth > 0 {
+ lines := strings.Split(str, "\n")
+
+ for i := range lines {
+ lines[i] = ansi.Truncate(lines[i], maxWidth, "")
+ }
+
+ str = strings.Join(lines, "\n")
+ }
+
+ // Truncate according to MaxHeight
+ if maxHeight > 0 {
+ lines := strings.Split(str, "\n")
+ height := min(maxHeight, len(lines))
+ if len(lines) > 0 {
+ str = strings.Join(lines[:height], "\n")
+ }
+ }
+
+ return str
+}
+
+func (s Style) maybeConvertTabs(str string) string {
+ tw := tabWidthDefault
+ if s.isSet(tabWidthKey) {
+ tw = s.getAsInt(tabWidthKey)
+ }
+ switch tw {
+ case -1:
+ return str
+ case 0:
+ return strings.ReplaceAll(str, "\t", "")
+ default:
+ return strings.ReplaceAll(str, "\t", strings.Repeat(" ", tw))
+ }
+}
+
+func (s Style) applyMargins(str string, inline bool) string {
+ var (
+ topMargin = s.getAsInt(marginTopKey)
+ rightMargin = s.getAsInt(marginRightKey)
+ bottomMargin = s.getAsInt(marginBottomKey)
+ leftMargin = s.getAsInt(marginLeftKey)
+
+ styler termenv.Style
+ )
+
+ bgc := s.getAsColor(marginBackgroundKey)
+ if bgc != noColor {
+ styler = styler.Background(bgc.color(s.r))
+ }
+
+ // Add left and right margin
+ str = padLeft(str, leftMargin, &styler)
+ str = padRight(str, rightMargin, &styler)
+
+ // Top/bottom margin
+ if !inline {
+ _, width := getLines(str)
+ spaces := strings.Repeat(" ", width)
+
+ if topMargin > 0 {
+ str = styler.Styled(strings.Repeat(spaces+"\n", topMargin)) + str
+ }
+ if bottomMargin > 0 {
+ str += styler.Styled(strings.Repeat("\n"+spaces, bottomMargin))
+ }
+ }
+
+ return str
+}
+
+// Apply left padding.
+func padLeft(str string, n int, style *termenv.Style) string {
+ return pad(str, -n, style)
+}
+
+// Apply right padding.
+func padRight(str string, n int, style *termenv.Style) string {
+ return pad(str, n, style)
+}
+
+// pad adds padding to either the left or right side of a string.
+// Positive values add to the right side while negative values
+// add to the left side.
+func pad(str string, n int, style *termenv.Style) string {
+ if n == 0 {
+ return str
+ }
+
+ sp := strings.Repeat(" ", abs(n))
+ if style != nil {
+ sp = style.Styled(sp)
+ }
+
+ b := strings.Builder{}
+ l := strings.Split(str, "\n")
+
+ for i := range l {
+ switch {
+ // pad right
+ case n > 0:
+ b.WriteString(l[i])
+ b.WriteString(sp)
+ // pad left
+ default:
+ b.WriteString(sp)
+ b.WriteString(l[i])
+ }
+
+ if i != len(l)-1 {
+ b.WriteRune('\n')
+ }
+ }
+
+ return b.String()
+}
+
+func max(a, b int) int { //nolint:unparam,predeclared
+ if a > b {
+ return a
+ }
+ return b
+}
+
+func min(a, b int) int { //nolint:predeclared
+ if a < b {
+ return a
+ }
+ return b
+}
+
+func abs(a int) int {
+ if a < 0 {
+ return -a
+ }
+
+ return a
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/unset.go b/vendor/github.com/charmbracelet/lipgloss/unset.go
new file mode 100644
index 0000000..1086e72
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/unset.go
@@ -0,0 +1,331 @@
+package lipgloss
+
+// unset unsets a property from a style.
+func (s *Style) unset(key propKey) {
+ s.props = s.props.unset(key)
+}
+
+// UnsetBold removes the bold style rule, if set.
+func (s Style) UnsetBold() Style {
+ s.unset(boldKey)
+ return s
+}
+
+// UnsetItalic removes the italic style rule, if set.
+func (s Style) UnsetItalic() Style {
+ s.unset(italicKey)
+ return s
+}
+
+// UnsetUnderline removes the underline style rule, if set.
+func (s Style) UnsetUnderline() Style {
+ s.unset(underlineKey)
+ return s
+}
+
+// UnsetStrikethrough removes the strikethrough style rule, if set.
+func (s Style) UnsetStrikethrough() Style {
+ s.unset(strikethroughKey)
+ return s
+}
+
+// UnsetReverse removes the reverse style rule, if set.
+func (s Style) UnsetReverse() Style {
+ s.unset(reverseKey)
+ return s
+}
+
+// UnsetBlink removes the blink style rule, if set.
+func (s Style) UnsetBlink() Style {
+ s.unset(blinkKey)
+ return s
+}
+
+// UnsetFaint removes the faint style rule, if set.
+func (s Style) UnsetFaint() Style {
+ s.unset(faintKey)
+ return s
+}
+
+// UnsetForeground removes the foreground style rule, if set.
+func (s Style) UnsetForeground() Style {
+ s.unset(foregroundKey)
+ return s
+}
+
+// UnsetBackground removes the background style rule, if set.
+func (s Style) UnsetBackground() Style {
+ s.unset(backgroundKey)
+ return s
+}
+
+// UnsetWidth removes the width style rule, if set.
+func (s Style) UnsetWidth() Style {
+ s.unset(widthKey)
+ return s
+}
+
+// UnsetHeight removes the height style rule, if set.
+func (s Style) UnsetHeight() Style {
+ s.unset(heightKey)
+ return s
+}
+
+// UnsetAlign removes the horizontal and vertical text alignment style rule, if set.
+func (s Style) UnsetAlign() Style {
+ s.unset(alignHorizontalKey)
+ s.unset(alignVerticalKey)
+ return s
+}
+
+// UnsetAlignHorizontal removes the horizontal text alignment style rule, if set.
+func (s Style) UnsetAlignHorizontal() Style {
+ s.unset(alignHorizontalKey)
+ return s
+}
+
+// UnsetAlignVertical removes the vertical text alignment style rule, if set.
+func (s Style) UnsetAlignVertical() Style {
+ s.unset(alignVerticalKey)
+ return s
+}
+
+// UnsetPadding removes all padding style rules.
+func (s Style) UnsetPadding() Style {
+ s.unset(paddingLeftKey)
+ s.unset(paddingRightKey)
+ s.unset(paddingTopKey)
+ s.unset(paddingBottomKey)
+ return s
+}
+
+// UnsetPaddingLeft removes the left padding style rule, if set.
+func (s Style) UnsetPaddingLeft() Style {
+ s.unset(paddingLeftKey)
+ return s
+}
+
+// UnsetPaddingRight removes the right padding style rule, if set.
+func (s Style) UnsetPaddingRight() Style {
+ s.unset(paddingRightKey)
+ return s
+}
+
+// UnsetPaddingTop removes the top padding style rule, if set.
+func (s Style) UnsetPaddingTop() Style {
+ s.unset(paddingTopKey)
+ return s
+}
+
+// UnsetPaddingBottom removes the bottom padding style rule, if set.
+func (s Style) UnsetPaddingBottom() Style {
+ s.unset(paddingBottomKey)
+ return s
+}
+
+// UnsetColorWhitespace removes the rule for coloring padding, if set.
+func (s Style) UnsetColorWhitespace() Style {
+ s.unset(colorWhitespaceKey)
+ return s
+}
+
+// UnsetMargins removes all margin style rules.
+func (s Style) UnsetMargins() Style {
+ s.unset(marginLeftKey)
+ s.unset(marginRightKey)
+ s.unset(marginTopKey)
+ s.unset(marginBottomKey)
+ return s
+}
+
+// UnsetMarginLeft removes the left margin style rule, if set.
+func (s Style) UnsetMarginLeft() Style {
+ s.unset(marginLeftKey)
+ return s
+}
+
+// UnsetMarginRight removes the right margin style rule, if set.
+func (s Style) UnsetMarginRight() Style {
+ s.unset(marginRightKey)
+ return s
+}
+
+// UnsetMarginTop removes the top margin style rule, if set.
+func (s Style) UnsetMarginTop() Style {
+ s.unset(marginTopKey)
+ return s
+}
+
+// UnsetMarginBottom removes the bottom margin style rule, if set.
+func (s Style) UnsetMarginBottom() Style {
+ s.unset(marginBottomKey)
+ return s
+}
+
+// UnsetMarginBackground removes the margin's background color. Note that the
+// margin's background color can be set from the background color of another
+// style during inheritance.
+func (s Style) UnsetMarginBackground() Style {
+ s.unset(marginBackgroundKey)
+ return s
+}
+
+// UnsetBorderStyle removes the border style rule, if set.
+func (s Style) UnsetBorderStyle() Style {
+ s.unset(borderStyleKey)
+ return s
+}
+
+// UnsetBorderTop removes the border top style rule, if set.
+func (s Style) UnsetBorderTop() Style {
+ s.unset(borderTopKey)
+ return s
+}
+
+// UnsetBorderRight removes the border right style rule, if set.
+func (s Style) UnsetBorderRight() Style {
+ s.unset(borderRightKey)
+ return s
+}
+
+// UnsetBorderBottom removes the border bottom style rule, if set.
+func (s Style) UnsetBorderBottom() Style {
+ s.unset(borderBottomKey)
+ return s
+}
+
+// UnsetBorderLeft removes the border left style rule, if set.
+func (s Style) UnsetBorderLeft() Style {
+ s.unset(borderLeftKey)
+ return s
+}
+
+// UnsetBorderForeground removes all border foreground color styles, if set.
+func (s Style) UnsetBorderForeground() Style {
+ s.unset(borderTopForegroundKey)
+ s.unset(borderRightForegroundKey)
+ s.unset(borderBottomForegroundKey)
+ s.unset(borderLeftForegroundKey)
+ return s
+}
+
+// UnsetBorderTopForeground removes the top border foreground color rule,
+// if set.
+func (s Style) UnsetBorderTopForeground() Style {
+ s.unset(borderTopForegroundKey)
+ return s
+}
+
+// UnsetBorderRightForeground removes the right border foreground color rule,
+// if set.
+func (s Style) UnsetBorderRightForeground() Style {
+ s.unset(borderRightForegroundKey)
+ return s
+}
+
+// UnsetBorderBottomForeground removes the bottom border foreground color
+// rule, if set.
+func (s Style) UnsetBorderBottomForeground() Style {
+ s.unset(borderBottomForegroundKey)
+ return s
+}
+
+// UnsetBorderLeftForeground removes the left border foreground color rule,
+// if set.
+func (s Style) UnsetBorderLeftForeground() Style {
+ s.unset(borderLeftForegroundKey)
+ return s
+}
+
+// UnsetBorderBackground removes all border background color styles, if
+// set.
+func (s Style) UnsetBorderBackground() Style {
+ s.unset(borderTopBackgroundKey)
+ s.unset(borderRightBackgroundKey)
+ s.unset(borderBottomBackgroundKey)
+ s.unset(borderLeftBackgroundKey)
+ return s
+}
+
+// UnsetBorderTopBackgroundColor removes the top border background color rule,
+// if set.
+//
+// Deprecated: This function simply calls Style.UnsetBorderTopBackground.
+func (s Style) UnsetBorderTopBackgroundColor() Style {
+ return s.UnsetBorderTopBackground()
+}
+
+// UnsetBorderTopBackground removes the top border background color rule,
+// if set.
+func (s Style) UnsetBorderTopBackground() Style {
+ s.unset(borderTopBackgroundKey)
+ return s
+}
+
+// UnsetBorderRightBackground removes the right border background color
+// rule, if set.
+func (s Style) UnsetBorderRightBackground() Style {
+ s.unset(borderRightBackgroundKey)
+ return s
+}
+
+// UnsetBorderBottomBackground removes the bottom border background color
+// rule, if set.
+func (s Style) UnsetBorderBottomBackground() Style {
+ s.unset(borderBottomBackgroundKey)
+ return s
+}
+
+// UnsetBorderLeftBackground removes the left border color rule, if set.
+func (s Style) UnsetBorderLeftBackground() Style {
+ s.unset(borderLeftBackgroundKey)
+ return s
+}
+
+// UnsetInline removes the inline style rule, if set.
+func (s Style) UnsetInline() Style {
+ s.unset(inlineKey)
+ return s
+}
+
+// UnsetMaxWidth removes the max width style rule, if set.
+func (s Style) UnsetMaxWidth() Style {
+ s.unset(maxWidthKey)
+ return s
+}
+
+// UnsetMaxHeight removes the max height style rule, if set.
+func (s Style) UnsetMaxHeight() Style {
+ s.unset(maxHeightKey)
+ return s
+}
+
+// UnsetTabWidth removes the tab width style rule, if set.
+func (s Style) UnsetTabWidth() Style {
+ s.unset(tabWidthKey)
+ return s
+}
+
+// UnsetUnderlineSpaces removes the value set by UnderlineSpaces.
+func (s Style) UnsetUnderlineSpaces() Style {
+ s.unset(underlineSpacesKey)
+ return s
+}
+
+// UnsetStrikethroughSpaces removes the value set by StrikethroughSpaces.
+func (s Style) UnsetStrikethroughSpaces() Style {
+ s.unset(strikethroughSpacesKey)
+ return s
+}
+
+// UnsetTransform removes the value set by Transform.
+func (s Style) UnsetTransform() Style {
+ s.unset(transformKey)
+ return s
+}
+
+// UnsetString sets the underlying string value to the empty string.
+func (s Style) UnsetString() Style {
+ s.value = ""
+ return s
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/whitespace.go b/vendor/github.com/charmbracelet/lipgloss/whitespace.go
new file mode 100644
index 0000000..040dc98
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/whitespace.go
@@ -0,0 +1,83 @@
+package lipgloss
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+ "github.com/muesli/termenv"
+)
+
+// whitespace is a whitespace renderer.
+type whitespace struct {
+ re *Renderer
+ style termenv.Style
+ chars string
+}
+
+// newWhitespace creates a new whitespace renderer. The order of the options
+// matters, if you're using WithWhitespaceRenderer, make sure it comes first as
+// other options might depend on it.
+func newWhitespace(r *Renderer, opts ...WhitespaceOption) *whitespace {
+ w := &whitespace{
+ re: r,
+ style: r.ColorProfile().String(),
+ }
+ for _, opt := range opts {
+ opt(w)
+ }
+ return w
+}
+
+// Render whitespaces.
+func (w whitespace) render(width int) string {
+ if w.chars == "" {
+ w.chars = " "
+ }
+
+ r := []rune(w.chars)
+ j := 0
+ b := strings.Builder{}
+
+ // Cycle through runes and print them into the whitespace.
+ for i := 0; i < width; {
+ b.WriteRune(r[j])
+ j++
+ if j >= len(r) {
+ j = 0
+ }
+ i += ansi.StringWidth(string(r[j]))
+ }
+
+ // Fill any extra gaps white spaces. This might be necessary if any runes
+ // are more than one cell wide, which could leave a one-rune gap.
+ short := width - ansi.StringWidth(b.String())
+ if short > 0 {
+ b.WriteString(strings.Repeat(" ", short))
+ }
+
+ return w.style.Styled(b.String())
+}
+
+// WhitespaceOption sets a styling rule for rendering whitespace.
+type WhitespaceOption func(*whitespace)
+
+// WithWhitespaceForeground sets the color of the characters in the whitespace.
+func WithWhitespaceForeground(c TerminalColor) WhitespaceOption {
+ return func(w *whitespace) {
+ w.style = w.style.Foreground(c.color(w.re))
+ }
+}
+
+// WithWhitespaceBackground sets the background color of the whitespace.
+func WithWhitespaceBackground(c TerminalColor) WhitespaceOption {
+ return func(w *whitespace) {
+ w.style = w.style.Background(c.color(w.re))
+ }
+}
+
+// WithWhitespaceChars sets the characters to be rendered in the whitespace.
+func WithWhitespaceChars(s string) WhitespaceOption {
+ return func(w *whitespace) {
+ w.chars = s
+ }
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/LICENSE b/vendor/github.com/charmbracelet/x/ansi/LICENSE
new file mode 100644
index 0000000..65a5654
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 Charmbracelet, Inc.
+
+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/vendor/github.com/charmbracelet/x/ansi/ansi.go b/vendor/github.com/charmbracelet/x/ansi/ansi.go
new file mode 100644
index 0000000..48d873c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/ansi.go
@@ -0,0 +1,11 @@
+package ansi
+
+import "io"
+
+// Execute is a function that "execute" the given escape sequence by writing it
+// to the provided output writter.
+//
+// This is a syntactic sugar over [io.WriteString].
+func Execute(w io.Writer, s string) (int, error) {
+ return io.WriteString(w, s)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/ascii.go b/vendor/github.com/charmbracelet/x/ansi/ascii.go
new file mode 100644
index 0000000..188582f
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/ascii.go
@@ -0,0 +1,8 @@
+package ansi
+
+const (
+ // SP is the space character (Char: \x20).
+ SP = 0x20
+ // DEL is the delete character (Caret: ^?, Char: \x7f).
+ DEL = 0x7F
+)
diff --git a/vendor/github.com/charmbracelet/x/ansi/background.go b/vendor/github.com/charmbracelet/x/ansi/background.go
new file mode 100644
index 0000000..2383cf0
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/background.go
@@ -0,0 +1,169 @@
+package ansi
+
+import (
+ "fmt"
+ "image/color"
+)
+
+// Colorizer is a [color.Color] interface that can be formatted as a string.
+type Colorizer interface {
+ color.Color
+ fmt.Stringer
+}
+
+// HexColorizer is a [color.Color] that can be formatted as a hex string.
+type HexColorizer struct{ color.Color }
+
+var _ Colorizer = HexColorizer{}
+
+// String returns the color as a hex string. If the color is nil, an empty
+// string is returned.
+func (h HexColorizer) String() string {
+ if h.Color == nil {
+ return ""
+ }
+ r, g, b, _ := h.RGBA()
+ // Get the lower 8 bits
+ r &= 0xff
+ g &= 0xff
+ b &= 0xff
+ return fmt.Sprintf("#%02x%02x%02x", uint8(r), uint8(g), uint8(b)) //nolint:gosec
+}
+
+// XRGBColorizer is a [color.Color] that can be formatted as an XParseColor
+// rgb: string.
+//
+// See: https://linux.die.net/man/3/xparsecolor
+type XRGBColorizer struct{ color.Color }
+
+var _ Colorizer = XRGBColorizer{}
+
+// String returns the color as an XParseColor rgb: string. If the color is nil,
+// an empty string is returned.
+func (x XRGBColorizer) String() string {
+ if x.Color == nil {
+ return ""
+ }
+ r, g, b, _ := x.RGBA()
+ // Get the lower 8 bits
+ return fmt.Sprintf("rgb:%04x/%04x/%04x", r, g, b)
+}
+
+// XRGBAColorizer is a [color.Color] that can be formatted as an XParseColor
+// rgba: string.
+//
+// See: https://linux.die.net/man/3/xparsecolor
+type XRGBAColorizer struct{ color.Color }
+
+var _ Colorizer = XRGBAColorizer{}
+
+// String returns the color as an XParseColor rgba: string. If the color is nil,
+// an empty string is returned.
+func (x XRGBAColorizer) String() string {
+ if x.Color == nil {
+ return ""
+ }
+ r, g, b, a := x.RGBA()
+ // Get the lower 8 bits
+ return fmt.Sprintf("rgba:%04x/%04x/%04x/%04x", r, g, b, a)
+}
+
+// SetForegroundColor returns a sequence that sets the default terminal
+// foreground color.
+//
+// OSC 10 ; color ST
+// OSC 10 ; color BEL
+//
+// Where color is the encoded color number.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+func SetForegroundColor(c color.Color) string {
+ var s string
+ switch c := c.(type) {
+ case Colorizer:
+ s = c.String()
+ case fmt.Stringer:
+ s = c.String()
+ default:
+ s = HexColorizer{c}.String()
+ }
+ return "\x1b]10;" + s + "\x07"
+}
+
+// RequestForegroundColor is a sequence that requests the current default
+// terminal foreground color.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+const RequestForegroundColor = "\x1b]10;?\x07"
+
+// ResetForegroundColor is a sequence that resets the default terminal
+// foreground color.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+const ResetForegroundColor = "\x1b]110\x07"
+
+// SetBackgroundColor returns a sequence that sets the default terminal
+// background color.
+//
+// OSC 11 ; color ST
+// OSC 11 ; color BEL
+//
+// Where color is the encoded color number.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+func SetBackgroundColor(c color.Color) string {
+ var s string
+ switch c := c.(type) {
+ case Colorizer:
+ s = c.String()
+ case fmt.Stringer:
+ s = c.String()
+ default:
+ s = HexColorizer{c}.String()
+ }
+ return "\x1b]11;" + s + "\x07"
+}
+
+// RequestBackgroundColor is a sequence that requests the current default
+// terminal background color.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+const RequestBackgroundColor = "\x1b]11;?\x07"
+
+// ResetBackgroundColor is a sequence that resets the default terminal
+// background color.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+const ResetBackgroundColor = "\x1b]111\x07"
+
+// SetCursorColor returns a sequence that sets the terminal cursor color.
+//
+// OSC 12 ; color ST
+// OSC 12 ; color BEL
+//
+// Where color is the encoded color number.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+func SetCursorColor(c color.Color) string {
+ var s string
+ switch c := c.(type) {
+ case Colorizer:
+ s = c.String()
+ case fmt.Stringer:
+ s = c.String()
+ default:
+ s = HexColorizer{c}.String()
+ }
+ return "\x1b]12;" + s + "\x07"
+}
+
+// RequestCursorColor is a sequence that requests the current terminal cursor
+// color.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+const RequestCursorColor = "\x1b]12;?\x07"
+
+// ResetCursorColor is a sequence that resets the terminal cursor color.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+const ResetCursorColor = "\x1b]112\x07"
diff --git a/vendor/github.com/charmbracelet/x/ansi/c0.go b/vendor/github.com/charmbracelet/x/ansi/c0.go
new file mode 100644
index 0000000..28ff7c2
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/c0.go
@@ -0,0 +1,79 @@
+package ansi
+
+// C0 control characters.
+//
+// These range from (0x00-0x1F) as defined in ISO 646 (ASCII).
+// See: https://en.wikipedia.org/wiki/C0_and_C1_control_codes
+const (
+ // NUL is the null character (Caret: ^@, Char: \0).
+ NUL = 0x00
+ // SOH is the start of heading character (Caret: ^A).
+ SOH = 0x01
+ // STX is the start of text character (Caret: ^B).
+ STX = 0x02
+ // ETX is the end of text character (Caret: ^C).
+ ETX = 0x03
+ // EOT is the end of transmission character (Caret: ^D).
+ EOT = 0x04
+ // ENQ is the enquiry character (Caret: ^E).
+ ENQ = 0x05
+ // ACK is the acknowledge character (Caret: ^F).
+ ACK = 0x06
+ // BEL is the bell character (Caret: ^G, Char: \a).
+ BEL = 0x07
+ // BS is the backspace character (Caret: ^H, Char: \b).
+ BS = 0x08
+ // HT is the horizontal tab character (Caret: ^I, Char: \t).
+ HT = 0x09
+ // LF is the line feed character (Caret: ^J, Char: \n).
+ LF = 0x0A
+ // VT is the vertical tab character (Caret: ^K, Char: \v).
+ VT = 0x0B
+ // FF is the form feed character (Caret: ^L, Char: \f).
+ FF = 0x0C
+ // CR is the carriage return character (Caret: ^M, Char: \r).
+ CR = 0x0D
+ // SO is the shift out character (Caret: ^N).
+ SO = 0x0E
+ // SI is the shift in character (Caret: ^O).
+ SI = 0x0F
+ // DLE is the data link escape character (Caret: ^P).
+ DLE = 0x10
+ // DC1 is the device control 1 character (Caret: ^Q).
+ DC1 = 0x11
+ // DC2 is the device control 2 character (Caret: ^R).
+ DC2 = 0x12
+ // DC3 is the device control 3 character (Caret: ^S).
+ DC3 = 0x13
+ // DC4 is the device control 4 character (Caret: ^T).
+ DC4 = 0x14
+ // NAK is the negative acknowledge character (Caret: ^U).
+ NAK = 0x15
+ // SYN is the synchronous idle character (Caret: ^V).
+ SYN = 0x16
+ // ETB is the end of transmission block character (Caret: ^W).
+ ETB = 0x17
+ // CAN is the cancel character (Caret: ^X).
+ CAN = 0x18
+ // EM is the end of medium character (Caret: ^Y).
+ EM = 0x19
+ // SUB is the substitute character (Caret: ^Z).
+ SUB = 0x1A
+ // ESC is the escape character (Caret: ^[, Char: \e).
+ ESC = 0x1B
+ // FS is the file separator character (Caret: ^\).
+ FS = 0x1C
+ // GS is the group separator character (Caret: ^]).
+ GS = 0x1D
+ // RS is the record separator character (Caret: ^^).
+ RS = 0x1E
+ // US is the unit separator character (Caret: ^_).
+ US = 0x1F
+
+ // LS0 is the locking shift 0 character.
+ // This is an alias for [SI].
+ LS0 = SI
+ // LS1 is the locking shift 1 character.
+ // This is an alias for [SO].
+ LS1 = SO
+)
diff --git a/vendor/github.com/charmbracelet/x/ansi/c1.go b/vendor/github.com/charmbracelet/x/ansi/c1.go
new file mode 100644
index 0000000..71058f5
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/c1.go
@@ -0,0 +1,72 @@
+package ansi
+
+// C1 control characters.
+//
+// These range from (0x80-0x9F) as defined in ISO 6429 (ECMA-48).
+// See: https://en.wikipedia.org/wiki/C0_and_C1_control_codes
+const (
+ // PAD is the padding character.
+ PAD = 0x80
+ // HOP is the high octet preset character.
+ HOP = 0x81
+ // BPH is the break permitted here character.
+ BPH = 0x82
+ // NBH is the no break here character.
+ NBH = 0x83
+ // IND is the index character.
+ IND = 0x84
+ // NEL is the next line character.
+ NEL = 0x85
+ // SSA is the start of selected area character.
+ SSA = 0x86
+ // ESA is the end of selected area character.
+ ESA = 0x87
+ // HTS is the horizontal tab set character.
+ HTS = 0x88
+ // HTJ is the horizontal tab with justification character.
+ HTJ = 0x89
+ // VTS is the vertical tab set character.
+ VTS = 0x8A
+ // PLD is the partial line forward character.
+ PLD = 0x8B
+ // PLU is the partial line backward character.
+ PLU = 0x8C
+ // RI is the reverse index character.
+ RI = 0x8D
+ // SS2 is the single shift 2 character.
+ SS2 = 0x8E
+ // SS3 is the single shift 3 character.
+ SS3 = 0x8F
+ // DCS is the device control string character.
+ DCS = 0x90
+ // PU1 is the private use 1 character.
+ PU1 = 0x91
+ // PU2 is the private use 2 character.
+ PU2 = 0x92
+ // STS is the set transmit state character.
+ STS = 0x93
+ // CCH is the cancel character.
+ CCH = 0x94
+ // MW is the message waiting character.
+ MW = 0x95
+ // SPA is the start of guarded area character.
+ SPA = 0x96
+ // EPA is the end of guarded area character.
+ EPA = 0x97
+ // SOS is the start of string character.
+ SOS = 0x98
+ // SGCI is the single graphic character introducer character.
+ SGCI = 0x99
+ // SCI is the single character introducer character.
+ SCI = 0x9A
+ // CSI is the control sequence introducer character.
+ CSI = 0x9B
+ // ST is the string terminator character.
+ ST = 0x9C
+ // OSC is the operating system command character.
+ OSC = 0x9D
+ // PM is the privacy message character.
+ PM = 0x9E
+ // APC is the application program command character.
+ APC = 0x9F
+)
diff --git a/vendor/github.com/charmbracelet/x/ansi/charset.go b/vendor/github.com/charmbracelet/x/ansi/charset.go
new file mode 100644
index 0000000..50fff51
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/charset.go
@@ -0,0 +1,55 @@
+package ansi
+
+// SelectCharacterSet sets the G-set character designator to the specified
+// character set.
+//
+// ESC Ps Pd
+//
+// Where Ps is the G-set character designator, and Pd is the identifier.
+// For 94-character sets, the designator can be one of:
+// - ( G0
+// - ) G1
+// - * G2
+// - + G3
+//
+// For 96-character sets, the designator can be one of:
+// - - G1
+// - . G2
+// - / G3
+//
+// Some common 94-character sets are:
+// - 0 DEC Special Drawing Set
+// - A United Kingdom (UK)
+// - B United States (USASCII)
+//
+// Examples:
+//
+// ESC ( B Select character set G0 = United States (USASCII)
+// ESC ( 0 Select character set G0 = Special Character and Line Drawing Set
+// ESC ) 0 Select character set G1 = Special Character and Line Drawing Set
+// ESC * A Select character set G2 = United Kingdom (UK)
+//
+// See: https://vt100.net/docs/vt510-rm/SCS.html
+func SelectCharacterSet(gset byte, charset byte) string {
+ return "\x1b" + string(gset) + string(charset)
+}
+
+// SCS is an alias for SelectCharacterSet.
+func SCS(gset byte, charset byte) string {
+ return SelectCharacterSet(gset, charset)
+}
+
+// Locking Shift 1 Right (LS1R) shifts G1 into GR character set.
+const LS1R = "\x1b~"
+
+// Locking Shift 2 (LS2) shifts G2 into GL character set.
+const LS2 = "\x1bn"
+
+// Locking Shift 2 Right (LS2R) shifts G2 into GR character set.
+const LS2R = "\x1b}"
+
+// Locking Shift 3 (LS3) shifts G3 into GL character set.
+const LS3 = "\x1bo"
+
+// Locking Shift 3 Right (LS3R) shifts G3 into GR character set.
+const LS3R = "\x1b|"
diff --git a/vendor/github.com/charmbracelet/x/ansi/clipboard.go b/vendor/github.com/charmbracelet/x/ansi/clipboard.go
new file mode 100644
index 0000000..94d26c3
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/clipboard.go
@@ -0,0 +1,75 @@
+package ansi
+
+import "encoding/base64"
+
+// Clipboard names.
+const (
+ SystemClipboard = 'c'
+ PrimaryClipboard = 'p'
+)
+
+// SetClipboard returns a sequence for manipulating the clipboard.
+//
+// OSC 52 ; Pc ; Pd ST
+// OSC 52 ; Pc ; Pd BEL
+//
+// Where Pc is the clipboard name and Pd is the base64 encoded data.
+// Empty data or invalid base64 data will reset the clipboard.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+func SetClipboard(c byte, d string) string {
+ if d != "" {
+ d = base64.StdEncoding.EncodeToString([]byte(d))
+ }
+ return "\x1b]52;" + string(c) + ";" + d + "\x07"
+}
+
+// SetSystemClipboard returns a sequence for setting the system clipboard.
+//
+// This is equivalent to SetClipboard(SystemClipboard, d).
+func SetSystemClipboard(d string) string {
+ return SetClipboard(SystemClipboard, d)
+}
+
+// SetPrimaryClipboard returns a sequence for setting the primary clipboard.
+//
+// This is equivalent to SetClipboard(PrimaryClipboard, d).
+func SetPrimaryClipboard(d string) string {
+ return SetClipboard(PrimaryClipboard, d)
+}
+
+// ResetClipboard returns a sequence for resetting the clipboard.
+//
+// This is equivalent to SetClipboard(c, "").
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+func ResetClipboard(c byte) string {
+ return SetClipboard(c, "")
+}
+
+// ResetSystemClipboard is a sequence for resetting the system clipboard.
+//
+// This is equivalent to ResetClipboard(SystemClipboard).
+const ResetSystemClipboard = "\x1b]52;c;\x07"
+
+// ResetPrimaryClipboard is a sequence for resetting the primary clipboard.
+//
+// This is equivalent to ResetClipboard(PrimaryClipboard).
+const ResetPrimaryClipboard = "\x1b]52;p;\x07"
+
+// RequestClipboard returns a sequence for requesting the clipboard.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+func RequestClipboard(c byte) string {
+ return "\x1b]52;" + string(c) + ";?\x07"
+}
+
+// RequestSystemClipboard is a sequence for requesting the system clipboard.
+//
+// This is equivalent to RequestClipboard(SystemClipboard).
+const RequestSystemClipboard = "\x1b]52;c;?\x07"
+
+// RequestPrimaryClipboard is a sequence for requesting the primary clipboard.
+//
+// This is equivalent to RequestClipboard(PrimaryClipboard).
+const RequestPrimaryClipboard = "\x1b]52;p;?\x07"
diff --git a/vendor/github.com/charmbracelet/x/ansi/color.go b/vendor/github.com/charmbracelet/x/ansi/color.go
new file mode 100644
index 0000000..77f8a08
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/color.go
@@ -0,0 +1,196 @@
+package ansi
+
+import (
+ "image/color"
+)
+
+// Technically speaking, the 16 basic ANSI colors are arbitrary and can be
+// customized at the terminal level. Given that, we're returning what we feel
+// are good defaults.
+//
+// This could also be a slice, but we use a map to make the mappings very
+// explicit.
+//
+// See: https://www.ditig.com/publications/256-colors-cheat-sheet
+var lowANSI = map[uint32]uint32{
+ 0: 0x000000, // black
+ 1: 0x800000, // red
+ 2: 0x008000, // green
+ 3: 0x808000, // yellow
+ 4: 0x000080, // blue
+ 5: 0x800080, // magenta
+ 6: 0x008080, // cyan
+ 7: 0xc0c0c0, // white
+ 8: 0x808080, // bright black
+ 9: 0xff0000, // bright red
+ 10: 0x00ff00, // bright green
+ 11: 0xffff00, // bright yellow
+ 12: 0x0000ff, // bright blue
+ 13: 0xff00ff, // bright magenta
+ 14: 0x00ffff, // bright cyan
+ 15: 0xffffff, // bright white
+}
+
+// Color is a color that can be used in a terminal. ANSI (including
+// ANSI256) and 24-bit "true colors" fall under this category.
+type Color interface {
+ color.Color
+}
+
+// BasicColor is an ANSI 3-bit or 4-bit color with a value from 0 to 15.
+type BasicColor uint8
+
+var _ Color = BasicColor(0)
+
+const (
+ // Black is the ANSI black color.
+ Black BasicColor = iota
+
+ // Red is the ANSI red color.
+ Red
+
+ // Green is the ANSI green color.
+ Green
+
+ // Yellow is the ANSI yellow color.
+ Yellow
+
+ // Blue is the ANSI blue color.
+ Blue
+
+ // Magenta is the ANSI magenta color.
+ Magenta
+
+ // Cyan is the ANSI cyan color.
+ Cyan
+
+ // White is the ANSI white color.
+ White
+
+ // BrightBlack is the ANSI bright black color.
+ BrightBlack
+
+ // BrightRed is the ANSI bright red color.
+ BrightRed
+
+ // BrightGreen is the ANSI bright green color.
+ BrightGreen
+
+ // BrightYellow is the ANSI bright yellow color.
+ BrightYellow
+
+ // BrightBlue is the ANSI bright blue color.
+ BrightBlue
+
+ // BrightMagenta is the ANSI bright magenta color.
+ BrightMagenta
+
+ // BrightCyan is the ANSI bright cyan color.
+ BrightCyan
+
+ // BrightWhite is the ANSI bright white color.
+ BrightWhite
+)
+
+// RGBA returns the red, green, blue and alpha components of the color. It
+// satisfies the color.Color interface.
+func (c BasicColor) RGBA() (uint32, uint32, uint32, uint32) {
+ ansi := uint32(c)
+ if ansi > 15 {
+ return 0, 0, 0, 0xffff
+ }
+
+ r, g, b := ansiToRGB(ansi)
+ return toRGBA(r, g, b)
+}
+
+// ExtendedColor is an ANSI 256 (8-bit) color with a value from 0 to 255.
+type ExtendedColor uint8
+
+var _ Color = ExtendedColor(0)
+
+// RGBA returns the red, green, blue and alpha components of the color. It
+// satisfies the color.Color interface.
+func (c ExtendedColor) RGBA() (uint32, uint32, uint32, uint32) {
+ r, g, b := ansiToRGB(uint32(c))
+ return toRGBA(r, g, b)
+}
+
+// TrueColor is a 24-bit color that can be used in the terminal.
+// This can be used to represent RGB colors.
+//
+// For example, the color red can be represented as:
+//
+// TrueColor(0xff0000)
+type TrueColor uint32
+
+var _ Color = TrueColor(0)
+
+// RGBA returns the red, green, blue and alpha components of the color. It
+// satisfies the color.Color interface.
+func (c TrueColor) RGBA() (uint32, uint32, uint32, uint32) {
+ r, g, b := hexToRGB(uint32(c))
+ return toRGBA(r, g, b)
+}
+
+// ansiToRGB converts an ANSI color to a 24-bit RGB color.
+//
+// r, g, b := ansiToRGB(57)
+func ansiToRGB(ansi uint32) (uint32, uint32, uint32) {
+ // For out-of-range values return black.
+ if ansi > 255 {
+ return 0, 0, 0
+ }
+
+ // Low ANSI.
+ if ansi < 16 {
+ h, ok := lowANSI[ansi]
+ if !ok {
+ return 0, 0, 0
+ }
+ r, g, b := hexToRGB(h)
+ return r, g, b
+ }
+
+ // Grays.
+ if ansi > 231 {
+ s := (ansi-232)*10 + 8
+ return s, s, s
+ }
+
+ // ANSI256.
+ n := ansi - 16
+ b := n % 6
+ g := (n - b) / 6 % 6
+ r := (n - b - g*6) / 36 % 6
+ for _, v := range []*uint32{&r, &g, &b} {
+ if *v > 0 {
+ c := *v*40 + 55
+ *v = c
+ }
+ }
+
+ return r, g, b
+}
+
+// hexToRGB converts a number in hexadecimal format to red, green, and blue
+// values.
+//
+// r, g, b := hexToRGB(0x0000FF)
+func hexToRGB(hex uint32) (uint32, uint32, uint32) {
+ return hex >> 16 & 0xff, hex >> 8 & 0xff, hex & 0xff
+}
+
+// toRGBA converts an RGB 8-bit color values to 32-bit color values suitable
+// for color.Color.
+//
+// color.Color requires 16-bit color values, so we duplicate the 8-bit values
+// to fill the 16-bit values.
+//
+// This always returns 0xffff (opaque) for the alpha channel.
+func toRGBA(r, g, b uint32) (uint32, uint32, uint32, uint32) {
+ r |= r << 8
+ g |= g << 8
+ b |= b << 8
+ return r, g, b, 0xffff
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/ctrl.go b/vendor/github.com/charmbracelet/x/ansi/ctrl.go
new file mode 100644
index 0000000..8ca744c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/ctrl.go
@@ -0,0 +1,137 @@
+package ansi
+
+import (
+ "strconv"
+ "strings"
+)
+
+// RequestNameVersion (XTVERSION) is a control sequence that requests the
+// terminal's name and version. It responds with a DSR sequence identifying the
+// terminal.
+//
+// CSI > 0 q
+// DCS > | text ST
+//
+// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-PC-Style-Function-Keys
+const (
+ RequestNameVersion = "\x1b[>q"
+ XTVERSION = RequestNameVersion
+)
+
+// RequestXTVersion is a control sequence that requests the terminal's XTVERSION. It responds with a DSR sequence identifying the version.
+//
+// CSI > Ps q
+// DCS > | text ST
+//
+// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-PC-Style-Function-Keys
+//
+// Deprecated: use [RequestNameVersion] instead.
+const RequestXTVersion = RequestNameVersion
+
+// PrimaryDeviceAttributes (DA1) is a control sequence that reports the
+// terminal's primary device attributes.
+//
+// CSI c
+// CSI 0 c
+// CSI ? Ps ; ... c
+//
+// If no attributes are given, or if the attribute is 0, this function returns
+// the request sequence. Otherwise, it returns the response sequence.
+//
+// See https://vt100.net/docs/vt510-rm/DA1.html
+func PrimaryDeviceAttributes(attrs ...int) string {
+ if len(attrs) == 0 {
+ return RequestPrimaryDeviceAttributes
+ } else if len(attrs) == 1 && attrs[0] == 0 {
+ return "\x1b[0c"
+ }
+
+ as := make([]string, len(attrs))
+ for i, a := range attrs {
+ as[i] = strconv.Itoa(a)
+ }
+ return "\x1b[?" + strings.Join(as, ";") + "c"
+}
+
+// DA1 is an alias for [PrimaryDeviceAttributes].
+func DA1(attrs ...int) string {
+ return PrimaryDeviceAttributes(attrs...)
+}
+
+// RequestPrimaryDeviceAttributes is a control sequence that requests the
+// terminal's primary device attributes (DA1).
+//
+// CSI c
+//
+// See https://vt100.net/docs/vt510-rm/DA1.html
+const RequestPrimaryDeviceAttributes = "\x1b[c"
+
+// SecondaryDeviceAttributes (DA2) is a control sequence that reports the
+// terminal's secondary device attributes.
+//
+// CSI > c
+// CSI > 0 c
+// CSI > Ps ; ... c
+//
+// See https://vt100.net/docs/vt510-rm/DA2.html
+func SecondaryDeviceAttributes(attrs ...int) string {
+ if len(attrs) == 0 {
+ return RequestSecondaryDeviceAttributes
+ }
+
+ as := make([]string, len(attrs))
+ for i, a := range attrs {
+ as[i] = strconv.Itoa(a)
+ }
+ return "\x1b[>" + strings.Join(as, ";") + "c"
+}
+
+// DA2 is an alias for [SecondaryDeviceAttributes].
+func DA2(attrs ...int) string {
+ return SecondaryDeviceAttributes(attrs...)
+}
+
+// RequestSecondaryDeviceAttributes is a control sequence that requests the
+// terminal's secondary device attributes (DA2).
+//
+// CSI > c
+//
+// See https://vt100.net/docs/vt510-rm/DA2.html
+const RequestSecondaryDeviceAttributes = "\x1b[>c"
+
+// TertiaryDeviceAttributes (DA3) is a control sequence that reports the
+// terminal's tertiary device attributes.
+//
+// CSI = c
+// CSI = 0 c
+// DCS ! | Text ST
+//
+// Where Text is the unit ID for the terminal.
+//
+// If no unit ID is given, or if the unit ID is 0, this function returns the
+// request sequence. Otherwise, it returns the response sequence.
+//
+// See https://vt100.net/docs/vt510-rm/DA3.html
+func TertiaryDeviceAttributes(unitID string) string {
+ switch unitID {
+ case "":
+ return RequestTertiaryDeviceAttributes
+ case "0":
+ return "\x1b[=0c"
+ }
+
+ return "\x1bP!|" + unitID + "\x1b\\"
+}
+
+// DA3 is an alias for [TertiaryDeviceAttributes].
+func DA3(unitID string) string {
+ return TertiaryDeviceAttributes(unitID)
+}
+
+// RequestTertiaryDeviceAttributes is a control sequence that requests the
+// terminal's tertiary device attributes (DA3).
+//
+// CSI = c
+//
+// See https://vt100.net/docs/vt510-rm/DA3.html
+const RequestTertiaryDeviceAttributes = "\x1b[=c"
diff --git a/vendor/github.com/charmbracelet/x/ansi/cursor.go b/vendor/github.com/charmbracelet/x/ansi/cursor.go
new file mode 100644
index 0000000..0c364d6
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/cursor.go
@@ -0,0 +1,633 @@
+package ansi
+
+import "strconv"
+
+// SaveCursor (DECSC) is an escape sequence that saves the current cursor
+// position.
+//
+// ESC 7
+//
+// See: https://vt100.net/docs/vt510-rm/DECSC.html
+const (
+ SaveCursor = "\x1b7"
+ DECSC = SaveCursor
+)
+
+// RestoreCursor (DECRC) is an escape sequence that restores the cursor
+// position.
+//
+// ESC 8
+//
+// See: https://vt100.net/docs/vt510-rm/DECRC.html
+const (
+ RestoreCursor = "\x1b8"
+ DECRC = RestoreCursor
+)
+
+// RequestCursorPosition is an escape sequence that requests the current cursor
+// position.
+//
+// CSI 6 n
+//
+// The terminal will report the cursor position as a CSI sequence in the
+// following format:
+//
+// CSI Pl ; Pc R
+//
+// Where Pl is the line number and Pc is the column number.
+// See: https://vt100.net/docs/vt510-rm/CPR.html
+//
+// Deprecated: use [RequestCursorPositionReport] instead.
+const RequestCursorPosition = "\x1b[6n"
+
+// RequestExtendedCursorPosition (DECXCPR) is a sequence for requesting the
+// cursor position report including the current page number.
+//
+// CSI ? 6 n
+//
+// The terminal will report the cursor position as a CSI sequence in the
+// following format:
+//
+// CSI ? Pl ; Pc ; Pp R
+//
+// Where Pl is the line number, Pc is the column number, and Pp is the page
+// number.
+// See: https://vt100.net/docs/vt510-rm/DECXCPR.html
+//
+// Deprecated: use [RequestExtendedCursorPositionReport] instead.
+const RequestExtendedCursorPosition = "\x1b[?6n"
+
+// CursorUp (CUU) returns a sequence for moving the cursor up n cells.
+//
+// CSI n A
+//
+// See: https://vt100.net/docs/vt510-rm/CUU.html
+func CursorUp(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "A"
+}
+
+// CUU is an alias for [CursorUp].
+func CUU(n int) string {
+ return CursorUp(n)
+}
+
+// CUU1 is a sequence for moving the cursor up one cell.
+const CUU1 = "\x1b[A"
+
+// CursorUp1 is a sequence for moving the cursor up one cell.
+//
+// This is equivalent to CursorUp(1).
+//
+// Deprecated: use [CUU1] instead.
+const CursorUp1 = "\x1b[A"
+
+// CursorDown (CUD) returns a sequence for moving the cursor down n cells.
+//
+// CSI n B
+//
+// See: https://vt100.net/docs/vt510-rm/CUD.html
+func CursorDown(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "B"
+}
+
+// CUD is an alias for [CursorDown].
+func CUD(n int) string {
+ return CursorDown(n)
+}
+
+// CUD1 is a sequence for moving the cursor down one cell.
+const CUD1 = "\x1b[B"
+
+// CursorDown1 is a sequence for moving the cursor down one cell.
+//
+// This is equivalent to CursorDown(1).
+//
+// Deprecated: use [CUD1] instead.
+const CursorDown1 = "\x1b[B"
+
+// CursorForward (CUF) returns a sequence for moving the cursor right n cells.
+//
+// # CSI n C
+//
+// See: https://vt100.net/docs/vt510-rm/CUF.html
+func CursorForward(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "C"
+}
+
+// CUF is an alias for [CursorForward].
+func CUF(n int) string {
+ return CursorForward(n)
+}
+
+// CUF1 is a sequence for moving the cursor right one cell.
+const CUF1 = "\x1b[C"
+
+// CursorRight (CUF) returns a sequence for moving the cursor right n cells.
+//
+// CSI n C
+//
+// See: https://vt100.net/docs/vt510-rm/CUF.html
+//
+// Deprecated: use [CursorForward] instead.
+func CursorRight(n int) string {
+ return CursorForward(n)
+}
+
+// CursorRight1 is a sequence for moving the cursor right one cell.
+//
+// This is equivalent to CursorRight(1).
+//
+// Deprecated: use [CUF1] instead.
+const CursorRight1 = CUF1
+
+// CursorBackward (CUB) returns a sequence for moving the cursor left n cells.
+//
+// # CSI n D
+//
+// See: https://vt100.net/docs/vt510-rm/CUB.html
+func CursorBackward(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "D"
+}
+
+// CUB is an alias for [CursorBackward].
+func CUB(n int) string {
+ return CursorBackward(n)
+}
+
+// CUB1 is a sequence for moving the cursor left one cell.
+const CUB1 = "\x1b[D"
+
+// CursorLeft (CUB) returns a sequence for moving the cursor left n cells.
+//
+// CSI n D
+//
+// See: https://vt100.net/docs/vt510-rm/CUB.html
+//
+// Deprecated: use [CursorBackward] instead.
+func CursorLeft(n int) string {
+ return CursorBackward(n)
+}
+
+// CursorLeft1 is a sequence for moving the cursor left one cell.
+//
+// This is equivalent to CursorLeft(1).
+//
+// Deprecated: use [CUB1] instead.
+const CursorLeft1 = CUB1
+
+// CursorNextLine (CNL) returns a sequence for moving the cursor to the
+// beginning of the next line n times.
+//
+// CSI n E
+//
+// See: https://vt100.net/docs/vt510-rm/CNL.html
+func CursorNextLine(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "E"
+}
+
+// CNL is an alias for [CursorNextLine].
+func CNL(n int) string {
+ return CursorNextLine(n)
+}
+
+// CursorPreviousLine (CPL) returns a sequence for moving the cursor to the
+// beginning of the previous line n times.
+//
+// CSI n F
+//
+// See: https://vt100.net/docs/vt510-rm/CPL.html
+func CursorPreviousLine(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "F"
+}
+
+// CPL is an alias for [CursorPreviousLine].
+func CPL(n int) string {
+ return CursorPreviousLine(n)
+}
+
+// CursorHorizontalAbsolute (CHA) returns a sequence for moving the cursor to
+// the given column.
+//
+// Default is 1.
+//
+// CSI n G
+//
+// See: https://vt100.net/docs/vt510-rm/CHA.html
+func CursorHorizontalAbsolute(col int) string {
+ var s string
+ if col > 0 {
+ s = strconv.Itoa(col)
+ }
+ return "\x1b[" + s + "G"
+}
+
+// CHA is an alias for [CursorHorizontalAbsolute].
+func CHA(col int) string {
+ return CursorHorizontalAbsolute(col)
+}
+
+// CursorPosition (CUP) returns a sequence for setting the cursor to the
+// given row and column.
+//
+// Default is 1,1.
+//
+// CSI n ; m H
+//
+// See: https://vt100.net/docs/vt510-rm/CUP.html
+func CursorPosition(col, row int) string {
+ if row <= 0 && col <= 0 {
+ return HomeCursorPosition
+ }
+
+ var r, c string
+ if row > 0 {
+ r = strconv.Itoa(row)
+ }
+ if col > 0 {
+ c = strconv.Itoa(col)
+ }
+ return "\x1b[" + r + ";" + c + "H"
+}
+
+// CUP is an alias for [CursorPosition].
+func CUP(col, row int) string {
+ return CursorPosition(col, row)
+}
+
+// CursorHomePosition is a sequence for moving the cursor to the upper left
+// corner of the scrolling region. This is equivalent to `CursorPosition(1, 1)`.
+const CursorHomePosition = "\x1b[H"
+
+// SetCursorPosition (CUP) returns a sequence for setting the cursor to the
+// given row and column.
+//
+// CSI n ; m H
+//
+// See: https://vt100.net/docs/vt510-rm/CUP.html
+//
+// Deprecated: use [CursorPosition] instead.
+func SetCursorPosition(col, row int) string {
+ if row <= 0 && col <= 0 {
+ return HomeCursorPosition
+ }
+
+ var r, c string
+ if row > 0 {
+ r = strconv.Itoa(row)
+ }
+ if col > 0 {
+ c = strconv.Itoa(col)
+ }
+ return "\x1b[" + r + ";" + c + "H"
+}
+
+// HomeCursorPosition is a sequence for moving the cursor to the upper left
+// corner of the scrolling region. This is equivalent to `SetCursorPosition(1, 1)`.
+//
+// Deprecated: use [CursorHomePosition] instead.
+const HomeCursorPosition = CursorHomePosition
+
+// MoveCursor (CUP) returns a sequence for setting the cursor to the
+// given row and column.
+//
+// CSI n ; m H
+//
+// See: https://vt100.net/docs/vt510-rm/CUP.html
+//
+// Deprecated: use [CursorPosition] instead.
+func MoveCursor(col, row int) string {
+ return SetCursorPosition(col, row)
+}
+
+// CursorOrigin is a sequence for moving the cursor to the upper left corner of
+// the display. This is equivalent to `SetCursorPosition(1, 1)`.
+//
+// Deprecated: use [CursorHomePosition] instead.
+const CursorOrigin = "\x1b[1;1H"
+
+// MoveCursorOrigin is a sequence for moving the cursor to the upper left
+// corner of the display. This is equivalent to `SetCursorPosition(1, 1)`.
+//
+// Deprecated: use [CursorHomePosition] instead.
+const MoveCursorOrigin = CursorOrigin
+
+// CursorHorizontalForwardTab (CHT) returns a sequence for moving the cursor to
+// the next tab stop n times.
+//
+// Default is 1.
+//
+// CSI n I
+//
+// See: https://vt100.net/docs/vt510-rm/CHT.html
+func CursorHorizontalForwardTab(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "I"
+}
+
+// CHT is an alias for [CursorHorizontalForwardTab].
+func CHT(n int) string {
+ return CursorHorizontalForwardTab(n)
+}
+
+// EraseCharacter (ECH) returns a sequence for erasing n characters and moving
+// the cursor to the right. This doesn't affect other cell attributes.
+//
+// Default is 1.
+//
+// CSI n X
+//
+// See: https://vt100.net/docs/vt510-rm/ECH.html
+func EraseCharacter(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "X"
+}
+
+// ECH is an alias for [EraseCharacter].
+func ECH(n int) string {
+ return EraseCharacter(n)
+}
+
+// CursorBackwardTab (CBT) returns a sequence for moving the cursor to the
+// previous tab stop n times.
+//
+// Default is 1.
+//
+// CSI n Z
+//
+// See: https://vt100.net/docs/vt510-rm/CBT.html
+func CursorBackwardTab(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "Z"
+}
+
+// CBT is an alias for [CursorBackwardTab].
+func CBT(n int) string {
+ return CursorBackwardTab(n)
+}
+
+// VerticalPositionAbsolute (VPA) returns a sequence for moving the cursor to
+// the given row.
+//
+// Default is 1.
+//
+// CSI n d
+//
+// See: https://vt100.net/docs/vt510-rm/VPA.html
+func VerticalPositionAbsolute(row int) string {
+ var s string
+ if row > 0 {
+ s = strconv.Itoa(row)
+ }
+ return "\x1b[" + s + "d"
+}
+
+// VPA is an alias for [VerticalPositionAbsolute].
+func VPA(row int) string {
+ return VerticalPositionAbsolute(row)
+}
+
+// VerticalPositionRelative (VPR) returns a sequence for moving the cursor down
+// n rows relative to the current position.
+//
+// Default is 1.
+//
+// CSI n e
+//
+// See: https://vt100.net/docs/vt510-rm/VPR.html
+func VerticalPositionRelative(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "e"
+}
+
+// VPR is an alias for [VerticalPositionRelative].
+func VPR(n int) string {
+ return VerticalPositionRelative(n)
+}
+
+// HorizontalVerticalPosition (HVP) returns a sequence for moving the cursor to
+// the given row and column.
+//
+// Default is 1,1.
+//
+// CSI n ; m f
+//
+// This has the same effect as [CursorPosition].
+//
+// See: https://vt100.net/docs/vt510-rm/HVP.html
+func HorizontalVerticalPosition(col, row int) string {
+ var r, c string
+ if row > 0 {
+ r = strconv.Itoa(row)
+ }
+ if col > 0 {
+ c = strconv.Itoa(col)
+ }
+ return "\x1b[" + r + ";" + c + "f"
+}
+
+// HVP is an alias for [HorizontalVerticalPosition].
+func HVP(col, row int) string {
+ return HorizontalVerticalPosition(col, row)
+}
+
+// HorizontalVerticalHomePosition is a sequence for moving the cursor to the
+// upper left corner of the scrolling region. This is equivalent to
+// `HorizontalVerticalPosition(1, 1)`.
+const HorizontalVerticalHomePosition = "\x1b[f"
+
+// SaveCurrentCursorPosition (SCOSC) is a sequence for saving the current cursor
+// position for SCO console mode.
+//
+// CSI s
+//
+// This acts like [DECSC], except the page number where the cursor is located
+// is not saved.
+//
+// See: https://vt100.net/docs/vt510-rm/SCOSC.html
+const (
+ SaveCurrentCursorPosition = "\x1b[s"
+ SCOSC = SaveCurrentCursorPosition
+)
+
+// SaveCursorPosition (SCP or SCOSC) is a sequence for saving the cursor
+// position.
+//
+// CSI s
+//
+// This acts like Save, except the page number where the cursor is located is
+// not saved.
+//
+// See: https://vt100.net/docs/vt510-rm/SCOSC.html
+//
+// Deprecated: use [SaveCurrentCursorPosition] instead.
+const SaveCursorPosition = "\x1b[s"
+
+// RestoreCurrentCursorPosition (SCORC) is a sequence for restoring the current
+// cursor position for SCO console mode.
+//
+// CSI u
+//
+// This acts like [DECRC], except the page number where the cursor was saved is
+// not restored.
+//
+// See: https://vt100.net/docs/vt510-rm/SCORC.html
+const (
+ RestoreCurrentCursorPosition = "\x1b[u"
+ SCORC = RestoreCurrentCursorPosition
+)
+
+// RestoreCursorPosition (RCP or SCORC) is a sequence for restoring the cursor
+// position.
+//
+// CSI u
+//
+// This acts like Restore, except the cursor stays on the same page where the
+// cursor was saved.
+//
+// See: https://vt100.net/docs/vt510-rm/SCORC.html
+//
+// Deprecated: use [RestoreCurrentCursorPosition] instead.
+const RestoreCursorPosition = "\x1b[u"
+
+// SetCursorStyle (DECSCUSR) returns a sequence for changing the cursor style.
+//
+// Default is 1.
+//
+// CSI Ps SP q
+//
+// Where Ps is the cursor style:
+//
+// 0: Blinking block
+// 1: Blinking block (default)
+// 2: Steady block
+// 3: Blinking underline
+// 4: Steady underline
+// 5: Blinking bar (xterm)
+// 6: Steady bar (xterm)
+//
+// See: https://vt100.net/docs/vt510-rm/DECSCUSR.html
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps-SP-q.1D81
+func SetCursorStyle(style int) string {
+ if style < 0 {
+ style = 0
+ }
+ return "\x1b[" + strconv.Itoa(style) + " q"
+}
+
+// DECSCUSR is an alias for [SetCursorStyle].
+func DECSCUSR(style int) string {
+ return SetCursorStyle(style)
+}
+
+// SetPointerShape returns a sequence for changing the mouse pointer cursor
+// shape. Use "default" for the default pointer shape.
+//
+// OSC 22 ; Pt ST
+// OSC 22 ; Pt BEL
+//
+// Where Pt is the pointer shape name. The name can be anything that the
+// operating system can understand. Some common names are:
+//
+// - copy
+// - crosshair
+// - default
+// - ew-resize
+// - n-resize
+// - text
+// - wait
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands
+func SetPointerShape(shape string) string {
+ return "\x1b]22;" + shape + "\x07"
+}
+
+// ReverseIndex (RI) is an escape sequence for moving the cursor up one line in
+// the same column. If the cursor is at the top margin, the screen scrolls
+// down.
+//
+// This has the same effect as [RI].
+const ReverseIndex = "\x1bM"
+
+// HorizontalPositionAbsolute (HPA) returns a sequence for moving the cursor to
+// the given column. This has the same effect as [CUP].
+//
+// Default is 1.
+//
+// CSI n `
+//
+// See: https://vt100.net/docs/vt510-rm/HPA.html
+func HorizontalPositionAbsolute(col int) string {
+ var s string
+ if col > 0 {
+ s = strconv.Itoa(col)
+ }
+ return "\x1b[" + s + "`"
+}
+
+// HPA is an alias for [HorizontalPositionAbsolute].
+func HPA(col int) string {
+ return HorizontalPositionAbsolute(col)
+}
+
+// HorizontalPositionRelative (HPR) returns a sequence for moving the cursor
+// right n columns relative to the current position. This has the same effect
+// as [CUP].
+//
+// Default is 1.
+//
+// CSI n a
+//
+// See: https://vt100.net/docs/vt510-rm/HPR.html
+func HorizontalPositionRelative(n int) string {
+ var s string
+ if n > 0 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "a"
+}
+
+// HPR is an alias for [HorizontalPositionRelative].
+func HPR(n int) string {
+ return HorizontalPositionRelative(n)
+}
+
+// Index (IND) is an escape sequence for moving the cursor down one line in the
+// same column. If the cursor is at the bottom margin, the screen scrolls up.
+// This has the same effect as [IND].
+const Index = "\x1bD"
diff --git a/vendor/github.com/charmbracelet/x/ansi/cwd.go b/vendor/github.com/charmbracelet/x/ansi/cwd.go
new file mode 100644
index 0000000..b03ac1b
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/cwd.go
@@ -0,0 +1,26 @@
+package ansi
+
+import (
+ "net/url"
+ "path"
+)
+
+// NotifyWorkingDirectory returns a sequence that notifies the terminal
+// of the current working directory.
+//
+// OSC 7 ; Pt BEL
+//
+// Where Pt is a URL in the format "file://[host]/[path]".
+// Set host to "localhost" if this is a path on the local computer.
+//
+// See: https://wezfurlong.org/wezterm/shell-integration.html#osc-7-escape-sequence-to-set-the-working-directory
+// See: https://iterm2.com/documentation-escape-codes.html#:~:text=RemoteHost%20and%20CurrentDir%3A-,OSC%207,-%3B%20%5BPs%5D%20ST
+func NotifyWorkingDirectory(host string, paths ...string) string {
+ path := path.Join(paths...)
+ u := &url.URL{
+ Scheme: "file",
+ Host: host,
+ Path: path,
+ }
+ return "\x1b]7;" + u.String() + "\x07"
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/doc.go b/vendor/github.com/charmbracelet/x/ansi/doc.go
new file mode 100644
index 0000000..e955e9f
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/doc.go
@@ -0,0 +1,7 @@
+// Package ansi defines common ANSI escape sequences based on the ECMA-48
+// specs.
+//
+// All sequences use 7-bit C1 control codes, which are supported by most
+// terminal emulators. OSC sequences are terminated by a BEL for wider
+// compatibility with terminals.
+package ansi
diff --git a/vendor/github.com/charmbracelet/x/ansi/focus.go b/vendor/github.com/charmbracelet/x/ansi/focus.go
new file mode 100644
index 0000000..4e0207c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/focus.go
@@ -0,0 +1,9 @@
+package ansi
+
+// Focus is an escape sequence to notify the terminal that it has focus.
+// This is used with [FocusEventMode].
+const Focus = "\x1b[I"
+
+// Blur is an escape sequence to notify the terminal that it has lost focus.
+// This is used with [FocusEventMode].
+const Blur = "\x1b[O"
diff --git a/vendor/github.com/charmbracelet/x/ansi/graphics.go b/vendor/github.com/charmbracelet/x/ansi/graphics.go
new file mode 100644
index 0000000..604fef4
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/graphics.go
@@ -0,0 +1,199 @@
+package ansi
+
+import (
+ "bytes"
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "image"
+ "io"
+ "os"
+ "strings"
+
+ "github.com/charmbracelet/x/ansi/kitty"
+)
+
+// KittyGraphics returns a sequence that encodes the given image in the Kitty
+// graphics protocol.
+//
+// APC G [comma separated options] ; [base64 encoded payload] ST
+//
+// See https://sw.kovidgoyal.net/kitty/graphics-protocol/
+func KittyGraphics(payload []byte, opts ...string) string {
+ var buf bytes.Buffer
+ buf.WriteString("\x1b_G")
+ buf.WriteString(strings.Join(opts, ","))
+ if len(payload) > 0 {
+ buf.WriteString(";")
+ buf.Write(payload)
+ }
+ buf.WriteString("\x1b\\")
+ return buf.String()
+}
+
+var (
+ // KittyGraphicsTempDir is the directory where temporary files are stored.
+ // This is used in [WriteKittyGraphics] along with [os.CreateTemp].
+ KittyGraphicsTempDir = ""
+
+ // KittyGraphicsTempPattern is the pattern used to create temporary files.
+ // This is used in [WriteKittyGraphics] along with [os.CreateTemp].
+ // The Kitty Graphics protocol requires the file path to contain the
+ // substring "tty-graphics-protocol".
+ KittyGraphicsTempPattern = "tty-graphics-protocol-*"
+)
+
+// WriteKittyGraphics writes an image using the Kitty Graphics protocol with
+// the given options to w. It chunks the written data if o.Chunk is true.
+//
+// You can omit m and use nil when rendering an image from a file. In this
+// case, you must provide a file path in o.File and use o.Transmission =
+// [kitty.File]. You can also use o.Transmission = [kitty.TempFile] to write
+// the image to a temporary file. In that case, the file path is ignored, and
+// the image is written to a temporary file that is automatically deleted by
+// the terminal.
+//
+// See https://sw.kovidgoyal.net/kitty/graphics-protocol/
+func WriteKittyGraphics(w io.Writer, m image.Image, o *kitty.Options) error {
+ if o == nil {
+ o = &kitty.Options{}
+ }
+
+ if o.Transmission == 0 && len(o.File) != 0 {
+ o.Transmission = kitty.File
+ }
+
+ var data bytes.Buffer // the data to be encoded into base64
+ e := &kitty.Encoder{
+ Compress: o.Compression == kitty.Zlib,
+ Format: o.Format,
+ }
+
+ switch o.Transmission {
+ case kitty.Direct:
+ if err := e.Encode(&data, m); err != nil {
+ return fmt.Errorf("failed to encode direct image: %w", err)
+ }
+
+ case kitty.SharedMemory:
+ // TODO: Implement shared memory
+ return fmt.Errorf("shared memory transmission is not yet implemented")
+
+ case kitty.File:
+ if len(o.File) == 0 {
+ return kitty.ErrMissingFile
+ }
+
+ f, err := os.Open(o.File)
+ if err != nil {
+ return fmt.Errorf("failed to open file: %w", err)
+ }
+
+ defer f.Close() //nolint:errcheck
+
+ stat, err := f.Stat()
+ if err != nil {
+ return fmt.Errorf("failed to get file info: %w", err)
+ }
+
+ mode := stat.Mode()
+ if !mode.IsRegular() {
+ return fmt.Errorf("file is not a regular file")
+ }
+
+ // Write the file path to the buffer
+ if _, err := data.WriteString(f.Name()); err != nil {
+ return fmt.Errorf("failed to write file path to buffer: %w", err)
+ }
+
+ case kitty.TempFile:
+ f, err := os.CreateTemp(KittyGraphicsTempDir, KittyGraphicsTempPattern)
+ if err != nil {
+ return fmt.Errorf("failed to create file: %w", err)
+ }
+
+ defer f.Close() //nolint:errcheck
+
+ if err := e.Encode(f, m); err != nil {
+ return fmt.Errorf("failed to encode image to file: %w", err)
+ }
+
+ // Write the file path to the buffer
+ if _, err := data.WriteString(f.Name()); err != nil {
+ return fmt.Errorf("failed to write file path to buffer: %w", err)
+ }
+ }
+
+ // Encode image to base64
+ var payload bytes.Buffer // the base64 encoded image to be written to w
+ b64 := base64.NewEncoder(base64.StdEncoding, &payload)
+ if _, err := data.WriteTo(b64); err != nil {
+ return fmt.Errorf("failed to write base64 encoded image to payload: %w", err)
+ }
+ if err := b64.Close(); err != nil {
+ return err
+ }
+
+ // If not chunking, write all at once
+ if !o.Chunk {
+ _, err := io.WriteString(w, KittyGraphics(payload.Bytes(), o.Options()...))
+ return err
+ }
+
+ // Write in chunks
+ var (
+ err error
+ n int
+ )
+ chunk := make([]byte, kitty.MaxChunkSize)
+ isFirstChunk := true
+
+ for {
+ // Stop if we read less than the chunk size [kitty.MaxChunkSize].
+ n, err = io.ReadFull(&payload, chunk)
+ if errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, io.EOF) {
+ break
+ }
+ if err != nil {
+ return fmt.Errorf("failed to read chunk: %w", err)
+ }
+
+ opts := buildChunkOptions(o, isFirstChunk, false)
+ if _, err := io.WriteString(w, KittyGraphics(chunk[:n], opts...)); err != nil {
+ return err
+ }
+
+ isFirstChunk = false
+ }
+
+ // Write the last chunk
+ opts := buildChunkOptions(o, isFirstChunk, true)
+ _, err = io.WriteString(w, KittyGraphics(chunk[:n], opts...))
+ return err
+}
+
+// buildChunkOptions creates the options slice for a chunk
+func buildChunkOptions(o *kitty.Options, isFirstChunk, isLastChunk bool) []string {
+ var opts []string
+ if isFirstChunk {
+ opts = o.Options()
+ } else {
+ // These options are allowed in subsequent chunks
+ if o.Quite > 0 {
+ opts = append(opts, fmt.Sprintf("q=%d", o.Quite))
+ }
+ if o.Action == kitty.Frame {
+ opts = append(opts, "a=f")
+ }
+ }
+
+ if !isFirstChunk || !isLastChunk {
+ // We don't need to encode the (m=) option when we only have one chunk.
+ if isLastChunk {
+ opts = append(opts, "m=0")
+ } else {
+ opts = append(opts, "m=1")
+ }
+ }
+ return opts
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/hyperlink.go b/vendor/github.com/charmbracelet/x/ansi/hyperlink.go
new file mode 100644
index 0000000..323bfe9
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/hyperlink.go
@@ -0,0 +1,28 @@
+package ansi
+
+import "strings"
+
+// SetHyperlink returns a sequence for starting a hyperlink.
+//
+// OSC 8 ; Params ; Uri ST
+// OSC 8 ; Params ; Uri BEL
+//
+// To reset the hyperlink, omit the URI.
+//
+// See: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
+func SetHyperlink(uri string, params ...string) string {
+ var p string
+ if len(params) > 0 {
+ p = strings.Join(params, ":")
+ }
+ return "\x1b]8;" + p + ";" + uri + "\x07"
+}
+
+// ResetHyperlink returns a sequence for resetting the hyperlink.
+//
+// This is equivalent to SetHyperlink("", params...).
+//
+// See: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
+func ResetHyperlink(params ...string) string {
+ return SetHyperlink("", params...)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/iterm2.go b/vendor/github.com/charmbracelet/x/ansi/iterm2.go
new file mode 100644
index 0000000..0ecb336
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/iterm2.go
@@ -0,0 +1,18 @@
+package ansi
+
+import "fmt"
+
+// ITerm2 returns a sequence that uses the iTerm2 proprietary protocol. Use the
+// iterm2 package for a more convenient API.
+//
+// OSC 1337 ; key = value ST
+//
+// Example:
+//
+// ITerm2(iterm2.File{...})
+//
+// See https://iterm2.com/documentation-escape-codes.html
+// See https://iterm2.com/documentation-images.html
+func ITerm2(data any) string {
+ return "\x1b]1337;" + fmt.Sprint(data) + "\x07"
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/keypad.go b/vendor/github.com/charmbracelet/x/ansi/keypad.go
new file mode 100644
index 0000000..9183c6a
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/keypad.go
@@ -0,0 +1,28 @@
+package ansi
+
+// Keypad Application Mode (DECKPAM) is a mode that determines whether the
+// keypad sends application sequences or ANSI sequences.
+//
+// This works like enabling [DECNKM].
+// Use [NumericKeypadMode] to set the numeric keypad mode.
+//
+// ESC =
+//
+// See: https://vt100.net/docs/vt510-rm/DECKPAM.html
+const (
+ KeypadApplicationMode = "\x1b="
+ DECKPAM = KeypadApplicationMode
+)
+
+// Keypad Numeric Mode (DECKPNM) is a mode that determines whether the keypad
+// sends application sequences or ANSI sequences.
+//
+// This works the same as disabling [DECNKM].
+//
+// ESC >
+//
+// See: https://vt100.net/docs/vt510-rm/DECKPNM.html
+const (
+ KeypadNumericMode = "\x1b>"
+ DECKPNM = KeypadNumericMode
+)
diff --git a/vendor/github.com/charmbracelet/x/ansi/kitty.go b/vendor/github.com/charmbracelet/x/ansi/kitty.go
new file mode 100644
index 0000000..124ab83
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/kitty.go
@@ -0,0 +1,90 @@
+package ansi
+
+import "strconv"
+
+// Kitty keyboard protocol progressive enhancement flags.
+// See: https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement
+const (
+ KittyDisambiguateEscapeCodes = 1 << iota
+ KittyReportEventTypes
+ KittyReportAlternateKeys
+ KittyReportAllKeysAsEscapeCodes
+ KittyReportAssociatedKeys
+
+ KittyAllFlags = KittyDisambiguateEscapeCodes | KittyReportEventTypes |
+ KittyReportAlternateKeys | KittyReportAllKeysAsEscapeCodes | KittyReportAssociatedKeys
+)
+
+// RequestKittyKeyboard is a sequence to request the terminal Kitty keyboard
+// protocol enabled flags.
+//
+// See: https://sw.kovidgoyal.net/kitty/keyboard-protocol/
+const RequestKittyKeyboard = "\x1b[?u"
+
+// KittyKeyboard returns a sequence to request keyboard enhancements from the terminal.
+// The flags argument is a bitmask of the Kitty keyboard protocol flags. While
+// mode specifies how the flags should be interpreted.
+//
+// Possible values for flags mask:
+//
+// 1: Disambiguate escape codes
+// 2: Report event types
+// 4: Report alternate keys
+// 8: Report all keys as escape codes
+// 16: Report associated text
+//
+// Possible values for mode:
+//
+// 1: Set given flags and unset all others
+// 2: Set given flags and keep existing flags unchanged
+// 3: Unset given flags and keep existing flags unchanged
+//
+// See https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement
+func KittyKeyboard(flags, mode int) string {
+ return "\x1b[=" + strconv.Itoa(flags) + ";" + strconv.Itoa(mode) + "u"
+}
+
+// PushKittyKeyboard returns a sequence to push the given flags to the terminal
+// Kitty Keyboard stack.
+//
+// Possible values for flags mask:
+//
+// 0: Disable all features
+// 1: Disambiguate escape codes
+// 2: Report event types
+// 4: Report alternate keys
+// 8: Report all keys as escape codes
+// 16: Report associated text
+//
+// CSI > flags u
+//
+// See https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement
+func PushKittyKeyboard(flags int) string {
+ var f string
+ if flags > 0 {
+ f = strconv.Itoa(flags)
+ }
+
+ return "\x1b[>" + f + "u"
+}
+
+// DisableKittyKeyboard is a sequence to push zero into the terminal Kitty
+// Keyboard stack to disable the protocol.
+//
+// This is equivalent to PushKittyKeyboard(0).
+const DisableKittyKeyboard = "\x1b[>u"
+
+// PopKittyKeyboard returns a sequence to pop n number of flags from the
+// terminal Kitty Keyboard stack.
+//
+// CSI < flags u
+//
+// See https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement
+func PopKittyKeyboard(n int) string {
+ var num string
+ if n > 0 {
+ num = strconv.Itoa(n)
+ }
+
+ return "\x1b[<" + num + "u"
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/kitty/decoder.go b/vendor/github.com/charmbracelet/x/ansi/kitty/decoder.go
new file mode 100644
index 0000000..fbd0844
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/kitty/decoder.go
@@ -0,0 +1,85 @@
+package kitty
+
+import (
+ "compress/zlib"
+ "fmt"
+ "image"
+ "image/color"
+ "image/png"
+ "io"
+)
+
+// Decoder is a decoder for the Kitty graphics protocol. It supports decoding
+// images in the 24-bit [RGB], 32-bit [RGBA], and [PNG] formats. It can also
+// decompress data using zlib.
+// The default format is 32-bit [RGBA].
+type Decoder struct {
+ // Uses zlib decompression.
+ Decompress bool
+
+ // Can be one of [RGB], [RGBA], or [PNG].
+ Format int
+
+ // Width of the image in pixels. This can be omitted if the image is [PNG]
+ // formatted.
+ Width int
+
+ // Height of the image in pixels. This can be omitted if the image is [PNG]
+ // formatted.
+ Height int
+}
+
+// Decode decodes the image data from r in the specified format.
+func (d *Decoder) Decode(r io.Reader) (image.Image, error) {
+ if d.Decompress {
+ zr, err := zlib.NewReader(r)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create zlib reader: %w", err)
+ }
+
+ defer zr.Close() //nolint:errcheck
+ r = zr
+ }
+
+ if d.Format == 0 {
+ d.Format = RGBA
+ }
+
+ switch d.Format {
+ case RGBA, RGB:
+ return d.decodeRGBA(r, d.Format == RGBA)
+
+ case PNG:
+ return png.Decode(r)
+
+ default:
+ return nil, fmt.Errorf("unsupported format: %d", d.Format)
+ }
+}
+
+// decodeRGBA decodes the image data in 32-bit RGBA or 24-bit RGB formats.
+func (d *Decoder) decodeRGBA(r io.Reader, alpha bool) (image.Image, error) {
+ m := image.NewRGBA(image.Rect(0, 0, d.Width, d.Height))
+
+ var buf []byte
+ if alpha {
+ buf = make([]byte, 4)
+ } else {
+ buf = make([]byte, 3)
+ }
+
+ for y := 0; y < d.Height; y++ {
+ for x := 0; x < d.Width; x++ {
+ if _, err := io.ReadFull(r, buf[:]); err != nil {
+ return nil, fmt.Errorf("failed to read pixel data: %w", err)
+ }
+ if alpha {
+ m.SetRGBA(x, y, color.RGBA{buf[0], buf[1], buf[2], buf[3]})
+ } else {
+ m.SetRGBA(x, y, color.RGBA{buf[0], buf[1], buf[2], 0xff})
+ }
+ }
+ }
+
+ return m, nil
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/kitty/encoder.go b/vendor/github.com/charmbracelet/x/ansi/kitty/encoder.go
new file mode 100644
index 0000000..f668b9e
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/kitty/encoder.go
@@ -0,0 +1,64 @@
+package kitty
+
+import (
+ "compress/zlib"
+ "fmt"
+ "image"
+ "image/png"
+ "io"
+)
+
+// Encoder is an encoder for the Kitty graphics protocol. It supports encoding
+// images in the 24-bit [RGB], 32-bit [RGBA], and [PNG] formats, and
+// compressing the data using zlib.
+// The default format is 32-bit [RGBA].
+type Encoder struct {
+ // Uses zlib compression.
+ Compress bool
+
+ // Can be one of [RGBA], [RGB], or [PNG].
+ Format int
+}
+
+// Encode encodes the image data in the specified format and writes it to w.
+func (e *Encoder) Encode(w io.Writer, m image.Image) error {
+ if m == nil {
+ return nil
+ }
+
+ if e.Compress {
+ zw := zlib.NewWriter(w)
+ defer zw.Close() //nolint:errcheck
+ w = zw
+ }
+
+ if e.Format == 0 {
+ e.Format = RGBA
+ }
+
+ switch e.Format {
+ case RGBA, RGB:
+ bounds := m.Bounds()
+ for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
+ for x := bounds.Min.X; x < bounds.Max.X; x++ {
+ r, g, b, a := m.At(x, y).RGBA()
+ switch e.Format {
+ case RGBA:
+ w.Write([]byte{byte(r >> 8), byte(g >> 8), byte(b >> 8), byte(a >> 8)}) //nolint:errcheck
+ case RGB:
+ w.Write([]byte{byte(r >> 8), byte(g >> 8), byte(b >> 8)}) //nolint:errcheck
+ }
+ }
+ }
+
+ case PNG:
+ if err := png.Encode(w, m); err != nil {
+ return fmt.Errorf("failed to encode PNG: %w", err)
+ }
+
+ default:
+ return fmt.Errorf("unsupported format: %d", e.Format)
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/kitty/graphics.go b/vendor/github.com/charmbracelet/x/ansi/kitty/graphics.go
new file mode 100644
index 0000000..490e7a8
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/kitty/graphics.go
@@ -0,0 +1,414 @@
+package kitty
+
+import "errors"
+
+// ErrMissingFile is returned when the file path is missing.
+var ErrMissingFile = errors.New("missing file path")
+
+// MaxChunkSize is the maximum chunk size for the image data.
+const MaxChunkSize = 1024 * 4
+
+// Placeholder is a special Unicode character that can be used as a placeholder
+// for an image.
+const Placeholder = '\U0010EEEE'
+
+// Graphics image format.
+const (
+ // 32-bit RGBA format.
+ RGBA = 32
+
+ // 24-bit RGB format.
+ RGB = 24
+
+ // PNG format.
+ PNG = 100
+)
+
+// Compression types.
+const (
+ Zlib = 'z'
+)
+
+// Transmission types.
+const (
+ // The data transmitted directly in the escape sequence.
+ Direct = 'd'
+
+ // The data transmitted in a regular file.
+ File = 'f'
+
+ // A temporary file is used and deleted after transmission.
+ TempFile = 't'
+
+ // A shared memory object.
+ // For POSIX see https://pubs.opengroup.org/onlinepubs/9699919799/functions/shm_open.html
+ // For Windows see https://docs.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memory
+ SharedMemory = 's'
+)
+
+// Action types.
+const (
+ // Transmit image data.
+ Transmit = 't'
+ // TransmitAndPut transmit image data and display (put) it.
+ TransmitAndPut = 'T'
+ // Query terminal for image info.
+ Query = 'q'
+ // Put (display) previously transmitted image.
+ Put = 'p'
+ // Delete image.
+ Delete = 'd'
+ // Frame transmits data for animation frames.
+ Frame = 'f'
+ // Animate controls animation.
+ Animate = 'a'
+ // Compose composes animation frames.
+ Compose = 'c'
+)
+
+// Delete types.
+const (
+ // Delete all placements visible on screen
+ DeleteAll = 'a'
+ // Delete all images with the specified id, specified using the i key. If
+ // you specify a p key for the placement id as well, then only the
+ // placement with the specified image id and placement id will be deleted.
+ DeleteID = 'i'
+ // Delete newest image with the specified number, specified using the I
+ // key. If you specify a p key for the placement id as well, then only the
+ // placement with the specified number and placement id will be deleted.
+ DeleteNumber = 'n'
+ // Delete all placements that intersect with the current cursor position.
+ DeleteCursor = 'c'
+ // Delete animation frames.
+ DeleteFrames = 'f'
+ // Delete all placements that intersect a specific cell, the cell is
+ // specified using the x and y keys
+ DeleteCell = 'p'
+ // Delete all placements that intersect a specific cell having a specific
+ // z-index. The cell and z-index is specified using the x, y and z keys.
+ DeleteCellZ = 'q'
+ // Delete all images whose id is greater than or equal to the value of the x
+ // key and less than or equal to the value of the y.
+ DeleteRange = 'r'
+ // Delete all placements that intersect the specified column, specified using
+ // the x key.
+ DeleteColumn = 'x'
+ // Delete all placements that intersect the specified row, specified using
+ // the y key.
+ DeleteRow = 'y'
+ // Delete all placements that have the specified z-index, specified using the
+ // z key.
+ DeleteZ = 'z'
+)
+
+// Diacritic returns the diacritic rune at the specified index. If the index is
+// out of bounds, the first diacritic rune is returned.
+func Diacritic(i int) rune {
+ if i < 0 || i >= len(diacritics) {
+ return diacritics[0]
+ }
+ return diacritics[i]
+}
+
+// From https://sw.kovidgoyal.net/kitty/_downloads/f0a0de9ec8d9ff4456206db8e0814937/rowcolumn-diacritics.txt
+// See https://sw.kovidgoyal.net/kitty/graphics-protocol/#unicode-placeholders for further explanation.
+var diacritics = []rune{
+ '\u0305',
+ '\u030D',
+ '\u030E',
+ '\u0310',
+ '\u0312',
+ '\u033D',
+ '\u033E',
+ '\u033F',
+ '\u0346',
+ '\u034A',
+ '\u034B',
+ '\u034C',
+ '\u0350',
+ '\u0351',
+ '\u0352',
+ '\u0357',
+ '\u035B',
+ '\u0363',
+ '\u0364',
+ '\u0365',
+ '\u0366',
+ '\u0367',
+ '\u0368',
+ '\u0369',
+ '\u036A',
+ '\u036B',
+ '\u036C',
+ '\u036D',
+ '\u036E',
+ '\u036F',
+ '\u0483',
+ '\u0484',
+ '\u0485',
+ '\u0486',
+ '\u0487',
+ '\u0592',
+ '\u0593',
+ '\u0594',
+ '\u0595',
+ '\u0597',
+ '\u0598',
+ '\u0599',
+ '\u059C',
+ '\u059D',
+ '\u059E',
+ '\u059F',
+ '\u05A0',
+ '\u05A1',
+ '\u05A8',
+ '\u05A9',
+ '\u05AB',
+ '\u05AC',
+ '\u05AF',
+ '\u05C4',
+ '\u0610',
+ '\u0611',
+ '\u0612',
+ '\u0613',
+ '\u0614',
+ '\u0615',
+ '\u0616',
+ '\u0617',
+ '\u0657',
+ '\u0658',
+ '\u0659',
+ '\u065A',
+ '\u065B',
+ '\u065D',
+ '\u065E',
+ '\u06D6',
+ '\u06D7',
+ '\u06D8',
+ '\u06D9',
+ '\u06DA',
+ '\u06DB',
+ '\u06DC',
+ '\u06DF',
+ '\u06E0',
+ '\u06E1',
+ '\u06E2',
+ '\u06E4',
+ '\u06E7',
+ '\u06E8',
+ '\u06EB',
+ '\u06EC',
+ '\u0730',
+ '\u0732',
+ '\u0733',
+ '\u0735',
+ '\u0736',
+ '\u073A',
+ '\u073D',
+ '\u073F',
+ '\u0740',
+ '\u0741',
+ '\u0743',
+ '\u0745',
+ '\u0747',
+ '\u0749',
+ '\u074A',
+ '\u07EB',
+ '\u07EC',
+ '\u07ED',
+ '\u07EE',
+ '\u07EF',
+ '\u07F0',
+ '\u07F1',
+ '\u07F3',
+ '\u0816',
+ '\u0817',
+ '\u0818',
+ '\u0819',
+ '\u081B',
+ '\u081C',
+ '\u081D',
+ '\u081E',
+ '\u081F',
+ '\u0820',
+ '\u0821',
+ '\u0822',
+ '\u0823',
+ '\u0825',
+ '\u0826',
+ '\u0827',
+ '\u0829',
+ '\u082A',
+ '\u082B',
+ '\u082C',
+ '\u082D',
+ '\u0951',
+ '\u0953',
+ '\u0954',
+ '\u0F82',
+ '\u0F83',
+ '\u0F86',
+ '\u0F87',
+ '\u135D',
+ '\u135E',
+ '\u135F',
+ '\u17DD',
+ '\u193A',
+ '\u1A17',
+ '\u1A75',
+ '\u1A76',
+ '\u1A77',
+ '\u1A78',
+ '\u1A79',
+ '\u1A7A',
+ '\u1A7B',
+ '\u1A7C',
+ '\u1B6B',
+ '\u1B6D',
+ '\u1B6E',
+ '\u1B6F',
+ '\u1B70',
+ '\u1B71',
+ '\u1B72',
+ '\u1B73',
+ '\u1CD0',
+ '\u1CD1',
+ '\u1CD2',
+ '\u1CDA',
+ '\u1CDB',
+ '\u1CE0',
+ '\u1DC0',
+ '\u1DC1',
+ '\u1DC3',
+ '\u1DC4',
+ '\u1DC5',
+ '\u1DC6',
+ '\u1DC7',
+ '\u1DC8',
+ '\u1DC9',
+ '\u1DCB',
+ '\u1DCC',
+ '\u1DD1',
+ '\u1DD2',
+ '\u1DD3',
+ '\u1DD4',
+ '\u1DD5',
+ '\u1DD6',
+ '\u1DD7',
+ '\u1DD8',
+ '\u1DD9',
+ '\u1DDA',
+ '\u1DDB',
+ '\u1DDC',
+ '\u1DDD',
+ '\u1DDE',
+ '\u1DDF',
+ '\u1DE0',
+ '\u1DE1',
+ '\u1DE2',
+ '\u1DE3',
+ '\u1DE4',
+ '\u1DE5',
+ '\u1DE6',
+ '\u1DFE',
+ '\u20D0',
+ '\u20D1',
+ '\u20D4',
+ '\u20D5',
+ '\u20D6',
+ '\u20D7',
+ '\u20DB',
+ '\u20DC',
+ '\u20E1',
+ '\u20E7',
+ '\u20E9',
+ '\u20F0',
+ '\u2CEF',
+ '\u2CF0',
+ '\u2CF1',
+ '\u2DE0',
+ '\u2DE1',
+ '\u2DE2',
+ '\u2DE3',
+ '\u2DE4',
+ '\u2DE5',
+ '\u2DE6',
+ '\u2DE7',
+ '\u2DE8',
+ '\u2DE9',
+ '\u2DEA',
+ '\u2DEB',
+ '\u2DEC',
+ '\u2DED',
+ '\u2DEE',
+ '\u2DEF',
+ '\u2DF0',
+ '\u2DF1',
+ '\u2DF2',
+ '\u2DF3',
+ '\u2DF4',
+ '\u2DF5',
+ '\u2DF6',
+ '\u2DF7',
+ '\u2DF8',
+ '\u2DF9',
+ '\u2DFA',
+ '\u2DFB',
+ '\u2DFC',
+ '\u2DFD',
+ '\u2DFE',
+ '\u2DFF',
+ '\uA66F',
+ '\uA67C',
+ '\uA67D',
+ '\uA6F0',
+ '\uA6F1',
+ '\uA8E0',
+ '\uA8E1',
+ '\uA8E2',
+ '\uA8E3',
+ '\uA8E4',
+ '\uA8E5',
+ '\uA8E6',
+ '\uA8E7',
+ '\uA8E8',
+ '\uA8E9',
+ '\uA8EA',
+ '\uA8EB',
+ '\uA8EC',
+ '\uA8ED',
+ '\uA8EE',
+ '\uA8EF',
+ '\uA8F0',
+ '\uA8F1',
+ '\uAAB0',
+ '\uAAB2',
+ '\uAAB3',
+ '\uAAB7',
+ '\uAAB8',
+ '\uAABE',
+ '\uAABF',
+ '\uAAC1',
+ '\uFE20',
+ '\uFE21',
+ '\uFE22',
+ '\uFE23',
+ '\uFE24',
+ '\uFE25',
+ '\uFE26',
+ '\U00010A0F',
+ '\U00010A38',
+ '\U0001D185',
+ '\U0001D186',
+ '\U0001D187',
+ '\U0001D188',
+ '\U0001D189',
+ '\U0001D1AA',
+ '\U0001D1AB',
+ '\U0001D1AC',
+ '\U0001D1AD',
+ '\U0001D242',
+ '\U0001D243',
+ '\U0001D244',
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/kitty/options.go b/vendor/github.com/charmbracelet/x/ansi/kitty/options.go
new file mode 100644
index 0000000..a8d907b
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/kitty/options.go
@@ -0,0 +1,367 @@
+package kitty
+
+import (
+ "encoding"
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+var (
+ _ encoding.TextMarshaler = Options{}
+ _ encoding.TextUnmarshaler = &Options{}
+)
+
+// Options represents a Kitty Graphics Protocol options.
+type Options struct {
+ // Common options.
+
+ // Action (a=t) is the action to be performed on the image. Can be one of
+ // [Transmit], [TransmitDisplay], [Query], [Put], [Delete], [Frame],
+ // [Animate], [Compose].
+ Action byte
+
+ // Quite mode (q=0) is the quiet mode. Can be either zero, one, or two
+ // where zero is the default, 1 suppresses OK responses, and 2 suppresses
+ // both OK and error responses.
+ Quite byte
+
+ // Transmission options.
+
+ // ID (i=) is the image ID. The ID is a unique identifier for the image.
+ // Must be a positive integer up to [math.MaxUint32].
+ ID int
+
+ // PlacementID (p=) is the placement ID. The placement ID is a unique
+ // identifier for the placement of the image. Must be a positive integer up
+ // to [math.MaxUint32].
+ PlacementID int
+
+ // Number (I=0) is the number of images to be transmitted.
+ Number int
+
+ // Format (f=32) is the image format. One of [RGBA], [RGB], [PNG].
+ Format int
+
+ // ImageWidth (s=0) is the transmitted image width.
+ ImageWidth int
+
+ // ImageHeight (v=0) is the transmitted image height.
+ ImageHeight int
+
+ // Compression (o=) is the image compression type. Can be [Zlib] or zero.
+ Compression byte
+
+ // Transmission (t=d) is the image transmission type. Can be [Direct], [File],
+ // [TempFile], or[SharedMemory].
+ Transmission byte
+
+ // File is the file path to be used when the transmission type is [File].
+ // If [Options.Transmission] is omitted i.e. zero and this is non-empty,
+ // the transmission type is set to [File].
+ File string
+
+ // Size (S=0) is the size to be read from the transmission medium.
+ Size int
+
+ // Offset (O=0) is the offset byte to start reading from the transmission
+ // medium.
+ Offset int
+
+ // Chunk (m=) whether the image is transmitted in chunks. Can be either
+ // zero or one. When true, the image is transmitted in chunks. Each chunk
+ // must be a multiple of 4, and up to [MaxChunkSize] bytes. Each chunk must
+ // have the m=1 option except for the last chunk which must have m=0.
+ Chunk bool
+
+ // Display options.
+
+ // X (x=0) is the pixel X coordinate of the image to start displaying.
+ X int
+
+ // Y (y=0) is the pixel Y coordinate of the image to start displaying.
+ Y int
+
+ // Z (z=0) is the Z coordinate of the image to display.
+ Z int
+
+ // Width (w=0) is the width of the image to display.
+ Width int
+
+ // Height (h=0) is the height of the image to display.
+ Height int
+
+ // OffsetX (X=0) is the OffsetX coordinate of the cursor cell to start
+ // displaying the image. OffsetX=0 is the leftmost cell. This must be
+ // smaller than the terminal cell width.
+ OffsetX int
+
+ // OffsetY (Y=0) is the OffsetY coordinate of the cursor cell to start
+ // displaying the image. OffsetY=0 is the topmost cell. This must be
+ // smaller than the terminal cell height.
+ OffsetY int
+
+ // Columns (c=0) is the number of columns to display the image. The image
+ // will be scaled to fit the number of columns.
+ Columns int
+
+ // Rows (r=0) is the number of rows to display the image. The image will be
+ // scaled to fit the number of rows.
+ Rows int
+
+ // VirtualPlacement (U=0) whether to use virtual placement. This is used
+ // with Unicode [Placeholder] to display images.
+ VirtualPlacement bool
+
+ // DoNotMoveCursor (C=0) whether to move the cursor after displaying the
+ // image.
+ DoNotMoveCursor bool
+
+ // ParentID (P=0) is the parent image ID. The parent ID is the ID of the
+ // image that is the parent of the current image. This is used with Unicode
+ // [Placeholder] to display images relative to the parent image.
+ ParentID int
+
+ // ParentPlacementID (Q=0) is the parent placement ID. The parent placement
+ // ID is the ID of the placement of the parent image. This is used with
+ // Unicode [Placeholder] to display images relative to the parent image.
+ ParentPlacementID int
+
+ // Delete options.
+
+ // Delete (d=a) is the delete action. Can be one of [DeleteAll],
+ // [DeleteID], [DeleteNumber], [DeleteCursor], [DeleteFrames],
+ // [DeleteCell], [DeleteCellZ], [DeleteRange], [DeleteColumn], [DeleteRow],
+ // [DeleteZ].
+ Delete byte
+
+ // DeleteResources indicates whether to delete the resources associated
+ // with the image.
+ DeleteResources bool
+}
+
+// Options returns the options as a slice of a key-value pairs.
+func (o *Options) Options() (opts []string) {
+ opts = []string{}
+ if o.Format == 0 {
+ o.Format = RGBA
+ }
+
+ if o.Action == 0 {
+ o.Action = Transmit
+ }
+
+ if o.Delete == 0 {
+ o.Delete = DeleteAll
+ }
+
+ if o.Transmission == 0 {
+ if len(o.File) > 0 {
+ o.Transmission = File
+ } else {
+ o.Transmission = Direct
+ }
+ }
+
+ if o.Format != RGBA {
+ opts = append(opts, fmt.Sprintf("f=%d", o.Format))
+ }
+
+ if o.Quite > 0 {
+ opts = append(opts, fmt.Sprintf("q=%d", o.Quite))
+ }
+
+ if o.ID > 0 {
+ opts = append(opts, fmt.Sprintf("i=%d", o.ID))
+ }
+
+ if o.PlacementID > 0 {
+ opts = append(opts, fmt.Sprintf("p=%d", o.PlacementID))
+ }
+
+ if o.Number > 0 {
+ opts = append(opts, fmt.Sprintf("I=%d", o.Number))
+ }
+
+ if o.ImageWidth > 0 {
+ opts = append(opts, fmt.Sprintf("s=%d", o.ImageWidth))
+ }
+
+ if o.ImageHeight > 0 {
+ opts = append(opts, fmt.Sprintf("v=%d", o.ImageHeight))
+ }
+
+ if o.Transmission != Direct {
+ opts = append(opts, fmt.Sprintf("t=%c", o.Transmission))
+ }
+
+ if o.Size > 0 {
+ opts = append(opts, fmt.Sprintf("S=%d", o.Size))
+ }
+
+ if o.Offset > 0 {
+ opts = append(opts, fmt.Sprintf("O=%d", o.Offset))
+ }
+
+ if o.Compression == Zlib {
+ opts = append(opts, fmt.Sprintf("o=%c", o.Compression))
+ }
+
+ if o.VirtualPlacement {
+ opts = append(opts, "U=1")
+ }
+
+ if o.DoNotMoveCursor {
+ opts = append(opts, "C=1")
+ }
+
+ if o.ParentID > 0 {
+ opts = append(opts, fmt.Sprintf("P=%d", o.ParentID))
+ }
+
+ if o.ParentPlacementID > 0 {
+ opts = append(opts, fmt.Sprintf("Q=%d", o.ParentPlacementID))
+ }
+
+ if o.X > 0 {
+ opts = append(opts, fmt.Sprintf("x=%d", o.X))
+ }
+
+ if o.Y > 0 {
+ opts = append(opts, fmt.Sprintf("y=%d", o.Y))
+ }
+
+ if o.Z > 0 {
+ opts = append(opts, fmt.Sprintf("z=%d", o.Z))
+ }
+
+ if o.Width > 0 {
+ opts = append(opts, fmt.Sprintf("w=%d", o.Width))
+ }
+
+ if o.Height > 0 {
+ opts = append(opts, fmt.Sprintf("h=%d", o.Height))
+ }
+
+ if o.OffsetX > 0 {
+ opts = append(opts, fmt.Sprintf("X=%d", o.OffsetX))
+ }
+
+ if o.OffsetY > 0 {
+ opts = append(opts, fmt.Sprintf("Y=%d", o.OffsetY))
+ }
+
+ if o.Columns > 0 {
+ opts = append(opts, fmt.Sprintf("c=%d", o.Columns))
+ }
+
+ if o.Rows > 0 {
+ opts = append(opts, fmt.Sprintf("r=%d", o.Rows))
+ }
+
+ if o.Delete != DeleteAll || o.DeleteResources {
+ da := o.Delete
+ if o.DeleteResources {
+ da = da - ' ' // to uppercase
+ }
+
+ opts = append(opts, fmt.Sprintf("d=%c", da))
+ }
+
+ if o.Action != Transmit {
+ opts = append(opts, fmt.Sprintf("a=%c", o.Action))
+ }
+
+ return
+}
+
+// String returns the string representation of the options.
+func (o Options) String() string {
+ return strings.Join(o.Options(), ",")
+}
+
+// MarshalText returns the string representation of the options.
+func (o Options) MarshalText() ([]byte, error) {
+ return []byte(o.String()), nil
+}
+
+// UnmarshalText parses the options from the given string.
+func (o *Options) UnmarshalText(text []byte) error {
+ opts := strings.Split(string(text), ",")
+ for _, opt := range opts {
+ ps := strings.SplitN(opt, "=", 2)
+ if len(ps) != 2 || len(ps[1]) == 0 {
+ continue
+ }
+
+ switch ps[0] {
+ case "a":
+ o.Action = ps[1][0]
+ case "o":
+ o.Compression = ps[1][0]
+ case "t":
+ o.Transmission = ps[1][0]
+ case "d":
+ d := ps[1][0]
+ if d >= 'A' && d <= 'Z' {
+ o.DeleteResources = true
+ d = d + ' ' // to lowercase
+ }
+ o.Delete = d
+ case "i", "q", "p", "I", "f", "s", "v", "S", "O", "m", "x", "y", "z", "w", "h", "X", "Y", "c", "r", "U", "P", "Q":
+ v, err := strconv.Atoi(ps[1])
+ if err != nil {
+ continue
+ }
+
+ switch ps[0] {
+ case "i":
+ o.ID = v
+ case "q":
+ o.Quite = byte(v)
+ case "p":
+ o.PlacementID = v
+ case "I":
+ o.Number = v
+ case "f":
+ o.Format = v
+ case "s":
+ o.ImageWidth = v
+ case "v":
+ o.ImageHeight = v
+ case "S":
+ o.Size = v
+ case "O":
+ o.Offset = v
+ case "m":
+ o.Chunk = v == 0 || v == 1
+ case "x":
+ o.X = v
+ case "y":
+ o.Y = v
+ case "z":
+ o.Z = v
+ case "w":
+ o.Width = v
+ case "h":
+ o.Height = v
+ case "X":
+ o.OffsetX = v
+ case "Y":
+ o.OffsetY = v
+ case "c":
+ o.Columns = v
+ case "r":
+ o.Rows = v
+ case "U":
+ o.VirtualPlacement = v == 1
+ case "P":
+ o.ParentID = v
+ case "Q":
+ o.ParentPlacementID = v
+ }
+ }
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/method.go b/vendor/github.com/charmbracelet/x/ansi/method.go
new file mode 100644
index 0000000..0218809
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/method.go
@@ -0,0 +1,172 @@
+package ansi
+
+// Method is a type that represents the how the renderer should calculate the
+// display width of cells.
+type Method uint8
+
+// Display width modes.
+const (
+ WcWidth Method = iota
+ GraphemeWidth
+)
+
+// StringWidth returns the width of a string in cells. This is the number of
+// cells that the string will occupy when printed in a terminal. ANSI escape
+// codes are ignored and wide characters (such as East Asians and emojis) are
+// accounted for.
+func (m Method) StringWidth(s string) int {
+ return stringWidth(m, s)
+}
+
+// Truncate truncates a string to a given length, adding a tail to the end if
+// the string is longer than the given length. This function is aware of ANSI
+// escape codes and will not break them, and accounts for wide-characters (such
+// as East-Asian characters and emojis).
+func (m Method) Truncate(s string, length int, tail string) string {
+ return truncate(m, s, length, tail)
+}
+
+// TruncateLeft truncates a string to a given length, adding a prefix to the
+// beginning if the string is longer than the given length. This function is
+// aware of ANSI escape codes and will not break them, and accounts for
+// wide-characters (such as East-Asian characters and emojis).
+func (m Method) TruncateLeft(s string, length int, prefix string) string {
+ return truncateLeft(m, s, length, prefix)
+}
+
+// Cut the string, without adding any prefix or tail strings. This function is
+// aware of ANSI escape codes and will not break them, and accounts for
+// wide-characters (such as East-Asian characters and emojis). Note that the
+// [left] parameter is inclusive, while [right] isn't.
+func (m Method) Cut(s string, left, right int) string {
+ return cut(m, s, left, right)
+}
+
+// Hardwrap wraps a string or a block of text to a given line length, breaking
+// word boundaries. This will preserve ANSI escape codes and will account for
+// wide-characters in the string.
+// When preserveSpace is true, spaces at the beginning of a line will be
+// preserved.
+// This treats the text as a sequence of graphemes.
+func (m Method) Hardwrap(s string, length int, preserveSpace bool) string {
+ return hardwrap(m, s, length, preserveSpace)
+}
+
+// Wordwrap wraps a string or a block of text to a given line length, not
+// breaking word boundaries. This will preserve ANSI escape codes and will
+// account for wide-characters in the string.
+// The breakpoints string is a list of characters that are considered
+// breakpoints for word wrapping. A hyphen (-) is always considered a
+// breakpoint.
+//
+// Note: breakpoints must be a string of 1-cell wide rune characters.
+func (m Method) Wordwrap(s string, length int, breakpoints string) string {
+ return wordwrap(m, s, length, breakpoints)
+}
+
+// Wrap wraps a string or a block of text to a given line length, breaking word
+// boundaries if necessary. This will preserve ANSI escape codes and will
+// account for wide-characters in the string. The breakpoints string is a list
+// of characters that are considered breakpoints for word wrapping. A hyphen
+// (-) is always considered a breakpoint.
+//
+// Note: breakpoints must be a string of 1-cell wide rune characters.
+func (m Method) Wrap(s string, length int, breakpoints string) string {
+ return wrap(m, s, length, breakpoints)
+}
+
+// DecodeSequence decodes the first ANSI escape sequence or a printable
+// grapheme from the given data. It returns the sequence slice, the number of
+// bytes read, the cell width for each sequence, and the new state.
+//
+// The cell width will always be 0 for control and escape sequences, 1 for
+// ASCII printable characters, and the number of cells other Unicode characters
+// occupy. It uses the uniseg package to calculate the width of Unicode
+// graphemes and characters. This means it will always do grapheme clustering
+// (mode 2027).
+//
+// Passing a non-nil [*Parser] as the last argument will allow the decoder to
+// collect sequence parameters, data, and commands. The parser cmd will have
+// the packed command value that contains intermediate and prefix characters.
+// In the case of a OSC sequence, the cmd will be the OSC command number. Use
+// [Cmd] and [Param] types to unpack command intermediates and prefixes as well
+// as parameters.
+//
+// Zero [Cmd] means the CSI, DCS, or ESC sequence is invalid. Moreover, checking the
+// validity of other data sequences, OSC, DCS, etc, will require checking for
+// the returned sequence terminator bytes such as ST (ESC \\) and BEL).
+//
+// We store the command byte in [Cmd] in the most significant byte, the
+// prefix byte in the next byte, and the intermediate byte in the least
+// significant byte. This is done to avoid using a struct to store the command
+// and its intermediates and prefixes. The command byte is always the least
+// significant byte i.e. [Cmd & 0xff]. Use the [Cmd] type to unpack the
+// command, intermediate, and prefix bytes. Note that we only collect the last
+// prefix character and intermediate byte.
+//
+// The [p.Params] slice will contain the parameters of the sequence. Any
+// sub-parameter will have the [parser.HasMoreFlag] set. Use the [Param] type
+// to unpack the parameters.
+//
+// Example:
+//
+// var state byte // the initial state is always zero [NormalState]
+// p := NewParser(32, 1024) // create a new parser with a 32 params buffer and 1024 data buffer (optional)
+// input := []byte("\x1b[31mHello, World!\x1b[0m")
+// for len(input) > 0 {
+// seq, width, n, newState := DecodeSequence(input, state, p)
+// log.Printf("seq: %q, width: %d", seq, width)
+// state = newState
+// input = input[n:]
+// }
+func (m Method) DecodeSequence(data []byte, state byte, p *Parser) (seq []byte, width, n int, newState byte) {
+ return decodeSequence(m, data, state, p)
+}
+
+// DecodeSequenceInString decodes the first ANSI escape sequence or a printable
+// grapheme from the given data. It returns the sequence slice, the number of
+// bytes read, the cell width for each sequence, and the new state.
+//
+// The cell width will always be 0 for control and escape sequences, 1 for
+// ASCII printable characters, and the number of cells other Unicode characters
+// occupy. It uses the uniseg package to calculate the width of Unicode
+// graphemes and characters. This means it will always do grapheme clustering
+// (mode 2027).
+//
+// Passing a non-nil [*Parser] as the last argument will allow the decoder to
+// collect sequence parameters, data, and commands. The parser cmd will have
+// the packed command value that contains intermediate and prefix characters.
+// In the case of a OSC sequence, the cmd will be the OSC command number. Use
+// [Cmd] and [Param] types to unpack command intermediates and prefixes as well
+// as parameters.
+//
+// Zero [Cmd] means the CSI, DCS, or ESC sequence is invalid. Moreover, checking the
+// validity of other data sequences, OSC, DCS, etc, will require checking for
+// the returned sequence terminator bytes such as ST (ESC \\) and BEL).
+//
+// We store the command byte in [Cmd] in the most significant byte, the
+// prefix byte in the next byte, and the intermediate byte in the least
+// significant byte. This is done to avoid using a struct to store the command
+// and its intermediates and prefixes. The command byte is always the least
+// significant byte i.e. [Cmd & 0xff]. Use the [Cmd] type to unpack the
+// command, intermediate, and prefix bytes. Note that we only collect the last
+// prefix character and intermediate byte.
+//
+// The [p.Params] slice will contain the parameters of the sequence. Any
+// sub-parameter will have the [parser.HasMoreFlag] set. Use the [Param] type
+// to unpack the parameters.
+//
+// Example:
+//
+// var state byte // the initial state is always zero [NormalState]
+// p := NewParser(32, 1024) // create a new parser with a 32 params buffer and 1024 data buffer (optional)
+// input := []byte("\x1b[31mHello, World!\x1b[0m")
+// for len(input) > 0 {
+// seq, width, n, newState := DecodeSequenceInString(input, state, p)
+// log.Printf("seq: %q, width: %d", seq, width)
+// state = newState
+// input = input[n:]
+// }
+func (m Method) DecodeSequenceInString(data string, state byte, p *Parser) (seq string, width, n int, newState byte) {
+ return decodeSequence(m, data, state, p)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/mode.go b/vendor/github.com/charmbracelet/x/ansi/mode.go
new file mode 100644
index 0000000..57f3f0a
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/mode.go
@@ -0,0 +1,763 @@
+package ansi
+
+import (
+ "strconv"
+ "strings"
+)
+
+// ModeSetting represents a mode setting.
+type ModeSetting byte
+
+// ModeSetting constants.
+const (
+ ModeNotRecognized ModeSetting = iota
+ ModeSet
+ ModeReset
+ ModePermanentlySet
+ ModePermanentlyReset
+)
+
+// IsNotRecognized returns true if the mode is not recognized.
+func (m ModeSetting) IsNotRecognized() bool {
+ return m == ModeNotRecognized
+}
+
+// IsSet returns true if the mode is set or permanently set.
+func (m ModeSetting) IsSet() bool {
+ return m == ModeSet || m == ModePermanentlySet
+}
+
+// IsReset returns true if the mode is reset or permanently reset.
+func (m ModeSetting) IsReset() bool {
+ return m == ModeReset || m == ModePermanentlyReset
+}
+
+// IsPermanentlySet returns true if the mode is permanently set.
+func (m ModeSetting) IsPermanentlySet() bool {
+ return m == ModePermanentlySet
+}
+
+// IsPermanentlyReset returns true if the mode is permanently reset.
+func (m ModeSetting) IsPermanentlyReset() bool {
+ return m == ModePermanentlyReset
+}
+
+// Mode represents an interface for terminal modes.
+// Modes can be set, reset, and requested.
+type Mode interface {
+ Mode() int
+}
+
+// SetMode (SM) returns a sequence to set a mode.
+// The mode arguments are a list of modes to set.
+//
+// If one of the modes is a [DECMode], the function will returns two escape
+// sequences.
+//
+// ANSI format:
+//
+// CSI Pd ; ... ; Pd h
+//
+// DEC format:
+//
+// CSI ? Pd ; ... ; Pd h
+//
+// See: https://vt100.net/docs/vt510-rm/SM.html
+func SetMode(modes ...Mode) string {
+ return setMode(false, modes...)
+}
+
+// SM is an alias for [SetMode].
+func SM(modes ...Mode) string {
+ return SetMode(modes...)
+}
+
+// ResetMode (RM) returns a sequence to reset a mode.
+// The mode arguments are a list of modes to reset.
+//
+// If one of the modes is a [DECMode], the function will returns two escape
+// sequences.
+//
+// ANSI format:
+//
+// CSI Pd ; ... ; Pd l
+//
+// DEC format:
+//
+// CSI ? Pd ; ... ; Pd l
+//
+// See: https://vt100.net/docs/vt510-rm/RM.html
+func ResetMode(modes ...Mode) string {
+ return setMode(true, modes...)
+}
+
+// RM is an alias for [ResetMode].
+func RM(modes ...Mode) string {
+ return ResetMode(modes...)
+}
+
+func setMode(reset bool, modes ...Mode) (s string) {
+ if len(modes) == 0 {
+ return
+ }
+
+ cmd := "h"
+ if reset {
+ cmd = "l"
+ }
+
+ seq := "\x1b["
+ if len(modes) == 1 {
+ switch modes[0].(type) {
+ case DECMode:
+ seq += "?"
+ }
+ return seq + strconv.Itoa(modes[0].Mode()) + cmd
+ }
+
+ dec := make([]string, 0, len(modes)/2)
+ ansi := make([]string, 0, len(modes)/2)
+ for _, m := range modes {
+ switch m.(type) {
+ case DECMode:
+ dec = append(dec, strconv.Itoa(m.Mode()))
+ case ANSIMode:
+ ansi = append(ansi, strconv.Itoa(m.Mode()))
+ }
+ }
+
+ if len(ansi) > 0 {
+ s += seq + strings.Join(ansi, ";") + cmd
+ }
+ if len(dec) > 0 {
+ s += seq + "?" + strings.Join(dec, ";") + cmd
+ }
+ return
+}
+
+// RequestMode (DECRQM) returns a sequence to request a mode from the terminal.
+// The terminal responds with a report mode function [DECRPM].
+//
+// ANSI format:
+//
+// CSI Pa $ p
+//
+// DEC format:
+//
+// CSI ? Pa $ p
+//
+// See: https://vt100.net/docs/vt510-rm/DECRQM.html
+func RequestMode(m Mode) string {
+ seq := "\x1b["
+ switch m.(type) {
+ case DECMode:
+ seq += "?"
+ }
+ return seq + strconv.Itoa(m.Mode()) + "$p"
+}
+
+// DECRQM is an alias for [RequestMode].
+func DECRQM(m Mode) string {
+ return RequestMode(m)
+}
+
+// ReportMode (DECRPM) returns a sequence that the terminal sends to the host
+// in response to a mode request [DECRQM].
+//
+// ANSI format:
+//
+// CSI Pa ; Ps ; $ y
+//
+// DEC format:
+//
+// CSI ? Pa ; Ps $ y
+//
+// Where Pa is the mode number, and Ps is the mode value.
+//
+// 0: Not recognized
+// 1: Set
+// 2: Reset
+// 3: Permanent set
+// 4: Permanent reset
+//
+// See: https://vt100.net/docs/vt510-rm/DECRPM.html
+func ReportMode(mode Mode, value ModeSetting) string {
+ if value > 4 {
+ value = 0
+ }
+ switch mode.(type) {
+ case DECMode:
+ return "\x1b[?" + strconv.Itoa(mode.Mode()) + ";" + strconv.Itoa(int(value)) + "$y"
+ }
+ return "\x1b[" + strconv.Itoa(mode.Mode()) + ";" + strconv.Itoa(int(value)) + "$y"
+}
+
+// DECRPM is an alias for [ReportMode].
+func DECRPM(mode Mode, value ModeSetting) string {
+ return ReportMode(mode, value)
+}
+
+// ANSIMode represents an ANSI terminal mode.
+type ANSIMode int //nolint:revive
+
+// Mode returns the ANSI mode as an integer.
+func (m ANSIMode) Mode() int {
+ return int(m)
+}
+
+// DECMode represents a private DEC terminal mode.
+type DECMode int
+
+// Mode returns the DEC mode as an integer.
+func (m DECMode) Mode() int {
+ return int(m)
+}
+
+// Keyboard Action Mode (KAM) is a mode that controls locking of the keyboard.
+// When the keyboard is locked, it cannot send data to the terminal.
+//
+// See: https://vt100.net/docs/vt510-rm/KAM.html
+const (
+ KeyboardActionMode = ANSIMode(2)
+ KAM = KeyboardActionMode
+
+ SetKeyboardActionMode = "\x1b[2h"
+ ResetKeyboardActionMode = "\x1b[2l"
+ RequestKeyboardActionMode = "\x1b[2$p"
+)
+
+// Insert/Replace Mode (IRM) is a mode that determines whether characters are
+// inserted or replaced when typed.
+//
+// When enabled, characters are inserted at the cursor position pushing the
+// characters to the right. When disabled, characters replace the character at
+// the cursor position.
+//
+// See: https://vt100.net/docs/vt510-rm/IRM.html
+const (
+ InsertReplaceMode = ANSIMode(4)
+ IRM = InsertReplaceMode
+
+ SetInsertReplaceMode = "\x1b[4h"
+ ResetInsertReplaceMode = "\x1b[4l"
+ RequestInsertReplaceMode = "\x1b[4$p"
+)
+
+// Send Receive Mode (SRM) or Local Echo Mode is a mode that determines whether
+// the terminal echoes characters back to the host. When enabled, the terminal
+// sends characters to the host as they are typed.
+//
+// See: https://vt100.net/docs/vt510-rm/SRM.html
+const (
+ SendReceiveMode = ANSIMode(12)
+ LocalEchoMode = SendReceiveMode
+ SRM = SendReceiveMode
+
+ SetSendReceiveMode = "\x1b[12h"
+ ResetSendReceiveMode = "\x1b[12l"
+ RequestSendReceiveMode = "\x1b[12$p"
+
+ SetLocalEchoMode = "\x1b[12h"
+ ResetLocalEchoMode = "\x1b[12l"
+ RequestLocalEchoMode = "\x1b[12$p"
+)
+
+// Line Feed/New Line Mode (LNM) is a mode that determines whether the terminal
+// interprets the line feed character as a new line.
+//
+// When enabled, the terminal interprets the line feed character as a new line.
+// When disabled, the terminal interprets the line feed character as a line feed.
+//
+// A new line moves the cursor to the first position of the next line.
+// A line feed moves the cursor down one line without changing the column
+// scrolling the screen if necessary.
+//
+// See: https://vt100.net/docs/vt510-rm/LNM.html
+const (
+ LineFeedNewLineMode = ANSIMode(20)
+ LNM = LineFeedNewLineMode
+
+ SetLineFeedNewLineMode = "\x1b[20h"
+ ResetLineFeedNewLineMode = "\x1b[20l"
+ RequestLineFeedNewLineMode = "\x1b[20$p"
+)
+
+// Cursor Keys Mode (DECCKM) is a mode that determines whether the cursor keys
+// send ANSI cursor sequences or application sequences.
+//
+// See: https://vt100.net/docs/vt510-rm/DECCKM.html
+const (
+ CursorKeysMode = DECMode(1)
+ DECCKM = CursorKeysMode
+
+ SetCursorKeysMode = "\x1b[?1h"
+ ResetCursorKeysMode = "\x1b[?1l"
+ RequestCursorKeysMode = "\x1b[?1$p"
+)
+
+// Deprecated: use [SetCursorKeysMode] and [ResetCursorKeysMode] instead.
+const (
+ EnableCursorKeys = "\x1b[?1h"
+ DisableCursorKeys = "\x1b[?1l"
+)
+
+// Origin Mode (DECOM) is a mode that determines whether the cursor moves to the
+// home position or the margin position.
+//
+// See: https://vt100.net/docs/vt510-rm/DECOM.html
+const (
+ OriginMode = DECMode(6)
+ DECOM = OriginMode
+
+ SetOriginMode = "\x1b[?6h"
+ ResetOriginMode = "\x1b[?6l"
+ RequestOriginMode = "\x1b[?6$p"
+)
+
+// Auto Wrap Mode (DECAWM) is a mode that determines whether the cursor wraps
+// to the next line when it reaches the right margin.
+//
+// See: https://vt100.net/docs/vt510-rm/DECAWM.html
+const (
+ AutoWrapMode = DECMode(7)
+ DECAWM = AutoWrapMode
+
+ SetAutoWrapMode = "\x1b[?7h"
+ ResetAutoWrapMode = "\x1b[?7l"
+ RequestAutoWrapMode = "\x1b[?7$p"
+)
+
+// X10 Mouse Mode is a mode that determines whether the mouse reports on button
+// presses.
+//
+// The terminal responds with the following encoding:
+//
+// CSI M CbCxCy
+//
+// Where Cb is the button-1, where it can be 1, 2, or 3.
+// Cx and Cy are the x and y coordinates of the mouse event.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+const (
+ X10MouseMode = DECMode(9)
+
+ SetX10MouseMode = "\x1b[?9h"
+ ResetX10MouseMode = "\x1b[?9l"
+ RequestX10MouseMode = "\x1b[?9$p"
+)
+
+// Text Cursor Enable Mode (DECTCEM) is a mode that shows/hides the cursor.
+//
+// See: https://vt100.net/docs/vt510-rm/DECTCEM.html
+const (
+ TextCursorEnableMode = DECMode(25)
+ DECTCEM = TextCursorEnableMode
+
+ SetTextCursorEnableMode = "\x1b[?25h"
+ ResetTextCursorEnableMode = "\x1b[?25l"
+ RequestTextCursorEnableMode = "\x1b[?25$p"
+)
+
+// These are aliases for [SetTextCursorEnableMode] and [ResetTextCursorEnableMode].
+const (
+ ShowCursor = SetTextCursorEnableMode
+ HideCursor = ResetTextCursorEnableMode
+)
+
+// Text Cursor Enable Mode (DECTCEM) is a mode that shows/hides the cursor.
+//
+// See: https://vt100.net/docs/vt510-rm/DECTCEM.html
+//
+// Deprecated: use [SetTextCursorEnableMode] and [ResetTextCursorEnableMode] instead.
+const (
+ CursorEnableMode = DECMode(25)
+ RequestCursorVisibility = "\x1b[?25$p"
+)
+
+// Numeric Keypad Mode (DECNKM) is a mode that determines whether the keypad
+// sends application sequences or numeric sequences.
+//
+// This works like [DECKPAM] and [DECKPNM], but uses different sequences.
+//
+// See: https://vt100.net/docs/vt510-rm/DECNKM.html
+const (
+ NumericKeypadMode = DECMode(66)
+ DECNKM = NumericKeypadMode
+
+ SetNumericKeypadMode = "\x1b[?66h"
+ ResetNumericKeypadMode = "\x1b[?66l"
+ RequestNumericKeypadMode = "\x1b[?66$p"
+)
+
+// Backarrow Key Mode (DECBKM) is a mode that determines whether the backspace
+// key sends a backspace or delete character. Disabled by default.
+//
+// See: https://vt100.net/docs/vt510-rm/DECBKM.html
+const (
+ BackarrowKeyMode = DECMode(67)
+ DECBKM = BackarrowKeyMode
+
+ SetBackarrowKeyMode = "\x1b[?67h"
+ ResetBackarrowKeyMode = "\x1b[?67l"
+ RequestBackarrowKeyMode = "\x1b[?67$p"
+)
+
+// Left Right Margin Mode (DECLRMM) is a mode that determines whether the left
+// and right margins can be set with [DECSLRM].
+//
+// See: https://vt100.net/docs/vt510-rm/DECLRMM.html
+const (
+ LeftRightMarginMode = DECMode(69)
+ DECLRMM = LeftRightMarginMode
+
+ SetLeftRightMarginMode = "\x1b[?69h"
+ ResetLeftRightMarginMode = "\x1b[?69l"
+ RequestLeftRightMarginMode = "\x1b[?69$p"
+)
+
+// Normal Mouse Mode is a mode that determines whether the mouse reports on
+// button presses and releases. It will also report modifier keys, wheel
+// events, and extra buttons.
+//
+// It uses the same encoding as [X10MouseMode] with a few differences:
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+const (
+ NormalMouseMode = DECMode(1000)
+
+ SetNormalMouseMode = "\x1b[?1000h"
+ ResetNormalMouseMode = "\x1b[?1000l"
+ RequestNormalMouseMode = "\x1b[?1000$p"
+)
+
+// VT Mouse Tracking is a mode that determines whether the mouse reports on
+// button press and release.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+//
+// Deprecated: use [NormalMouseMode] instead.
+const (
+ MouseMode = DECMode(1000)
+
+ EnableMouse = "\x1b[?1000h"
+ DisableMouse = "\x1b[?1000l"
+ RequestMouse = "\x1b[?1000$p"
+)
+
+// Highlight Mouse Tracking is a mode that determines whether the mouse reports
+// on button presses, releases, and highlighted cells.
+//
+// It uses the same encoding as [NormalMouseMode] with a few differences:
+//
+// On highlight events, the terminal responds with the following encoding:
+//
+// CSI t CxCy
+// CSI T CxCyCxCyCxCy
+//
+// Where the parameters are startx, starty, endx, endy, mousex, and mousey.
+const (
+ HighlightMouseMode = DECMode(1001)
+
+ SetHighlightMouseMode = "\x1b[?1001h"
+ ResetHighlightMouseMode = "\x1b[?1001l"
+ RequestHighlightMouseMode = "\x1b[?1001$p"
+)
+
+// VT Hilite Mouse Tracking is a mode that determines whether the mouse reports on
+// button presses, releases, and highlighted cells.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+//
+// Deprecated: use [HighlightMouseMode] instead.
+const (
+ MouseHiliteMode = DECMode(1001)
+
+ EnableMouseHilite = "\x1b[?1001h"
+ DisableMouseHilite = "\x1b[?1001l"
+ RequestMouseHilite = "\x1b[?1001$p"
+)
+
+// Button Event Mouse Tracking is essentially the same as [NormalMouseMode],
+// but it also reports button-motion events when a button is pressed.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+const (
+ ButtonEventMouseMode = DECMode(1002)
+
+ SetButtonEventMouseMode = "\x1b[?1002h"
+ ResetButtonEventMouseMode = "\x1b[?1002l"
+ RequestButtonEventMouseMode = "\x1b[?1002$p"
+)
+
+// Cell Motion Mouse Tracking is a mode that determines whether the mouse
+// reports on button press, release, and motion events.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+//
+// Deprecated: use [ButtonEventMouseMode] instead.
+const (
+ MouseCellMotionMode = DECMode(1002)
+
+ EnableMouseCellMotion = "\x1b[?1002h"
+ DisableMouseCellMotion = "\x1b[?1002l"
+ RequestMouseCellMotion = "\x1b[?1002$p"
+)
+
+// Any Event Mouse Tracking is the same as [ButtonEventMouseMode], except that
+// all motion events are reported even if no mouse buttons are pressed.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+const (
+ AnyEventMouseMode = DECMode(1003)
+
+ SetAnyEventMouseMode = "\x1b[?1003h"
+ ResetAnyEventMouseMode = "\x1b[?1003l"
+ RequestAnyEventMouseMode = "\x1b[?1003$p"
+)
+
+// All Mouse Tracking is a mode that determines whether the mouse reports on
+// button press, release, motion, and highlight events.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+//
+// Deprecated: use [AnyEventMouseMode] instead.
+const (
+ MouseAllMotionMode = DECMode(1003)
+
+ EnableMouseAllMotion = "\x1b[?1003h"
+ DisableMouseAllMotion = "\x1b[?1003l"
+ RequestMouseAllMotion = "\x1b[?1003$p"
+)
+
+// Focus Event Mode is a mode that determines whether the terminal reports focus
+// and blur events.
+//
+// The terminal sends the following encoding:
+//
+// CSI I // Focus In
+// CSI O // Focus Out
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Focus-Tracking
+const (
+ FocusEventMode = DECMode(1004)
+
+ SetFocusEventMode = "\x1b[?1004h"
+ ResetFocusEventMode = "\x1b[?1004l"
+ RequestFocusEventMode = "\x1b[?1004$p"
+)
+
+// Deprecated: use [SetFocusEventMode], [ResetFocusEventMode], and
+// [RequestFocusEventMode] instead.
+const (
+ ReportFocusMode = DECMode(1004)
+
+ EnableReportFocus = "\x1b[?1004h"
+ DisableReportFocus = "\x1b[?1004l"
+ RequestReportFocus = "\x1b[?1004$p"
+)
+
+// SGR Extended Mouse Mode is a mode that changes the mouse tracking encoding
+// to use SGR parameters.
+//
+// The terminal responds with the following encoding:
+//
+// CSI < Cb ; Cx ; Cy M
+//
+// Where Cb is the same as [NormalMouseMode], and Cx and Cy are the x and y.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+const (
+ SgrExtMouseMode = DECMode(1006)
+
+ SetSgrExtMouseMode = "\x1b[?1006h"
+ ResetSgrExtMouseMode = "\x1b[?1006l"
+ RequestSgrExtMouseMode = "\x1b[?1006$p"
+)
+
+// Deprecated: use [SgrExtMouseMode] [SetSgrExtMouseMode],
+// [ResetSgrExtMouseMode], and [RequestSgrExtMouseMode] instead.
+const (
+ MouseSgrExtMode = DECMode(1006)
+ EnableMouseSgrExt = "\x1b[?1006h"
+ DisableMouseSgrExt = "\x1b[?1006l"
+ RequestMouseSgrExt = "\x1b[?1006$p"
+)
+
+// UTF-8 Extended Mouse Mode is a mode that changes the mouse tracking encoding
+// to use UTF-8 parameters.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+const (
+ Utf8ExtMouseMode = DECMode(1005)
+
+ SetUtf8ExtMouseMode = "\x1b[?1005h"
+ ResetUtf8ExtMouseMode = "\x1b[?1005l"
+ RequestUtf8ExtMouseMode = "\x1b[?1005$p"
+)
+
+// URXVT Extended Mouse Mode is a mode that changes the mouse tracking encoding
+// to use an alternate encoding.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+const (
+ UrxvtExtMouseMode = DECMode(1015)
+
+ SetUrxvtExtMouseMode = "\x1b[?1015h"
+ ResetUrxvtExtMouseMode = "\x1b[?1015l"
+ RequestUrxvtExtMouseMode = "\x1b[?1015$p"
+)
+
+// SGR Pixel Extended Mouse Mode is a mode that changes the mouse tracking
+// encoding to use SGR parameters with pixel coordinates.
+//
+// This is similar to [SgrExtMouseMode], but also reports pixel coordinates.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+const (
+ SgrPixelExtMouseMode = DECMode(1016)
+
+ SetSgrPixelExtMouseMode = "\x1b[?1016h"
+ ResetSgrPixelExtMouseMode = "\x1b[?1016l"
+ RequestSgrPixelExtMouseMode = "\x1b[?1016$p"
+)
+
+// Alternate Screen Mode is a mode that determines whether the alternate screen
+// buffer is active. When this mode is enabled, the alternate screen buffer is
+// cleared.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer
+const (
+ AltScreenMode = DECMode(1047)
+
+ SetAltScreenMode = "\x1b[?1047h"
+ ResetAltScreenMode = "\x1b[?1047l"
+ RequestAltScreenMode = "\x1b[?1047$p"
+)
+
+// Save Cursor Mode is a mode that saves the cursor position.
+// This is equivalent to [SaveCursor] and [RestoreCursor].
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer
+const (
+ SaveCursorMode = DECMode(1048)
+
+ SetSaveCursorMode = "\x1b[?1048h"
+ ResetSaveCursorMode = "\x1b[?1048l"
+ RequestSaveCursorMode = "\x1b[?1048$p"
+)
+
+// Alternate Screen Save Cursor Mode is a mode that saves the cursor position as in
+// [SaveCursorMode], switches to the alternate screen buffer as in [AltScreenMode],
+// and clears the screen on switch.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer
+const (
+ AltScreenSaveCursorMode = DECMode(1049)
+
+ SetAltScreenSaveCursorMode = "\x1b[?1049h"
+ ResetAltScreenSaveCursorMode = "\x1b[?1049l"
+ RequestAltScreenSaveCursorMode = "\x1b[?1049$p"
+)
+
+// Alternate Screen Buffer is a mode that determines whether the alternate screen
+// buffer is active.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer
+//
+// Deprecated: use [AltScreenSaveCursorMode] instead.
+const (
+ AltScreenBufferMode = DECMode(1049)
+
+ SetAltScreenBufferMode = "\x1b[?1049h"
+ ResetAltScreenBufferMode = "\x1b[?1049l"
+ RequestAltScreenBufferMode = "\x1b[?1049$p"
+
+ EnableAltScreenBuffer = "\x1b[?1049h"
+ DisableAltScreenBuffer = "\x1b[?1049l"
+ RequestAltScreenBuffer = "\x1b[?1049$p"
+)
+
+// Bracketed Paste Mode is a mode that determines whether pasted text is
+// bracketed with escape sequences.
+//
+// See: https://cirw.in/blog/bracketed-paste
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Bracketed-Paste-Mode
+const (
+ BracketedPasteMode = DECMode(2004)
+
+ SetBracketedPasteMode = "\x1b[?2004h"
+ ResetBracketedPasteMode = "\x1b[?2004l"
+ RequestBracketedPasteMode = "\x1b[?2004$p"
+)
+
+// Deprecated: use [SetBracketedPasteMode], [ResetBracketedPasteMode], and
+// [RequestBracketedPasteMode] instead.
+const (
+ EnableBracketedPaste = "\x1b[?2004h"
+ DisableBracketedPaste = "\x1b[?2004l"
+ RequestBracketedPaste = "\x1b[?2004$p"
+)
+
+// Synchronized Output Mode is a mode that determines whether output is
+// synchronized with the terminal.
+//
+// See: https://gist.github.com/christianparpart/d8a62cc1ab659194337d73e399004036
+const (
+ SynchronizedOutputMode = DECMode(2026)
+
+ SetSynchronizedOutputMode = "\x1b[?2026h"
+ ResetSynchronizedOutputMode = "\x1b[?2026l"
+ RequestSynchronizedOutputMode = "\x1b[?2026$p"
+)
+
+// Deprecated: use [SynchronizedOutputMode], [SetSynchronizedOutputMode], and
+// [ResetSynchronizedOutputMode], and [RequestSynchronizedOutputMode] instead.
+const (
+ SyncdOutputMode = DECMode(2026)
+
+ EnableSyncdOutput = "\x1b[?2026h"
+ DisableSyncdOutput = "\x1b[?2026l"
+ RequestSyncdOutput = "\x1b[?2026$p"
+)
+
+// Grapheme Clustering Mode is a mode that determines whether the terminal
+// should look for grapheme clusters instead of single runes in the rendered
+// text. This makes the terminal properly render combining characters such as
+// emojis.
+//
+// See: https://github.com/contour-terminal/terminal-unicode-core
+const (
+ GraphemeClusteringMode = DECMode(2027)
+
+ SetGraphemeClusteringMode = "\x1b[?2027h"
+ ResetGraphemeClusteringMode = "\x1b[?2027l"
+ RequestGraphemeClusteringMode = "\x1b[?2027$p"
+)
+
+// Deprecated: use [SetGraphemeClusteringMode], [ResetGraphemeClusteringMode], and
+// [RequestGraphemeClusteringMode] instead.
+const (
+ EnableGraphemeClustering = "\x1b[?2027h"
+ DisableGraphemeClustering = "\x1b[?2027l"
+ RequestGraphemeClustering = "\x1b[?2027$p"
+)
+
+// Win32Input is a mode that determines whether input is processed by the
+// Win32 console and Conpty.
+//
+// See: https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md
+const (
+ Win32InputMode = DECMode(9001)
+
+ SetWin32InputMode = "\x1b[?9001h"
+ ResetWin32InputMode = "\x1b[?9001l"
+ RequestWin32InputMode = "\x1b[?9001$p"
+)
+
+// Deprecated: use [SetWin32InputMode], [ResetWin32InputMode], and
+// [RequestWin32InputMode] instead.
+const (
+ EnableWin32Input = "\x1b[?9001h"
+ DisableWin32Input = "\x1b[?9001l"
+ RequestWin32Input = "\x1b[?9001$p"
+)
diff --git a/vendor/github.com/charmbracelet/x/ansi/modes.go b/vendor/github.com/charmbracelet/x/ansi/modes.go
new file mode 100644
index 0000000..1bec5bc
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/modes.go
@@ -0,0 +1,71 @@
+package ansi
+
+// Modes represents the terminal modes that can be set or reset. By default,
+// all modes are [ModeNotRecognized].
+type Modes map[Mode]ModeSetting
+
+// NewModes creates a new Modes map. By default, all modes are
+// [ModeNotRecognized].
+func NewModes() Modes {
+ return make(Modes)
+}
+
+// Get returns the setting of a terminal mode. If the mode is not set, it
+// returns [ModeNotRecognized].
+func (m Modes) Get(mode Mode) ModeSetting {
+ return m[mode]
+}
+
+// Delete deletes a terminal mode. This has the same effect as setting the mode
+// to [ModeNotRecognized].
+func (m Modes) Delete(mode Mode) {
+ delete(m, mode)
+}
+
+// Set sets a terminal mode to [ModeSet].
+func (m Modes) Set(modes ...Mode) {
+ for _, mode := range modes {
+ m[mode] = ModeSet
+ }
+}
+
+// PermanentlySet sets a terminal mode to [ModePermanentlySet].
+func (m Modes) PermanentlySet(modes ...Mode) {
+ for _, mode := range modes {
+ m[mode] = ModePermanentlySet
+ }
+}
+
+// Reset sets a terminal mode to [ModeReset].
+func (m Modes) Reset(modes ...Mode) {
+ for _, mode := range modes {
+ m[mode] = ModeReset
+ }
+}
+
+// PermanentlyReset sets a terminal mode to [ModePermanentlyReset].
+func (m Modes) PermanentlyReset(modes ...Mode) {
+ for _, mode := range modes {
+ m[mode] = ModePermanentlyReset
+ }
+}
+
+// IsSet returns true if the mode is set to [ModeSet] or [ModePermanentlySet].
+func (m Modes) IsSet(mode Mode) bool {
+ return m[mode].IsSet()
+}
+
+// IsPermanentlySet returns true if the mode is set to [ModePermanentlySet].
+func (m Modes) IsPermanentlySet(mode Mode) bool {
+ return m[mode].IsPermanentlySet()
+}
+
+// IsReset returns true if the mode is set to [ModeReset] or [ModePermanentlyReset].
+func (m Modes) IsReset(mode Mode) bool {
+ return m[mode].IsReset()
+}
+
+// IsPermanentlyReset returns true if the mode is set to [ModePermanentlyReset].
+func (m Modes) IsPermanentlyReset(mode Mode) bool {
+ return m[mode].IsPermanentlyReset()
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/mouse.go b/vendor/github.com/charmbracelet/x/ansi/mouse.go
new file mode 100644
index 0000000..95b0127
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/mouse.go
@@ -0,0 +1,172 @@
+package ansi
+
+import (
+ "fmt"
+)
+
+// MouseButton represents the button that was pressed during a mouse message.
+type MouseButton byte
+
+// Mouse event buttons
+//
+// This is based on X11 mouse button codes.
+//
+// 1 = left button
+// 2 = middle button (pressing the scroll wheel)
+// 3 = right button
+// 4 = turn scroll wheel up
+// 5 = turn scroll wheel down
+// 6 = push scroll wheel left
+// 7 = push scroll wheel right
+// 8 = 4th button (aka browser backward button)
+// 9 = 5th button (aka browser forward button)
+// 10
+// 11
+//
+// Other buttons are not supported.
+const (
+ MouseNone MouseButton = iota
+ MouseButton1
+ MouseButton2
+ MouseButton3
+ MouseButton4
+ MouseButton5
+ MouseButton6
+ MouseButton7
+ MouseButton8
+ MouseButton9
+ MouseButton10
+ MouseButton11
+
+ MouseLeft = MouseButton1
+ MouseMiddle = MouseButton2
+ MouseRight = MouseButton3
+ MouseWheelUp = MouseButton4
+ MouseWheelDown = MouseButton5
+ MouseWheelLeft = MouseButton6
+ MouseWheelRight = MouseButton7
+ MouseBackward = MouseButton8
+ MouseForward = MouseButton9
+ MouseRelease = MouseNone
+)
+
+var mouseButtons = map[MouseButton]string{
+ MouseNone: "none",
+ MouseLeft: "left",
+ MouseMiddle: "middle",
+ MouseRight: "right",
+ MouseWheelUp: "wheelup",
+ MouseWheelDown: "wheeldown",
+ MouseWheelLeft: "wheelleft",
+ MouseWheelRight: "wheelright",
+ MouseBackward: "backward",
+ MouseForward: "forward",
+ MouseButton10: "button10",
+ MouseButton11: "button11",
+}
+
+// String returns a string representation of the mouse button.
+func (b MouseButton) String() string {
+ return mouseButtons[b]
+}
+
+// EncodeMouseButton returns a byte representing a mouse button.
+// The button is a bitmask of the following leftmost values:
+//
+// - The first two bits are the button number:
+// 0 = left button, wheel up, or button no. 8 aka (backwards)
+// 1 = middle button, wheel down, or button no. 9 aka (forwards)
+// 2 = right button, wheel left, or button no. 10
+// 3 = release event, wheel right, or button no. 11
+//
+// - The third bit indicates whether the shift key was pressed.
+//
+// - The fourth bit indicates the alt key was pressed.
+//
+// - The fifth bit indicates the control key was pressed.
+//
+// - The sixth bit indicates motion events. Combined with button number 3, i.e.
+// release event, it represents a drag event.
+//
+// - The seventh bit indicates a wheel event.
+//
+// - The eighth bit indicates additional buttons.
+//
+// If button is [MouseNone], and motion is false, this returns a release event.
+// If button is undefined, this function returns 0xff.
+func EncodeMouseButton(b MouseButton, motion, shift, alt, ctrl bool) (m byte) {
+ // mouse bit shifts
+ const (
+ bitShift = 0b0000_0100
+ bitAlt = 0b0000_1000
+ bitCtrl = 0b0001_0000
+ bitMotion = 0b0010_0000
+ bitWheel = 0b0100_0000
+ bitAdd = 0b1000_0000 // additional buttons 8-11
+
+ bitsMask = 0b0000_0011
+ )
+
+ if b == MouseNone {
+ m = bitsMask
+ } else if b >= MouseLeft && b <= MouseRight {
+ m = byte(b - MouseLeft)
+ } else if b >= MouseWheelUp && b <= MouseWheelRight {
+ m = byte(b - MouseWheelUp)
+ m |= bitWheel
+ } else if b >= MouseBackward && b <= MouseButton11 {
+ m = byte(b - MouseBackward)
+ m |= bitAdd
+ } else {
+ m = 0xff // invalid button
+ }
+
+ if shift {
+ m |= bitShift
+ }
+ if alt {
+ m |= bitAlt
+ }
+ if ctrl {
+ m |= bitCtrl
+ }
+ if motion {
+ m |= bitMotion
+ }
+
+ return
+}
+
+// x10Offset is the offset for X10 mouse events.
+// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
+const x10Offset = 32
+
+// MouseX10 returns an escape sequence representing a mouse event in X10 mode.
+// Note that this requires the terminal support X10 mouse modes.
+//
+// CSI M Cb Cx Cy
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
+func MouseX10(b byte, x, y int) string {
+ return "\x1b[M" + string(b+x10Offset) + string(byte(x)+x10Offset+1) + string(byte(y)+x10Offset+1)
+}
+
+// MouseSgr returns an escape sequence representing a mouse event in SGR mode.
+//
+// CSI < Cb ; Cx ; Cy M
+// CSI < Cb ; Cx ; Cy m (release)
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
+func MouseSgr(b byte, x, y int, release bool) string {
+ s := 'M'
+ if release {
+ s = 'm'
+ }
+ if x < 0 {
+ x = -x
+ }
+ if y < 0 {
+ y = -y
+ }
+ return fmt.Sprintf("\x1b[<%d;%d;%d%c", b, x+1, y+1, s)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/notification.go b/vendor/github.com/charmbracelet/x/ansi/notification.go
new file mode 100644
index 0000000..c712f34
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/notification.go
@@ -0,0 +1,13 @@
+package ansi
+
+// Notify sends a desktop notification using iTerm's OSC 9.
+//
+// OSC 9 ; Mc ST
+// OSC 9 ; Mc BEL
+//
+// Where Mc is the notification body.
+//
+// See: https://iterm2.com/documentation-escape-codes.html
+func Notify(s string) string {
+ return "\x1b]9;" + s + "\x07"
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/parser.go b/vendor/github.com/charmbracelet/x/ansi/parser.go
new file mode 100644
index 0000000..882e1ed
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/parser.go
@@ -0,0 +1,417 @@
+package ansi
+
+import (
+ "unicode/utf8"
+ "unsafe"
+
+ "github.com/charmbracelet/x/ansi/parser"
+)
+
+// Parser represents a DEC ANSI compatible sequence parser.
+//
+// It uses a state machine to parse ANSI escape sequences and control
+// characters. The parser is designed to be used with a terminal emulator or
+// similar application that needs to parse ANSI escape sequences and control
+// characters.
+// See package [parser] for more information.
+//
+//go:generate go run ./gen.go
+type Parser struct {
+ handler Handler
+
+ // params contains the raw parameters of the sequence.
+ // These parameters used when constructing CSI and DCS sequences.
+ params []int
+
+ // data contains the raw data of the sequence.
+ // These data used when constructing OSC, DCS, SOS, PM, and APC sequences.
+ data []byte
+
+ // dataLen keeps track of the length of the data buffer.
+ // If dataLen is -1, the data buffer is unlimited and will grow as needed.
+ // Otherwise, dataLen is limited by the size of the data buffer.
+ dataLen int
+
+ // paramsLen keeps track of the number of parameters.
+ // This is limited by the size of the params buffer.
+ //
+ // This is also used when collecting UTF-8 runes to keep track of the
+ // number of rune bytes collected.
+ paramsLen int
+
+ // cmd contains the raw command along with the private prefix and
+ // intermediate bytes of the sequence.
+ // The first lower byte contains the command byte, the next byte contains
+ // the private prefix, and the next byte contains the intermediate byte.
+ //
+ // This is also used when collecting UTF-8 runes treating it as a slice of
+ // 4 bytes.
+ cmd int
+
+ // state is the current state of the parser.
+ state byte
+}
+
+// NewParser returns a new parser with the default settings.
+// The [Parser] uses a default size of 32 for the parameters and 64KB for the
+// data buffer. Use [Parser.SetParamsSize] and [Parser.SetDataSize] to set the
+// size of the parameters and data buffer respectively.
+func NewParser() *Parser {
+ p := new(Parser)
+ p.SetParamsSize(parser.MaxParamsSize)
+ p.SetDataSize(1024 * 64) // 64KB data buffer
+ return p
+}
+
+// SetParamsSize sets the size of the parameters buffer.
+// This is used when constructing CSI and DCS sequences.
+func (p *Parser) SetParamsSize(size int) {
+ p.params = make([]int, size)
+}
+
+// SetDataSize sets the size of the data buffer.
+// This is used when constructing OSC, DCS, SOS, PM, and APC sequences.
+// If size is less than or equal to 0, the data buffer is unlimited and will
+// grow as needed.
+func (p *Parser) SetDataSize(size int) {
+ if size <= 0 {
+ size = 0
+ p.dataLen = -1
+ }
+ p.data = make([]byte, size)
+}
+
+// Params returns the list of parsed packed parameters.
+func (p *Parser) Params() Params {
+ return unsafe.Slice((*Param)(unsafe.Pointer(&p.params[0])), p.paramsLen)
+}
+
+// Param returns the parameter at the given index and falls back to the default
+// value if the parameter is missing. If the index is out of bounds, it returns
+// the default value and false.
+func (p *Parser) Param(i, def int) (int, bool) {
+ if i < 0 || i >= p.paramsLen {
+ return def, false
+ }
+ return Param(p.params[i]).Param(def), true
+}
+
+// Command returns the packed command of the last dispatched sequence. Use
+// [Cmd] to unpack the command.
+func (p *Parser) Command() int {
+ return p.cmd
+}
+
+// Rune returns the last dispatched sequence as a rune.
+func (p *Parser) Rune() rune {
+ rw := utf8ByteLen(byte(p.cmd & 0xff))
+ if rw == -1 {
+ return utf8.RuneError
+ }
+ r, _ := utf8.DecodeRune((*[utf8.UTFMax]byte)(unsafe.Pointer(&p.cmd))[:rw])
+ return r
+}
+
+// Control returns the last dispatched sequence as a control code.
+func (p *Parser) Control() byte {
+ return byte(p.cmd & 0xff)
+}
+
+// Data returns the raw data of the last dispatched sequence.
+func (p *Parser) Data() []byte {
+ return p.data[:p.dataLen]
+}
+
+// Reset resets the parser to its initial state.
+func (p *Parser) Reset() {
+ p.clear()
+ p.state = parser.GroundState
+}
+
+// clear clears the parser parameters and command.
+func (p *Parser) clear() {
+ if len(p.params) > 0 {
+ p.params[0] = parser.MissingParam
+ }
+ p.paramsLen = 0
+ p.cmd = 0
+}
+
+// State returns the current state of the parser.
+func (p *Parser) State() parser.State {
+ return p.state
+}
+
+// StateName returns the name of the current state.
+func (p *Parser) StateName() string {
+ return parser.StateNames[p.state]
+}
+
+// Parse parses the given dispatcher and byte buffer.
+// Deprecated: Loop over the buffer and call [Parser.Advance] instead.
+func (p *Parser) Parse(b []byte) {
+ for i := 0; i < len(b); i++ {
+ p.Advance(b[i])
+ }
+}
+
+// Advance advances the parser using the given byte. It returns the action
+// performed by the parser.
+func (p *Parser) Advance(b byte) parser.Action {
+ switch p.state {
+ case parser.Utf8State:
+ // We handle UTF-8 here.
+ return p.advanceUtf8(b)
+ default:
+ return p.advance(b)
+ }
+}
+
+func (p *Parser) collectRune(b byte) {
+ if p.paramsLen >= utf8.UTFMax {
+ return
+ }
+
+ shift := p.paramsLen * 8
+ p.cmd &^= 0xff << shift
+ p.cmd |= int(b) << shift
+ p.paramsLen++
+}
+
+func (p *Parser) advanceUtf8(b byte) parser.Action {
+ // Collect UTF-8 rune bytes.
+ p.collectRune(b)
+ rw := utf8ByteLen(byte(p.cmd & 0xff))
+ if rw == -1 {
+ // We panic here because the first byte comes from the state machine,
+ // if this panics, it means there is a bug in the state machine!
+ panic("invalid rune") // unreachable
+ }
+
+ if p.paramsLen < rw {
+ return parser.CollectAction
+ }
+
+ // We have enough bytes to decode the rune using unsafe
+ if p.handler.Print != nil {
+ p.handler.Print(p.Rune())
+ }
+
+ p.state = parser.GroundState
+ p.paramsLen = 0
+
+ return parser.PrintAction
+}
+
+func (p *Parser) advance(b byte) parser.Action {
+ state, action := parser.Table.Transition(p.state, b)
+
+ // We need to clear the parser state if the state changes from EscapeState.
+ // This is because when we enter the EscapeState, we don't get a chance to
+ // clear the parser state. For example, when a sequence terminates with a
+ // ST (\x1b\\ or \x9c), we dispatch the current sequence and transition to
+ // EscapeState. However, the parser state is not cleared in this case and
+ // we need to clear it here before dispatching the esc sequence.
+ if p.state != state {
+ if p.state == parser.EscapeState {
+ p.performAction(parser.ClearAction, state, b)
+ }
+ if action == parser.PutAction &&
+ p.state == parser.DcsEntryState && state == parser.DcsStringState {
+ // XXX: This is a special case where we need to start collecting
+ // non-string parameterized data i.e. doesn't follow the ECMA-48 §
+ // 5.4.1 string parameters format.
+ p.performAction(parser.StartAction, state, 0)
+ }
+ }
+
+ // Handle special cases
+ switch {
+ case b == ESC && p.state == parser.EscapeState:
+ // Two ESCs in a row
+ p.performAction(parser.ExecuteAction, state, b)
+ default:
+ p.performAction(action, state, b)
+ }
+
+ p.state = state
+
+ return action
+}
+
+func (p *Parser) parseStringCmd() {
+ // Try to parse the command
+ datalen := len(p.data)
+ if p.dataLen >= 0 {
+ datalen = p.dataLen
+ }
+ for i := 0; i < datalen; i++ {
+ d := p.data[i]
+ if d < '0' || d > '9' {
+ break
+ }
+ if p.cmd == parser.MissingCommand {
+ p.cmd = 0
+ }
+ p.cmd *= 10
+ p.cmd += int(d - '0')
+ }
+}
+
+func (p *Parser) performAction(action parser.Action, state parser.State, b byte) {
+ switch action {
+ case parser.IgnoreAction:
+ break
+
+ case parser.ClearAction:
+ p.clear()
+
+ case parser.PrintAction:
+ p.cmd = int(b)
+ if p.handler.Print != nil {
+ p.handler.Print(rune(b))
+ }
+
+ case parser.ExecuteAction:
+ p.cmd = int(b)
+ if p.handler.Execute != nil {
+ p.handler.Execute(b)
+ }
+
+ case parser.PrefixAction:
+ // Collect private prefix
+ // we only store the last prefix
+ p.cmd &^= 0xff << parser.PrefixShift
+ p.cmd |= int(b) << parser.PrefixShift
+
+ case parser.CollectAction:
+ if state == parser.Utf8State {
+ // Reset the UTF-8 counter
+ p.paramsLen = 0
+ p.collectRune(b)
+ } else {
+ // Collect intermediate bytes
+ // we only store the last intermediate byte
+ p.cmd &^= 0xff << parser.IntermedShift
+ p.cmd |= int(b) << parser.IntermedShift
+ }
+
+ case parser.ParamAction:
+ // Collect parameters
+ if p.paramsLen >= len(p.params) {
+ break
+ }
+
+ if b >= '0' && b <= '9' {
+ if p.params[p.paramsLen] == parser.MissingParam {
+ p.params[p.paramsLen] = 0
+ }
+
+ p.params[p.paramsLen] *= 10
+ p.params[p.paramsLen] += int(b - '0')
+ }
+
+ if b == ':' {
+ p.params[p.paramsLen] |= parser.HasMoreFlag
+ }
+
+ if b == ';' || b == ':' {
+ p.paramsLen++
+ if p.paramsLen < len(p.params) {
+ p.params[p.paramsLen] = parser.MissingParam
+ }
+ }
+
+ case parser.StartAction:
+ if p.dataLen < 0 && p.data != nil {
+ p.data = p.data[:0]
+ } else {
+ p.dataLen = 0
+ }
+ if p.state >= parser.DcsEntryState && p.state <= parser.DcsStringState {
+ // Collect the command byte for DCS
+ p.cmd |= int(b)
+ } else {
+ p.cmd = parser.MissingCommand
+ }
+
+ case parser.PutAction:
+ switch p.state {
+ case parser.OscStringState:
+ if b == ';' && p.cmd == parser.MissingCommand {
+ p.parseStringCmd()
+ }
+ }
+
+ if p.dataLen < 0 {
+ p.data = append(p.data, b)
+ } else {
+ if p.dataLen < len(p.data) {
+ p.data[p.dataLen] = b
+ p.dataLen++
+ }
+ }
+
+ case parser.DispatchAction:
+ // Increment the last parameter
+ if p.paramsLen > 0 && p.paramsLen < len(p.params)-1 ||
+ p.paramsLen == 0 && len(p.params) > 0 && p.params[0] != parser.MissingParam {
+ p.paramsLen++
+ }
+
+ if p.state == parser.OscStringState && p.cmd == parser.MissingCommand {
+ // Ensure we have a command for OSC
+ p.parseStringCmd()
+ }
+
+ data := p.data
+ if p.dataLen >= 0 {
+ data = data[:p.dataLen]
+ }
+ switch p.state {
+ case parser.CsiEntryState, parser.CsiParamState, parser.CsiIntermediateState:
+ p.cmd |= int(b)
+ if p.handler.HandleCsi != nil {
+ p.handler.HandleCsi(Cmd(p.cmd), p.Params())
+ }
+ case parser.EscapeState, parser.EscapeIntermediateState:
+ p.cmd |= int(b)
+ if p.handler.HandleEsc != nil {
+ p.handler.HandleEsc(Cmd(p.cmd))
+ }
+ case parser.DcsEntryState, parser.DcsParamState, parser.DcsIntermediateState, parser.DcsStringState:
+ if p.handler.HandleDcs != nil {
+ p.handler.HandleDcs(Cmd(p.cmd), p.Params(), data)
+ }
+ case parser.OscStringState:
+ if p.handler.HandleOsc != nil {
+ p.handler.HandleOsc(p.cmd, data)
+ }
+ case parser.SosStringState:
+ if p.handler.HandleSos != nil {
+ p.handler.HandleSos(data)
+ }
+ case parser.PmStringState:
+ if p.handler.HandlePm != nil {
+ p.handler.HandlePm(data)
+ }
+ case parser.ApcStringState:
+ if p.handler.HandleApc != nil {
+ p.handler.HandleApc(data)
+ }
+ }
+ }
+}
+
+func utf8ByteLen(b byte) int {
+ if b <= 0b0111_1111 { // 0x00-0x7F
+ return 1
+ } else if b >= 0b1100_0000 && b <= 0b1101_1111 { // 0xC0-0xDF
+ return 2
+ } else if b >= 0b1110_0000 && b <= 0b1110_1111 { // 0xE0-0xEF
+ return 3
+ } else if b >= 0b1111_0000 && b <= 0b1111_0111 { // 0xF0-0xF7
+ return 4
+ }
+ return -1
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/parser/const.go b/vendor/github.com/charmbracelet/x/ansi/parser/const.go
new file mode 100644
index 0000000..d62dbf3
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/parser/const.go
@@ -0,0 +1,78 @@
+package parser
+
+// Action is a DEC ANSI parser action.
+type Action = byte
+
+// These are the actions that the parser can take.
+const (
+ NoneAction Action = iota
+ ClearAction
+ CollectAction
+ PrefixAction
+ DispatchAction
+ ExecuteAction
+ StartAction // Start of a data string
+ PutAction // Put into the data string
+ ParamAction
+ PrintAction
+
+ IgnoreAction = NoneAction
+)
+
+// nolint: unused
+var ActionNames = []string{
+ "NoneAction",
+ "ClearAction",
+ "CollectAction",
+ "PrefixAction",
+ "DispatchAction",
+ "ExecuteAction",
+ "StartAction",
+ "PutAction",
+ "ParamAction",
+ "PrintAction",
+}
+
+// State is a DEC ANSI parser state.
+type State = byte
+
+// These are the states that the parser can be in.
+const (
+ GroundState State = iota
+ CsiEntryState
+ CsiIntermediateState
+ CsiParamState
+ DcsEntryState
+ DcsIntermediateState
+ DcsParamState
+ DcsStringState
+ EscapeState
+ EscapeIntermediateState
+ OscStringState
+ SosStringState
+ PmStringState
+ ApcStringState
+
+ // Utf8State is not part of the DEC ANSI standard. It is used to handle
+ // UTF-8 sequences.
+ Utf8State
+)
+
+// nolint: unused
+var StateNames = []string{
+ "GroundState",
+ "CsiEntryState",
+ "CsiIntermediateState",
+ "CsiParamState",
+ "DcsEntryState",
+ "DcsIntermediateState",
+ "DcsParamState",
+ "DcsStringState",
+ "EscapeState",
+ "EscapeIntermediateState",
+ "OscStringState",
+ "SosStringState",
+ "PmStringState",
+ "ApcStringState",
+ "Utf8State",
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/parser/seq.go b/vendor/github.com/charmbracelet/x/ansi/parser/seq.go
new file mode 100644
index 0000000..29f491d
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/parser/seq.go
@@ -0,0 +1,136 @@
+package parser
+
+import "math"
+
+// Shift and masks for sequence parameters and intermediates.
+const (
+ PrefixShift = 8
+ IntermedShift = 16
+ FinalMask = 0xff
+ HasMoreFlag = math.MinInt32
+ ParamMask = ^HasMoreFlag
+ MissingParam = ParamMask
+ MissingCommand = MissingParam
+ MaxParam = math.MaxUint16 // the maximum value a parameter can have
+)
+
+const (
+ // MaxParamsSize is the maximum number of parameters a sequence can have.
+ MaxParamsSize = 32
+
+ // DefaultParamValue is the default value used for missing parameters.
+ DefaultParamValue = 0
+)
+
+// Prefix returns the prefix byte of the sequence.
+// This is always gonna be one of the following '<' '=' '>' '?' and in the
+// range of 0x3C-0x3F.
+// Zero is returned if the sequence does not have a prefix.
+func Prefix(cmd int) int {
+ return (cmd >> PrefixShift) & FinalMask
+}
+
+// Intermediate returns the intermediate byte of the sequence.
+// An intermediate byte is in the range of 0x20-0x2F. This includes these
+// characters from ' ', '!', '"', '#', '$', '%', '&', ”', '(', ')', '*', '+',
+// ',', '-', '.', '/'.
+// Zero is returned if the sequence does not have an intermediate byte.
+func Intermediate(cmd int) int {
+ return (cmd >> IntermedShift) & FinalMask
+}
+
+// Command returns the command byte of the CSI sequence.
+func Command(cmd int) int {
+ return cmd & FinalMask
+}
+
+// Param returns the parameter at the given index.
+// It returns -1 if the parameter does not exist.
+func Param(params []int, i int) int {
+ if len(params) == 0 || i < 0 || i >= len(params) {
+ return -1
+ }
+
+ p := params[i] & ParamMask
+ if p == MissingParam {
+ return -1
+ }
+
+ return p
+}
+
+// HasMore returns true if the parameter has more sub-parameters.
+func HasMore(params []int, i int) bool {
+ if len(params) == 0 || i >= len(params) {
+ return false
+ }
+
+ return params[i]&HasMoreFlag != 0
+}
+
+// Subparams returns the sub-parameters of the given parameter.
+// It returns nil if the parameter does not exist.
+func Subparams(params []int, i int) []int {
+ if len(params) == 0 || i < 0 || i >= len(params) {
+ return nil
+ }
+
+ // Count the number of parameters before the given parameter index.
+ var count int
+ var j int
+ for j = 0; j < len(params); j++ {
+ if count == i {
+ break
+ }
+ if !HasMore(params, j) {
+ count++
+ }
+ }
+
+ if count > i || j >= len(params) {
+ return nil
+ }
+
+ var subs []int
+ for ; j < len(params); j++ {
+ if !HasMore(params, j) {
+ break
+ }
+ p := Param(params, j)
+ if p == -1 {
+ p = DefaultParamValue
+ }
+ subs = append(subs, p)
+ }
+
+ p := Param(params, j)
+ if p == -1 {
+ p = DefaultParamValue
+ }
+
+ return append(subs, p)
+}
+
+// Len returns the number of parameters in the sequence.
+// This will return the number of parameters in the sequence, excluding any
+// sub-parameters.
+func Len(params []int) int {
+ var n int
+ for i := 0; i < len(params); i++ {
+ if !HasMore(params, i) {
+ n++
+ }
+ }
+ return n
+}
+
+// Range iterates over the parameters of the sequence and calls the given
+// function for each parameter.
+// The function should return false to stop the iteration.
+func Range(params []int, fn func(i int, param int, hasMore bool) bool) {
+ for i := 0; i < len(params); i++ {
+ if !fn(i, Param(params, i), HasMore(params, i)) {
+ break
+ }
+ }
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/parser/transition_table.go b/vendor/github.com/charmbracelet/x/ansi/parser/transition_table.go
new file mode 100644
index 0000000..558a5ea
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/parser/transition_table.go
@@ -0,0 +1,273 @@
+package parser
+
+// Table values are generated like this:
+//
+// index: currentState << IndexStateShift | charCode
+// value: action << TransitionActionShift | nextState
+const (
+ TransitionActionShift = 4
+ TransitionStateMask = 15
+ IndexStateShift = 8
+
+ // DefaultTableSize is the default size of the transition table.
+ DefaultTableSize = 4096
+)
+
+// Table is a DEC ANSI transition table.
+var Table = GenerateTransitionTable()
+
+// TransitionTable is a DEC ANSI transition table.
+// https://vt100.net/emu/dec_ansi_parser
+type TransitionTable []byte
+
+// NewTransitionTable returns a new DEC ANSI transition table.
+func NewTransitionTable(size int) TransitionTable {
+ if size <= 0 {
+ size = DefaultTableSize
+ }
+ return TransitionTable(make([]byte, size))
+}
+
+// SetDefault sets default transition.
+func (t TransitionTable) SetDefault(action Action, state State) {
+ for i := 0; i < len(t); i++ {
+ t[i] = action<> TransitionActionShift
+}
+
+// byte range macro
+func r(start, end byte) []byte {
+ var a []byte
+ for i := int(start); i <= int(end); i++ {
+ a = append(a, byte(i))
+ }
+ return a
+}
+
+// GenerateTransitionTable generates a DEC ANSI transition table compatible
+// with the VT500-series of terminals. This implementation includes a few
+// modifications that include:
+// - A new Utf8State is introduced to handle UTF8 sequences.
+// - Osc and Dcs data accept UTF8 sequences by extending the printable range
+// to 0xFF and 0xFE respectively.
+// - We don't ignore 0x3A (':') when building Csi and Dcs parameters and
+// instead use it to denote sub-parameters.
+// - Support dispatching SosPmApc sequences.
+// - The DEL (0x7F) character is executed in the Ground state.
+// - The DEL (0x7F) character is collected in the DcsPassthrough string state.
+// - The ST C1 control character (0x9C) is executed and not ignored.
+func GenerateTransitionTable() TransitionTable {
+ table := NewTransitionTable(DefaultTableSize)
+ table.SetDefault(NoneAction, GroundState)
+
+ // Anywhere
+ for _, state := range r(GroundState, Utf8State) {
+ // Anywhere -> Ground
+ table.AddMany([]byte{0x18, 0x1a, 0x99, 0x9a}, state, ExecuteAction, GroundState)
+ table.AddRange(0x80, 0x8F, state, ExecuteAction, GroundState)
+ table.AddRange(0x90, 0x97, state, ExecuteAction, GroundState)
+ table.AddOne(0x9C, state, ExecuteAction, GroundState)
+ // Anywhere -> Escape
+ table.AddOne(0x1B, state, ClearAction, EscapeState)
+ // Anywhere -> SosStringState
+ table.AddOne(0x98, state, StartAction, SosStringState)
+ // Anywhere -> PmStringState
+ table.AddOne(0x9E, state, StartAction, PmStringState)
+ // Anywhere -> ApcStringState
+ table.AddOne(0x9F, state, StartAction, ApcStringState)
+ // Anywhere -> CsiEntry
+ table.AddOne(0x9B, state, ClearAction, CsiEntryState)
+ // Anywhere -> DcsEntry
+ table.AddOne(0x90, state, ClearAction, DcsEntryState)
+ // Anywhere -> OscString
+ table.AddOne(0x9D, state, StartAction, OscStringState)
+ // Anywhere -> Utf8
+ table.AddRange(0xC2, 0xDF, state, CollectAction, Utf8State) // UTF8 2 byte sequence
+ table.AddRange(0xE0, 0xEF, state, CollectAction, Utf8State) // UTF8 3 byte sequence
+ table.AddRange(0xF0, 0xF4, state, CollectAction, Utf8State) // UTF8 4 byte sequence
+ }
+
+ // Ground
+ table.AddRange(0x00, 0x17, GroundState, ExecuteAction, GroundState)
+ table.AddOne(0x19, GroundState, ExecuteAction, GroundState)
+ table.AddRange(0x1C, 0x1F, GroundState, ExecuteAction, GroundState)
+ table.AddRange(0x20, 0x7E, GroundState, PrintAction, GroundState)
+ table.AddOne(0x7F, GroundState, ExecuteAction, GroundState)
+
+ // EscapeIntermediate
+ table.AddRange(0x00, 0x17, EscapeIntermediateState, ExecuteAction, EscapeIntermediateState)
+ table.AddOne(0x19, EscapeIntermediateState, ExecuteAction, EscapeIntermediateState)
+ table.AddRange(0x1C, 0x1F, EscapeIntermediateState, ExecuteAction, EscapeIntermediateState)
+ table.AddRange(0x20, 0x2F, EscapeIntermediateState, CollectAction, EscapeIntermediateState)
+ table.AddOne(0x7F, EscapeIntermediateState, IgnoreAction, EscapeIntermediateState)
+ // EscapeIntermediate -> Ground
+ table.AddRange(0x30, 0x7E, EscapeIntermediateState, DispatchAction, GroundState)
+
+ // Escape
+ table.AddRange(0x00, 0x17, EscapeState, ExecuteAction, EscapeState)
+ table.AddOne(0x19, EscapeState, ExecuteAction, EscapeState)
+ table.AddRange(0x1C, 0x1F, EscapeState, ExecuteAction, EscapeState)
+ table.AddOne(0x7F, EscapeState, IgnoreAction, EscapeState)
+ // Escape -> Ground
+ table.AddRange(0x30, 0x4F, EscapeState, DispatchAction, GroundState)
+ table.AddRange(0x51, 0x57, EscapeState, DispatchAction, GroundState)
+ table.AddOne(0x59, EscapeState, DispatchAction, GroundState)
+ table.AddOne(0x5A, EscapeState, DispatchAction, GroundState)
+ table.AddOne(0x5C, EscapeState, DispatchAction, GroundState)
+ table.AddRange(0x60, 0x7E, EscapeState, DispatchAction, GroundState)
+ // Escape -> Escape_intermediate
+ table.AddRange(0x20, 0x2F, EscapeState, CollectAction, EscapeIntermediateState)
+ // Escape -> Sos_pm_apc_string
+ table.AddOne('X', EscapeState, StartAction, SosStringState) // SOS
+ table.AddOne('^', EscapeState, StartAction, PmStringState) // PM
+ table.AddOne('_', EscapeState, StartAction, ApcStringState) // APC
+ // Escape -> Dcs_entry
+ table.AddOne('P', EscapeState, ClearAction, DcsEntryState)
+ // Escape -> Csi_entry
+ table.AddOne('[', EscapeState, ClearAction, CsiEntryState)
+ // Escape -> Osc_string
+ table.AddOne(']', EscapeState, StartAction, OscStringState)
+
+ // Sos_pm_apc_string
+ for _, state := range r(SosStringState, ApcStringState) {
+ table.AddRange(0x00, 0x17, state, PutAction, state)
+ table.AddOne(0x19, state, PutAction, state)
+ table.AddRange(0x1C, 0x1F, state, PutAction, state)
+ table.AddRange(0x20, 0x7F, state, PutAction, state)
+ // ESC, ST, CAN, and SUB terminate the sequence
+ table.AddOne(0x1B, state, DispatchAction, EscapeState)
+ table.AddOne(0x9C, state, DispatchAction, GroundState)
+ table.AddMany([]byte{0x18, 0x1A}, state, IgnoreAction, GroundState)
+ }
+
+ // Dcs_entry
+ table.AddRange(0x00, 0x07, DcsEntryState, IgnoreAction, DcsEntryState)
+ table.AddRange(0x0E, 0x17, DcsEntryState, IgnoreAction, DcsEntryState)
+ table.AddOne(0x19, DcsEntryState, IgnoreAction, DcsEntryState)
+ table.AddRange(0x1C, 0x1F, DcsEntryState, IgnoreAction, DcsEntryState)
+ table.AddOne(0x7F, DcsEntryState, IgnoreAction, DcsEntryState)
+ // Dcs_entry -> Dcs_intermediate
+ table.AddRange(0x20, 0x2F, DcsEntryState, CollectAction, DcsIntermediateState)
+ // Dcs_entry -> Dcs_param
+ table.AddRange(0x30, 0x3B, DcsEntryState, ParamAction, DcsParamState)
+ table.AddRange(0x3C, 0x3F, DcsEntryState, PrefixAction, DcsParamState)
+ // Dcs_entry -> Dcs_passthrough
+ table.AddRange(0x08, 0x0D, DcsEntryState, PutAction, DcsStringState) // Follows ECMA-48 § 8.3.27
+ // XXX: allows passing ESC (not a ECMA-48 standard) this to allow for
+ // passthrough of ANSI sequences like in Screen or Tmux passthrough mode.
+ table.AddOne(0x1B, DcsEntryState, PutAction, DcsStringState)
+ table.AddRange(0x40, 0x7E, DcsEntryState, StartAction, DcsStringState)
+
+ // Dcs_intermediate
+ table.AddRange(0x00, 0x17, DcsIntermediateState, IgnoreAction, DcsIntermediateState)
+ table.AddOne(0x19, DcsIntermediateState, IgnoreAction, DcsIntermediateState)
+ table.AddRange(0x1C, 0x1F, DcsIntermediateState, IgnoreAction, DcsIntermediateState)
+ table.AddRange(0x20, 0x2F, DcsIntermediateState, CollectAction, DcsIntermediateState)
+ table.AddOne(0x7F, DcsIntermediateState, IgnoreAction, DcsIntermediateState)
+ // Dcs_intermediate -> Dcs_passthrough
+ table.AddRange(0x30, 0x3F, DcsIntermediateState, StartAction, DcsStringState)
+ table.AddRange(0x40, 0x7E, DcsIntermediateState, StartAction, DcsStringState)
+
+ // Dcs_param
+ table.AddRange(0x00, 0x17, DcsParamState, IgnoreAction, DcsParamState)
+ table.AddOne(0x19, DcsParamState, IgnoreAction, DcsParamState)
+ table.AddRange(0x1C, 0x1F, DcsParamState, IgnoreAction, DcsParamState)
+ table.AddRange(0x30, 0x3B, DcsParamState, ParamAction, DcsParamState)
+ table.AddOne(0x7F, DcsParamState, IgnoreAction, DcsParamState)
+ table.AddRange(0x3C, 0x3F, DcsParamState, IgnoreAction, DcsParamState)
+ // Dcs_param -> Dcs_intermediate
+ table.AddRange(0x20, 0x2F, DcsParamState, CollectAction, DcsIntermediateState)
+ // Dcs_param -> Dcs_passthrough
+ table.AddRange(0x40, 0x7E, DcsParamState, StartAction, DcsStringState)
+
+ // Dcs_passthrough
+ table.AddRange(0x00, 0x17, DcsStringState, PutAction, DcsStringState)
+ table.AddOne(0x19, DcsStringState, PutAction, DcsStringState)
+ table.AddRange(0x1C, 0x1F, DcsStringState, PutAction, DcsStringState)
+ table.AddRange(0x20, 0x7E, DcsStringState, PutAction, DcsStringState)
+ table.AddOne(0x7F, DcsStringState, PutAction, DcsStringState)
+ table.AddRange(0x80, 0xFF, DcsStringState, PutAction, DcsStringState) // Allow Utf8 characters by extending the printable range from 0x7F to 0xFF
+ // ST, CAN, SUB, and ESC terminate the sequence
+ table.AddOne(0x1B, DcsStringState, DispatchAction, EscapeState)
+ table.AddOne(0x9C, DcsStringState, DispatchAction, GroundState)
+ table.AddMany([]byte{0x18, 0x1A}, DcsStringState, IgnoreAction, GroundState)
+
+ // Csi_param
+ table.AddRange(0x00, 0x17, CsiParamState, ExecuteAction, CsiParamState)
+ table.AddOne(0x19, CsiParamState, ExecuteAction, CsiParamState)
+ table.AddRange(0x1C, 0x1F, CsiParamState, ExecuteAction, CsiParamState)
+ table.AddRange(0x30, 0x3B, CsiParamState, ParamAction, CsiParamState)
+ table.AddOne(0x7F, CsiParamState, IgnoreAction, CsiParamState)
+ table.AddRange(0x3C, 0x3F, CsiParamState, IgnoreAction, CsiParamState)
+ // Csi_param -> Ground
+ table.AddRange(0x40, 0x7E, CsiParamState, DispatchAction, GroundState)
+ // Csi_param -> Csi_intermediate
+ table.AddRange(0x20, 0x2F, CsiParamState, CollectAction, CsiIntermediateState)
+
+ // Csi_intermediate
+ table.AddRange(0x00, 0x17, CsiIntermediateState, ExecuteAction, CsiIntermediateState)
+ table.AddOne(0x19, CsiIntermediateState, ExecuteAction, CsiIntermediateState)
+ table.AddRange(0x1C, 0x1F, CsiIntermediateState, ExecuteAction, CsiIntermediateState)
+ table.AddRange(0x20, 0x2F, CsiIntermediateState, CollectAction, CsiIntermediateState)
+ table.AddOne(0x7F, CsiIntermediateState, IgnoreAction, CsiIntermediateState)
+ // Csi_intermediate -> Ground
+ table.AddRange(0x40, 0x7E, CsiIntermediateState, DispatchAction, GroundState)
+ // Csi_intermediate -> Csi_ignore
+ table.AddRange(0x30, 0x3F, CsiIntermediateState, IgnoreAction, GroundState)
+
+ // Csi_entry
+ table.AddRange(0x00, 0x17, CsiEntryState, ExecuteAction, CsiEntryState)
+ table.AddOne(0x19, CsiEntryState, ExecuteAction, CsiEntryState)
+ table.AddRange(0x1C, 0x1F, CsiEntryState, ExecuteAction, CsiEntryState)
+ table.AddOne(0x7F, CsiEntryState, IgnoreAction, CsiEntryState)
+ // Csi_entry -> Ground
+ table.AddRange(0x40, 0x7E, CsiEntryState, DispatchAction, GroundState)
+ // Csi_entry -> Csi_intermediate
+ table.AddRange(0x20, 0x2F, CsiEntryState, CollectAction, CsiIntermediateState)
+ // Csi_entry -> Csi_param
+ table.AddRange(0x30, 0x3B, CsiEntryState, ParamAction, CsiParamState)
+ table.AddRange(0x3C, 0x3F, CsiEntryState, PrefixAction, CsiParamState)
+
+ // Osc_string
+ table.AddRange(0x00, 0x06, OscStringState, IgnoreAction, OscStringState)
+ table.AddRange(0x08, 0x17, OscStringState, IgnoreAction, OscStringState)
+ table.AddOne(0x19, OscStringState, IgnoreAction, OscStringState)
+ table.AddRange(0x1C, 0x1F, OscStringState, IgnoreAction, OscStringState)
+ table.AddRange(0x20, 0xFF, OscStringState, PutAction, OscStringState) // Allow Utf8 characters by extending the printable range from 0x7F to 0xFF
+
+ // ST, CAN, SUB, ESC, and BEL terminate the sequence
+ table.AddOne(0x1B, OscStringState, DispatchAction, EscapeState)
+ table.AddOne(0x07, OscStringState, DispatchAction, GroundState)
+ table.AddOne(0x9C, OscStringState, DispatchAction, GroundState)
+ table.AddMany([]byte{0x18, 0x1A}, OscStringState, IgnoreAction, GroundState)
+
+ return table
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/parser_decode.go b/vendor/github.com/charmbracelet/x/ansi/parser_decode.go
new file mode 100644
index 0000000..3e50473
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/parser_decode.go
@@ -0,0 +1,524 @@
+package ansi
+
+import (
+ "unicode/utf8"
+
+ "github.com/charmbracelet/x/ansi/parser"
+ "github.com/mattn/go-runewidth"
+ "github.com/rivo/uniseg"
+)
+
+// State represents the state of the ANSI escape sequence parser used by
+// [DecodeSequence].
+type State = byte
+
+// ANSI escape sequence states used by [DecodeSequence].
+const (
+ NormalState State = iota
+ PrefixState
+ ParamsState
+ IntermedState
+ EscapeState
+ StringState
+)
+
+// DecodeSequence decodes the first ANSI escape sequence or a printable
+// grapheme from the given data. It returns the sequence slice, the number of
+// bytes read, the cell width for each sequence, and the new state.
+//
+// The cell width will always be 0 for control and escape sequences, 1 for
+// ASCII printable characters, and the number of cells other Unicode characters
+// occupy. It uses the uniseg package to calculate the width of Unicode
+// graphemes and characters. This means it will always do grapheme clustering
+// (mode 2027).
+//
+// Passing a non-nil [*Parser] as the last argument will allow the decoder to
+// collect sequence parameters, data, and commands. The parser cmd will have
+// the packed command value that contains intermediate and prefix characters.
+// In the case of a OSC sequence, the cmd will be the OSC command number. Use
+// [Cmd] and [Param] types to unpack command intermediates and prefixes as well
+// as parameters.
+//
+// Zero [Cmd] means the CSI, DCS, or ESC sequence is invalid. Moreover, checking the
+// validity of other data sequences, OSC, DCS, etc, will require checking for
+// the returned sequence terminator bytes such as ST (ESC \\) and BEL).
+//
+// We store the command byte in [Cmd] in the most significant byte, the
+// prefix byte in the next byte, and the intermediate byte in the least
+// significant byte. This is done to avoid using a struct to store the command
+// and its intermediates and prefixes. The command byte is always the least
+// significant byte i.e. [Cmd & 0xff]. Use the [Cmd] type to unpack the
+// command, intermediate, and prefix bytes. Note that we only collect the last
+// prefix character and intermediate byte.
+//
+// The [p.Params] slice will contain the parameters of the sequence. Any
+// sub-parameter will have the [parser.HasMoreFlag] set. Use the [Param] type
+// to unpack the parameters.
+//
+// Example:
+//
+// var state byte // the initial state is always zero [NormalState]
+// p := NewParser(32, 1024) // create a new parser with a 32 params buffer and 1024 data buffer (optional)
+// input := []byte("\x1b[31mHello, World!\x1b[0m")
+// for len(input) > 0 {
+// seq, width, n, newState := DecodeSequence(input, state, p)
+// log.Printf("seq: %q, width: %d", seq, width)
+// state = newState
+// input = input[n:]
+// }
+//
+// This function treats the text as a sequence of grapheme clusters.
+func DecodeSequence[T string | []byte](b T, state byte, p *Parser) (seq T, width int, n int, newState byte) {
+ return decodeSequence(GraphemeWidth, b, state, p)
+}
+
+// DecodeSequenceWc decodes the first ANSI escape sequence or a printable
+// grapheme from the given data. It returns the sequence slice, the number of
+// bytes read, the cell width for each sequence, and the new state.
+//
+// The cell width will always be 0 for control and escape sequences, 1 for
+// ASCII printable characters, and the number of cells other Unicode characters
+// occupy. It uses the uniseg package to calculate the width of Unicode
+// graphemes and characters. This means it will always do grapheme clustering
+// (mode 2027).
+//
+// Passing a non-nil [*Parser] as the last argument will allow the decoder to
+// collect sequence parameters, data, and commands. The parser cmd will have
+// the packed command value that contains intermediate and prefix characters.
+// In the case of a OSC sequence, the cmd will be the OSC command number. Use
+// [Cmd] and [Param] types to unpack command intermediates and prefixes as well
+// as parameters.
+//
+// Zero [Cmd] means the CSI, DCS, or ESC sequence is invalid. Moreover, checking the
+// validity of other data sequences, OSC, DCS, etc, will require checking for
+// the returned sequence terminator bytes such as ST (ESC \\) and BEL).
+//
+// We store the command byte in [Cmd] in the most significant byte, the
+// prefix byte in the next byte, and the intermediate byte in the least
+// significant byte. This is done to avoid using a struct to store the command
+// and its intermediates and prefixes. The command byte is always the least
+// significant byte i.e. [Cmd & 0xff]. Use the [Cmd] type to unpack the
+// command, intermediate, and prefix bytes. Note that we only collect the last
+// prefix character and intermediate byte.
+//
+// The [p.Params] slice will contain the parameters of the sequence. Any
+// sub-parameter will have the [parser.HasMoreFlag] set. Use the [Param] type
+// to unpack the parameters.
+//
+// Example:
+//
+// var state byte // the initial state is always zero [NormalState]
+// p := NewParser(32, 1024) // create a new parser with a 32 params buffer and 1024 data buffer (optional)
+// input := []byte("\x1b[31mHello, World!\x1b[0m")
+// for len(input) > 0 {
+// seq, width, n, newState := DecodeSequenceWc(input, state, p)
+// log.Printf("seq: %q, width: %d", seq, width)
+// state = newState
+// input = input[n:]
+// }
+//
+// This function treats the text as a sequence of wide characters and runes.
+func DecodeSequenceWc[T string | []byte](b T, state byte, p *Parser) (seq T, width int, n int, newState byte) {
+ return decodeSequence(WcWidth, b, state, p)
+}
+
+func decodeSequence[T string | []byte](m Method, b T, state State, p *Parser) (seq T, width int, n int, newState byte) {
+ for i := 0; i < len(b); i++ {
+ c := b[i]
+
+ switch state {
+ case NormalState:
+ switch c {
+ case ESC:
+ if p != nil {
+ if len(p.params) > 0 {
+ p.params[0] = parser.MissingParam
+ }
+ p.cmd = 0
+ p.paramsLen = 0
+ p.dataLen = 0
+ }
+ state = EscapeState
+ continue
+ case CSI, DCS:
+ if p != nil {
+ if len(p.params) > 0 {
+ p.params[0] = parser.MissingParam
+ }
+ p.cmd = 0
+ p.paramsLen = 0
+ p.dataLen = 0
+ }
+ state = PrefixState
+ continue
+ case OSC, APC, SOS, PM:
+ if p != nil {
+ p.cmd = parser.MissingCommand
+ p.dataLen = 0
+ }
+ state = StringState
+ continue
+ }
+
+ if p != nil {
+ p.dataLen = 0
+ p.paramsLen = 0
+ p.cmd = 0
+ }
+ if c > US && c < DEL {
+ // ASCII printable characters
+ return b[i : i+1], 1, 1, NormalState
+ }
+
+ if c <= US || c == DEL || c < 0xC0 {
+ // C0 & C1 control characters & DEL
+ return b[i : i+1], 0, 1, NormalState
+ }
+
+ if utf8.RuneStart(c) {
+ seq, _, width, _ = FirstGraphemeCluster(b, -1)
+ if m == WcWidth {
+ width = runewidth.StringWidth(string(seq))
+ }
+ i += len(seq)
+ return b[:i], width, i, NormalState
+ }
+
+ // Invalid UTF-8 sequence
+ return b[:i], 0, i, NormalState
+ case PrefixState:
+ if c >= '<' && c <= '?' {
+ if p != nil {
+ // We only collect the last prefix character.
+ p.cmd &^= 0xff << parser.PrefixShift
+ p.cmd |= int(c) << parser.PrefixShift
+ }
+ break
+ }
+
+ state = ParamsState
+ fallthrough
+ case ParamsState:
+ if c >= '0' && c <= '9' {
+ if p != nil {
+ if p.params[p.paramsLen] == parser.MissingParam {
+ p.params[p.paramsLen] = 0
+ }
+
+ p.params[p.paramsLen] *= 10
+ p.params[p.paramsLen] += int(c - '0')
+ }
+ break
+ }
+
+ if c == ':' {
+ if p != nil {
+ p.params[p.paramsLen] |= parser.HasMoreFlag
+ }
+ }
+
+ if c == ';' || c == ':' {
+ if p != nil {
+ p.paramsLen++
+ if p.paramsLen < len(p.params) {
+ p.params[p.paramsLen] = parser.MissingParam
+ }
+ }
+ break
+ }
+
+ state = IntermedState
+ fallthrough
+ case IntermedState:
+ if c >= ' ' && c <= '/' {
+ if p != nil {
+ p.cmd &^= 0xff << parser.IntermedShift
+ p.cmd |= int(c) << parser.IntermedShift
+ }
+ break
+ }
+
+ if p != nil {
+ // Increment the last parameter
+ if p.paramsLen > 0 && p.paramsLen < len(p.params)-1 ||
+ p.paramsLen == 0 && len(p.params) > 0 && p.params[0] != parser.MissingParam {
+ p.paramsLen++
+ }
+ }
+
+ if c >= '@' && c <= '~' {
+ if p != nil {
+ p.cmd &^= 0xff
+ p.cmd |= int(c)
+ }
+
+ if HasDcsPrefix(b) {
+ // Continue to collect DCS data
+ if p != nil {
+ p.dataLen = 0
+ }
+ state = StringState
+ continue
+ }
+
+ return b[:i+1], 0, i + 1, NormalState
+ }
+
+ // Invalid CSI/DCS sequence
+ return b[:i], 0, i, NormalState
+ case EscapeState:
+ switch c {
+ case '[', 'P':
+ if p != nil {
+ if len(p.params) > 0 {
+ p.params[0] = parser.MissingParam
+ }
+ p.paramsLen = 0
+ p.cmd = 0
+ }
+ state = PrefixState
+ continue
+ case ']', 'X', '^', '_':
+ if p != nil {
+ p.cmd = parser.MissingCommand
+ p.dataLen = 0
+ }
+ state = StringState
+ continue
+ }
+
+ if c >= ' ' && c <= '/' {
+ if p != nil {
+ p.cmd &^= 0xff << parser.IntermedShift
+ p.cmd |= int(c) << parser.IntermedShift
+ }
+ continue
+ } else if c >= '0' && c <= '~' {
+ if p != nil {
+ p.cmd &^= 0xff
+ p.cmd |= int(c)
+ }
+ return b[:i+1], 0, i + 1, NormalState
+ }
+
+ // Invalid escape sequence
+ return b[:i], 0, i, NormalState
+ case StringState:
+ switch c {
+ case BEL:
+ if HasOscPrefix(b) {
+ parseOscCmd(p)
+ return b[:i+1], 0, i + 1, NormalState
+ }
+ case CAN, SUB:
+ if HasOscPrefix(b) {
+ // Ensure we parse the OSC command number
+ parseOscCmd(p)
+ }
+
+ // Cancel the sequence
+ return b[:i], 0, i, NormalState
+ case ST:
+ if HasOscPrefix(b) {
+ // Ensure we parse the OSC command number
+ parseOscCmd(p)
+ }
+
+ return b[:i+1], 0, i + 1, NormalState
+ case ESC:
+ if HasStPrefix(b[i:]) {
+ if HasOscPrefix(b) {
+ // Ensure we parse the OSC command number
+ parseOscCmd(p)
+ }
+
+ // End of string 7-bit (ST)
+ return b[:i+2], 0, i + 2, NormalState
+ }
+
+ // Otherwise, cancel the sequence
+ return b[:i], 0, i, NormalState
+ }
+
+ if p != nil && p.dataLen < len(p.data) {
+ p.data[p.dataLen] = c
+ p.dataLen++
+
+ // Parse the OSC command number
+ if c == ';' && HasOscPrefix(b) {
+ parseOscCmd(p)
+ }
+ }
+ }
+ }
+
+ return b, 0, len(b), state
+}
+
+func parseOscCmd(p *Parser) {
+ if p == nil || p.cmd != parser.MissingCommand {
+ return
+ }
+ for j := 0; j < p.dataLen; j++ {
+ d := p.data[j]
+ if d < '0' || d > '9' {
+ break
+ }
+ if p.cmd == parser.MissingCommand {
+ p.cmd = 0
+ }
+ p.cmd *= 10
+ p.cmd += int(d - '0')
+ }
+}
+
+// Equal returns true if the given byte slices are equal.
+func Equal[T string | []byte](a, b T) bool {
+ return string(a) == string(b)
+}
+
+// HasPrefix returns true if the given byte slice has prefix.
+func HasPrefix[T string | []byte](b, prefix T) bool {
+ return len(b) >= len(prefix) && Equal(b[0:len(prefix)], prefix)
+}
+
+// HasSuffix returns true if the given byte slice has suffix.
+func HasSuffix[T string | []byte](b, suffix T) bool {
+ return len(b) >= len(suffix) && Equal(b[len(b)-len(suffix):], suffix)
+}
+
+// HasCsiPrefix returns true if the given byte slice has a CSI prefix.
+func HasCsiPrefix[T string | []byte](b T) bool {
+ return (len(b) > 0 && b[0] == CSI) ||
+ (len(b) > 1 && b[0] == ESC && b[1] == '[')
+}
+
+// HasOscPrefix returns true if the given byte slice has an OSC prefix.
+func HasOscPrefix[T string | []byte](b T) bool {
+ return (len(b) > 0 && b[0] == OSC) ||
+ (len(b) > 1 && b[0] == ESC && b[1] == ']')
+}
+
+// HasApcPrefix returns true if the given byte slice has an APC prefix.
+func HasApcPrefix[T string | []byte](b T) bool {
+ return (len(b) > 0 && b[0] == APC) ||
+ (len(b) > 1 && b[0] == ESC && b[1] == '_')
+}
+
+// HasDcsPrefix returns true if the given byte slice has a DCS prefix.
+func HasDcsPrefix[T string | []byte](b T) bool {
+ return (len(b) > 0 && b[0] == DCS) ||
+ (len(b) > 1 && b[0] == ESC && b[1] == 'P')
+}
+
+// HasSosPrefix returns true if the given byte slice has a SOS prefix.
+func HasSosPrefix[T string | []byte](b T) bool {
+ return (len(b) > 0 && b[0] == SOS) ||
+ (len(b) > 1 && b[0] == ESC && b[1] == 'X')
+}
+
+// HasPmPrefix returns true if the given byte slice has a PM prefix.
+func HasPmPrefix[T string | []byte](b T) bool {
+ return (len(b) > 0 && b[0] == PM) ||
+ (len(b) > 1 && b[0] == ESC && b[1] == '^')
+}
+
+// HasStPrefix returns true if the given byte slice has a ST prefix.
+func HasStPrefix[T string | []byte](b T) bool {
+ return (len(b) > 0 && b[0] == ST) ||
+ (len(b) > 1 && b[0] == ESC && b[1] == '\\')
+}
+
+// HasEscPrefix returns true if the given byte slice has an ESC prefix.
+func HasEscPrefix[T string | []byte](b T) bool {
+ return len(b) > 0 && b[0] == ESC
+}
+
+// FirstGraphemeCluster returns the first grapheme cluster in the given string or byte slice.
+// This is a syntactic sugar function that wraps
+// uniseg.FirstGraphemeClusterInString and uniseg.FirstGraphemeCluster.
+func FirstGraphemeCluster[T string | []byte](b T, state int) (T, T, int, int) {
+ switch b := any(b).(type) {
+ case string:
+ cluster, rest, width, newState := uniseg.FirstGraphemeClusterInString(b, state)
+ return T(cluster), T(rest), width, newState
+ case []byte:
+ cluster, rest, width, newState := uniseg.FirstGraphemeCluster(b, state)
+ return T(cluster), T(rest), width, newState
+ }
+ panic("unreachable")
+}
+
+// Cmd represents a sequence command. This is used to pack/unpack a sequence
+// command with its intermediate and prefix characters. Those are commonly
+// found in CSI and DCS sequences.
+type Cmd int
+
+// Prefix returns the unpacked prefix byte of the CSI sequence.
+// This is always gonna be one of the following '<' '=' '>' '?' and in the
+// range of 0x3C-0x3F.
+// Zero is returned if the sequence does not have a prefix.
+func (c Cmd) Prefix() byte {
+ return byte(parser.Prefix(int(c)))
+}
+
+// Intermediate returns the unpacked intermediate byte of the CSI sequence.
+// An intermediate byte is in the range of 0x20-0x2F. This includes these
+// characters from ' ', '!', '"', '#', '$', '%', '&', ”', '(', ')', '*', '+',
+// ',', '-', '.', '/'.
+// Zero is returned if the sequence does not have an intermediate byte.
+func (c Cmd) Intermediate() byte {
+ return byte(parser.Intermediate(int(c)))
+}
+
+// Final returns the unpacked command byte of the CSI sequence.
+func (c Cmd) Final() byte {
+ return byte(parser.Command(int(c)))
+}
+
+// Command packs a command with the given prefix, intermediate, and final. A
+// zero byte means the sequence does not have a prefix or intermediate.
+//
+// Prefixes are in the range of 0x3C-0x3F that is one of `<=>?`.
+//
+// Intermediates are in the range of 0x20-0x2F that is anything in
+// `!"#$%&'()*+,-./`.
+//
+// Final bytes are in the range of 0x40-0x7E that is anything in the range
+// `@A–Z[\]^_`a–z{|}~`.
+func Command(prefix, inter, final byte) (c int) {
+ c = int(final)
+ c |= int(prefix) << parser.PrefixShift
+ c |= int(inter) << parser.IntermedShift
+ return
+}
+
+// Param represents a sequence parameter. Sequence parameters with
+// sub-parameters are packed with the HasMoreFlag set. This is used to unpack
+// the parameters from a CSI and DCS sequences.
+type Param int
+
+// Param returns the unpacked parameter at the given index.
+// It returns the default value if the parameter is missing.
+func (s Param) Param(def int) int {
+ p := int(s) & parser.ParamMask
+ if p == parser.MissingParam {
+ return def
+ }
+ return p
+}
+
+// HasMore unpacks the HasMoreFlag from the parameter.
+func (s Param) HasMore() bool {
+ return s&parser.HasMoreFlag != 0
+}
+
+// Parameter packs an escape code parameter with the given parameter and
+// whether this parameter has following sub-parameters.
+func Parameter(p int, hasMore bool) (s int) {
+ s = p & parser.ParamMask
+ if hasMore {
+ s |= parser.HasMoreFlag
+ }
+ return
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/parser_handler.go b/vendor/github.com/charmbracelet/x/ansi/parser_handler.go
new file mode 100644
index 0000000..03f9ed4
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/parser_handler.go
@@ -0,0 +1,60 @@
+package ansi
+
+import "unsafe"
+
+// Params represents a list of packed parameters.
+type Params []Param
+
+// Param returns the parameter at the given index and if it is part of a
+// sub-parameters. It falls back to the default value if the parameter is
+// missing. If the index is out of bounds, it returns the default value and
+// false.
+func (p Params) Param(i, def int) (int, bool, bool) {
+ if i < 0 || i >= len(p) {
+ return def, false, false
+ }
+ return p[i].Param(def), p[i].HasMore(), true
+}
+
+// ForEach iterates over the parameters and calls the given function for each
+// parameter. If a parameter is part of a sub-parameter, it will be called with
+// hasMore set to true.
+// Use def to set a default value for missing parameters.
+func (p Params) ForEach(def int, f func(i, param int, hasMore bool)) {
+ for i := range p {
+ f(i, p[i].Param(def), p[i].HasMore())
+ }
+}
+
+// ToParams converts a list of integers to a list of parameters.
+func ToParams(params []int) Params {
+ return unsafe.Slice((*Param)(unsafe.Pointer(¶ms[0])), len(params))
+}
+
+// Handler handles actions performed by the parser.
+// It is used to handle ANSI escape sequences, control characters, and runes.
+type Handler struct {
+ // Print is called when a printable rune is encountered.
+ Print func(r rune)
+ // Execute is called when a control character is encountered.
+ Execute func(b byte)
+ // HandleCsi is called when a CSI sequence is encountered.
+ HandleCsi func(cmd Cmd, params Params)
+ // HandleEsc is called when an ESC sequence is encountered.
+ HandleEsc func(cmd Cmd)
+ // HandleDcs is called when a DCS sequence is encountered.
+ HandleDcs func(cmd Cmd, params Params, data []byte)
+ // HandleOsc is called when an OSC sequence is encountered.
+ HandleOsc func(cmd int, data []byte)
+ // HandlePm is called when a PM sequence is encountered.
+ HandlePm func(data []byte)
+ // HandleApc is called when an APC sequence is encountered.
+ HandleApc func(data []byte)
+ // HandleSos is called when a SOS sequence is encountered.
+ HandleSos func(data []byte)
+}
+
+// SetHandler sets the handler for the parser.
+func (p *Parser) SetHandler(h Handler) {
+ p.handler = h
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/parser_sync.go b/vendor/github.com/charmbracelet/x/ansi/parser_sync.go
new file mode 100644
index 0000000..65d25a9
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/parser_sync.go
@@ -0,0 +1,29 @@
+package ansi
+
+import (
+ "sync"
+
+ "github.com/charmbracelet/x/ansi/parser"
+)
+
+var parserPool = sync.Pool{
+ New: func() any {
+ p := NewParser()
+ p.SetParamsSize(parser.MaxParamsSize)
+ p.SetDataSize(1024 * 1024 * 4) // 4MB of data buffer
+ return p
+ },
+}
+
+// GetParser returns a parser from a sync pool.
+func GetParser() *Parser {
+ return parserPool.Get().(*Parser)
+}
+
+// PutParser returns a parser to a sync pool. The parser is reset
+// automatically.
+func PutParser(p *Parser) {
+ p.Reset()
+ p.dataLen = 0
+ parserPool.Put(p)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/passthrough.go b/vendor/github.com/charmbracelet/x/ansi/passthrough.go
new file mode 100644
index 0000000..14a7452
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/passthrough.go
@@ -0,0 +1,63 @@
+package ansi
+
+import (
+ "bytes"
+)
+
+// ScreenPassthrough wraps the given ANSI sequence in a DCS passthrough
+// sequence to be sent to the outer terminal. This is used to send raw escape
+// sequences to the outer terminal when running inside GNU Screen.
+//
+// DCS ST
+//
+// Note: Screen limits the length of string sequences to 768 bytes (since 2014).
+// Use zero to indicate no limit, otherwise, this will chunk the returned
+// string into limit sized chunks.
+//
+// See: https://www.gnu.org/software/screen/manual/screen.html#String-Escapes
+// See: https://git.savannah.gnu.org/cgit/screen.git/tree/src/screen.h?id=c184c6ec27683ff1a860c45be5cf520d896fd2ef#n44
+func ScreenPassthrough(seq string, limit int) string {
+ var b bytes.Buffer
+ b.WriteString("\x1bP")
+ if limit > 0 {
+ for i := 0; i < len(seq); i += limit {
+ end := i + limit
+ if end > len(seq) {
+ end = len(seq)
+ }
+ b.WriteString(seq[i:end])
+ if end < len(seq) {
+ b.WriteString("\x1b\\\x1bP")
+ }
+ }
+ } else {
+ b.WriteString(seq)
+ }
+ b.WriteString("\x1b\\")
+ return b.String()
+}
+
+// TmuxPassthrough wraps the given ANSI sequence in a special DCS passthrough
+// sequence to be sent to the outer terminal. This is used to send raw escape
+// sequences to the outer terminal when running inside Tmux.
+//
+// DCS tmux ; ST
+//
+// Where is the given sequence in which all occurrences of ESC
+// (0x1b) are doubled i.e. replaced with ESC ESC (0x1b 0x1b).
+//
+// Note: this needs the `allow-passthrough` option to be set to `on`.
+//
+// See: https://github.com/tmux/tmux/wiki/FAQ#what-is-the-passthrough-escape-sequence-and-how-do-i-use-it
+func TmuxPassthrough(seq string) string {
+ var b bytes.Buffer
+ b.WriteString("\x1bPtmux;")
+ for i := 0; i < len(seq); i++ {
+ if seq[i] == ESC {
+ b.WriteByte(ESC)
+ }
+ b.WriteByte(seq[i])
+ }
+ b.WriteString("\x1b\\")
+ return b.String()
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/paste.go b/vendor/github.com/charmbracelet/x/ansi/paste.go
new file mode 100644
index 0000000..2f9ea6f
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/paste.go
@@ -0,0 +1,7 @@
+package ansi
+
+// BracketedPasteStart is the control sequence to enable bracketed paste mode.
+const BracketedPasteStart = "\x1b[200~"
+
+// BracketedPasteEnd is the control sequence to disable bracketed paste mode.
+const BracketedPasteEnd = "\x1b[201~"
diff --git a/vendor/github.com/charmbracelet/x/ansi/reset.go b/vendor/github.com/charmbracelet/x/ansi/reset.go
new file mode 100644
index 0000000..c1b89ea
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/reset.go
@@ -0,0 +1,11 @@
+package ansi
+
+// ResetInitialState (RIS) resets the terminal to its initial state.
+//
+// ESC c
+//
+// See: https://vt100.net/docs/vt510-rm/RIS.html
+const (
+ ResetInitialState = "\x1bc"
+ RIS = ResetInitialState
+)
diff --git a/vendor/github.com/charmbracelet/x/ansi/screen.go b/vendor/github.com/charmbracelet/x/ansi/screen.go
new file mode 100644
index 0000000..c76e4f0
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/screen.go
@@ -0,0 +1,410 @@
+package ansi
+
+import (
+ "strconv"
+ "strings"
+)
+
+// EraseDisplay (ED) clears the display or parts of the display. A screen is
+// the shown part of the terminal display excluding the scrollback buffer.
+// Possible values:
+//
+// Default is 0.
+//
+// 0: Clear from cursor to end of screen.
+// 1: Clear from cursor to beginning of the screen.
+// 2: Clear entire screen (and moves cursor to upper left on DOS).
+// 3: Clear entire display which delete all lines saved in the scrollback buffer (xterm).
+//
+// CSI J
+//
+// See: https://vt100.net/docs/vt510-rm/ED.html
+func EraseDisplay(n int) string {
+ var s string
+ if n > 0 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "J"
+}
+
+// ED is an alias for [EraseDisplay].
+func ED(n int) string {
+ return EraseDisplay(n)
+}
+
+// EraseDisplay constants.
+// These are the possible values for the EraseDisplay function.
+const (
+ EraseScreenBelow = "\x1b[J"
+ EraseScreenAbove = "\x1b[1J"
+ EraseEntireScreen = "\x1b[2J"
+ EraseEntireDisplay = "\x1b[3J"
+)
+
+// EraseLine (EL) clears the current line or parts of the line. Possible values:
+//
+// 0: Clear from cursor to end of line.
+// 1: Clear from cursor to beginning of the line.
+// 2: Clear entire line.
+//
+// The cursor position is not affected.
+//
+// CSI K
+//
+// See: https://vt100.net/docs/vt510-rm/EL.html
+func EraseLine(n int) string {
+ var s string
+ if n > 0 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "K"
+}
+
+// EL is an alias for [EraseLine].
+func EL(n int) string {
+ return EraseLine(n)
+}
+
+// EraseLine constants.
+// These are the possible values for the EraseLine function.
+const (
+ EraseLineRight = "\x1b[K"
+ EraseLineLeft = "\x1b[1K"
+ EraseEntireLine = "\x1b[2K"
+)
+
+// ScrollUp (SU) scrolls the screen up n lines. New lines are added at the
+// bottom of the screen.
+//
+// CSI Pn S
+//
+// See: https://vt100.net/docs/vt510-rm/SU.html
+func ScrollUp(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "S"
+}
+
+// PanDown is an alias for [ScrollUp].
+func PanDown(n int) string {
+ return ScrollUp(n)
+}
+
+// SU is an alias for [ScrollUp].
+func SU(n int) string {
+ return ScrollUp(n)
+}
+
+// ScrollDown (SD) scrolls the screen down n lines. New lines are added at the
+// top of the screen.
+//
+// CSI Pn T
+//
+// See: https://vt100.net/docs/vt510-rm/SD.html
+func ScrollDown(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "T"
+}
+
+// PanUp is an alias for [ScrollDown].
+func PanUp(n int) string {
+ return ScrollDown(n)
+}
+
+// SD is an alias for [ScrollDown].
+func SD(n int) string {
+ return ScrollDown(n)
+}
+
+// InsertLine (IL) inserts n blank lines at the current cursor position.
+// Existing lines are moved down.
+//
+// CSI Pn L
+//
+// See: https://vt100.net/docs/vt510-rm/IL.html
+func InsertLine(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "L"
+}
+
+// IL is an alias for [InsertLine].
+func IL(n int) string {
+ return InsertLine(n)
+}
+
+// DeleteLine (DL) deletes n lines at the current cursor position. Existing
+// lines are moved up.
+//
+// CSI Pn M
+//
+// See: https://vt100.net/docs/vt510-rm/DL.html
+func DeleteLine(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "M"
+}
+
+// DL is an alias for [DeleteLine].
+func DL(n int) string {
+ return DeleteLine(n)
+}
+
+// SetTopBottomMargins (DECSTBM) sets the top and bottom margins for the scrolling
+// region. The default is the entire screen.
+//
+// Default is 1 and the bottom of the screen.
+//
+// CSI Pt ; Pb r
+//
+// See: https://vt100.net/docs/vt510-rm/DECSTBM.html
+func SetTopBottomMargins(top, bot int) string {
+ var t, b string
+ if top > 0 {
+ t = strconv.Itoa(top)
+ }
+ if bot > 0 {
+ b = strconv.Itoa(bot)
+ }
+ return "\x1b[" + t + ";" + b + "r"
+}
+
+// DECSTBM is an alias for [SetTopBottomMargins].
+func DECSTBM(top, bot int) string {
+ return SetTopBottomMargins(top, bot)
+}
+
+// SetLeftRightMargins (DECSLRM) sets the left and right margins for the scrolling
+// region.
+//
+// Default is 1 and the right of the screen.
+//
+// CSI Pl ; Pr s
+//
+// See: https://vt100.net/docs/vt510-rm/DECSLRM.html
+func SetLeftRightMargins(left, right int) string {
+ var l, r string
+ if left > 0 {
+ l = strconv.Itoa(left)
+ }
+ if right > 0 {
+ r = strconv.Itoa(right)
+ }
+ return "\x1b[" + l + ";" + r + "s"
+}
+
+// DECSLRM is an alias for [SetLeftRightMargins].
+func DECSLRM(left, right int) string {
+ return SetLeftRightMargins(left, right)
+}
+
+// SetScrollingRegion (DECSTBM) sets the top and bottom margins for the scrolling
+// region. The default is the entire screen.
+//
+// CSI ; r
+//
+// See: https://vt100.net/docs/vt510-rm/DECSTBM.html
+//
+// Deprecated: use [SetTopBottomMargins] instead.
+func SetScrollingRegion(t, b int) string {
+ if t < 0 {
+ t = 0
+ }
+ if b < 0 {
+ b = 0
+ }
+ return "\x1b[" + strconv.Itoa(t) + ";" + strconv.Itoa(b) + "r"
+}
+
+// InsertCharacter (ICH) inserts n blank characters at the current cursor
+// position. Existing characters move to the right. Characters moved past the
+// right margin are lost. ICH has no effect outside the scrolling margins.
+//
+// Default is 1.
+//
+// CSI Pn @
+//
+// See: https://vt100.net/docs/vt510-rm/ICH.html
+func InsertCharacter(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "@"
+}
+
+// ICH is an alias for [InsertCharacter].
+func ICH(n int) string {
+ return InsertCharacter(n)
+}
+
+// DeleteCharacter (DCH) deletes n characters at the current cursor position.
+// As the characters are deleted, the remaining characters move to the left and
+// the cursor remains at the same position.
+//
+// Default is 1.
+//
+// CSI Pn P
+//
+// See: https://vt100.net/docs/vt510-rm/DCH.html
+func DeleteCharacter(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "P"
+}
+
+// DCH is an alias for [DeleteCharacter].
+func DCH(n int) string {
+ return DeleteCharacter(n)
+}
+
+// SetTabEvery8Columns (DECST8C) sets the tab stops at every 8 columns.
+//
+// CSI ? 5 W
+//
+// See: https://vt100.net/docs/vt510-rm/DECST8C.html
+const (
+ SetTabEvery8Columns = "\x1b[?5W"
+ DECST8C = SetTabEvery8Columns
+)
+
+// HorizontalTabSet (HTS) sets a horizontal tab stop at the current cursor
+// column.
+//
+// This is equivalent to [HTS].
+//
+// ESC H
+//
+// See: https://vt100.net/docs/vt510-rm/HTS.html
+const HorizontalTabSet = "\x1bH"
+
+// TabClear (TBC) clears tab stops.
+//
+// Default is 0.
+//
+// Possible values:
+// 0: Clear tab stop at the current column. (default)
+// 3: Clear all tab stops.
+//
+// CSI Pn g
+//
+// See: https://vt100.net/docs/vt510-rm/TBC.html
+func TabClear(n int) string {
+ var s string
+ if n > 0 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "g"
+}
+
+// TBC is an alias for [TabClear].
+func TBC(n int) string {
+ return TabClear(n)
+}
+
+// RequestPresentationStateReport (DECRQPSR) requests the terminal to send a
+// report of the presentation state. This includes the cursor information [DECCIR],
+// and tab stop [DECTABSR] reports.
+//
+// Default is 0.
+//
+// Possible values:
+// 0: Error, request ignored.
+// 1: Cursor information report [DECCIR].
+// 2: Tab stop report [DECTABSR].
+//
+// CSI Ps $ w
+//
+// See: https://vt100.net/docs/vt510-rm/DECRQPSR.html
+func RequestPresentationStateReport(n int) string {
+ var s string
+ if n > 0 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "$w"
+}
+
+// DECRQPSR is an alias for [RequestPresentationStateReport].
+func DECRQPSR(n int) string {
+ return RequestPresentationStateReport(n)
+}
+
+// TabStopReport (DECTABSR) is the response to a tab stop report request.
+// It reports the tab stops set in the terminal.
+//
+// The response is a list of tab stops separated by a slash (/) character.
+//
+// DCS 2 $ u D ... D ST
+//
+// Where D is a decimal number representing a tab stop.
+//
+// See: https://vt100.net/docs/vt510-rm/DECTABSR.html
+func TabStopReport(stops ...int) string {
+ var s []string
+ for _, v := range stops {
+ s = append(s, strconv.Itoa(v))
+ }
+ return "\x1bP2$u" + strings.Join(s, "/") + "\x1b\\"
+}
+
+// DECTABSR is an alias for [TabStopReport].
+func DECTABSR(stops ...int) string {
+ return TabStopReport(stops...)
+}
+
+// CursorInformationReport (DECCIR) is the response to a cursor information
+// report request. It reports the cursor position, visual attributes, and
+// character protection attributes. It also reports the status of origin mode
+// [DECOM] and the current active character set.
+//
+// The response is a list of values separated by a semicolon (;) character.
+//
+// DCS 1 $ u D ... D ST
+//
+// Where D is a decimal number representing a value.
+//
+// See: https://vt100.net/docs/vt510-rm/DECCIR.html
+func CursorInformationReport(values ...int) string {
+ var s []string
+ for _, v := range values {
+ s = append(s, strconv.Itoa(v))
+ }
+ return "\x1bP1$u" + strings.Join(s, ";") + "\x1b\\"
+}
+
+// DECCIR is an alias for [CursorInformationReport].
+func DECCIR(values ...int) string {
+ return CursorInformationReport(values...)
+}
+
+// RepeatPreviousCharacter (REP) repeats the previous character n times.
+// This is identical to typing the same character n times.
+//
+// Default is 1.
+//
+// CSI Pn b
+//
+// See: ECMA-48 § 8.3.103
+func RepeatPreviousCharacter(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "b"
+}
+
+// REP is an alias for [RepeatPreviousCharacter].
+func REP(n int) string {
+ return RepeatPreviousCharacter(n)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/sgr.go b/vendor/github.com/charmbracelet/x/ansi/sgr.go
new file mode 100644
index 0000000..1a18c98
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/sgr.go
@@ -0,0 +1,95 @@
+package ansi
+
+import "strconv"
+
+// Select Graphic Rendition (SGR) is a command that sets display attributes.
+//
+// Default is 0.
+//
+// CSI Ps ; Ps ... m
+//
+// See: https://vt100.net/docs/vt510-rm/SGR.html
+func SelectGraphicRendition(ps ...Attr) string {
+ if len(ps) == 0 {
+ return ResetStyle
+ }
+
+ var s Style
+ for _, p := range ps {
+ attr, ok := attrStrings[p]
+ if ok {
+ s = append(s, attr)
+ } else {
+ if p < 0 {
+ p = 0
+ }
+ s = append(s, strconv.Itoa(p))
+ }
+ }
+
+ return s.String()
+}
+
+// SGR is an alias for [SelectGraphicRendition].
+func SGR(ps ...Attr) string {
+ return SelectGraphicRendition(ps...)
+}
+
+var attrStrings = map[int]string{
+ ResetAttr: "0",
+ BoldAttr: "1",
+ FaintAttr: "2",
+ ItalicAttr: "3",
+ UnderlineAttr: "4",
+ SlowBlinkAttr: "5",
+ RapidBlinkAttr: "6",
+ ReverseAttr: "7",
+ ConcealAttr: "8",
+ StrikethroughAttr: "9",
+ NoBoldAttr: "21",
+ NormalIntensityAttr: "22",
+ NoItalicAttr: "23",
+ NoUnderlineAttr: "24",
+ NoBlinkAttr: "25",
+ NoReverseAttr: "27",
+ NoConcealAttr: "28",
+ NoStrikethroughAttr: "29",
+ BlackForegroundColorAttr: "30",
+ RedForegroundColorAttr: "31",
+ GreenForegroundColorAttr: "32",
+ YellowForegroundColorAttr: "33",
+ BlueForegroundColorAttr: "34",
+ MagentaForegroundColorAttr: "35",
+ CyanForegroundColorAttr: "36",
+ WhiteForegroundColorAttr: "37",
+ ExtendedForegroundColorAttr: "38",
+ DefaultForegroundColorAttr: "39",
+ BlackBackgroundColorAttr: "40",
+ RedBackgroundColorAttr: "41",
+ GreenBackgroundColorAttr: "42",
+ YellowBackgroundColorAttr: "43",
+ BlueBackgroundColorAttr: "44",
+ MagentaBackgroundColorAttr: "45",
+ CyanBackgroundColorAttr: "46",
+ WhiteBackgroundColorAttr: "47",
+ ExtendedBackgroundColorAttr: "48",
+ DefaultBackgroundColorAttr: "49",
+ ExtendedUnderlineColorAttr: "58",
+ DefaultUnderlineColorAttr: "59",
+ BrightBlackForegroundColorAttr: "90",
+ BrightRedForegroundColorAttr: "91",
+ BrightGreenForegroundColorAttr: "92",
+ BrightYellowForegroundColorAttr: "93",
+ BrightBlueForegroundColorAttr: "94",
+ BrightMagentaForegroundColorAttr: "95",
+ BrightCyanForegroundColorAttr: "96",
+ BrightWhiteForegroundColorAttr: "97",
+ BrightBlackBackgroundColorAttr: "100",
+ BrightRedBackgroundColorAttr: "101",
+ BrightGreenBackgroundColorAttr: "102",
+ BrightYellowBackgroundColorAttr: "103",
+ BrightBlueBackgroundColorAttr: "104",
+ BrightMagentaBackgroundColorAttr: "105",
+ BrightCyanBackgroundColorAttr: "106",
+ BrightWhiteBackgroundColorAttr: "107",
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/status.go b/vendor/github.com/charmbracelet/x/ansi/status.go
new file mode 100644
index 0000000..4337e18
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/status.go
@@ -0,0 +1,144 @@
+package ansi
+
+import (
+ "strconv"
+ "strings"
+)
+
+// StatusReport represents a terminal status report.
+type StatusReport interface {
+ // StatusReport returns the status report identifier.
+ StatusReport() int
+}
+
+// ANSIReport represents an ANSI terminal status report.
+type ANSIStatusReport int //nolint:revive
+
+// Report returns the status report identifier.
+func (s ANSIStatusReport) StatusReport() int {
+ return int(s)
+}
+
+// DECStatusReport represents a DEC terminal status report.
+type DECStatusReport int
+
+// Status returns the status report identifier.
+func (s DECStatusReport) StatusReport() int {
+ return int(s)
+}
+
+// DeviceStatusReport (DSR) is a control sequence that reports the terminal's
+// status.
+// The terminal responds with a DSR sequence.
+//
+// CSI Ps n
+// CSI ? Ps n
+//
+// If one of the statuses is a [DECStatus], the sequence will use the DEC
+// format.
+//
+// See also https://vt100.net/docs/vt510-rm/DSR.html
+func DeviceStatusReport(statues ...StatusReport) string {
+ var dec bool
+ list := make([]string, len(statues))
+ seq := "\x1b["
+ for i, status := range statues {
+ list[i] = strconv.Itoa(status.StatusReport())
+ switch status.(type) {
+ case DECStatusReport:
+ dec = true
+ }
+ }
+ if dec {
+ seq += "?"
+ }
+ return seq + strings.Join(list, ";") + "n"
+}
+
+// DSR is an alias for [DeviceStatusReport].
+func DSR(status StatusReport) string {
+ return DeviceStatusReport(status)
+}
+
+// RequestCursorPositionReport is an escape sequence that requests the current
+// cursor position.
+//
+// CSI 6 n
+//
+// The terminal will report the cursor position as a CSI sequence in the
+// following format:
+//
+// CSI Pl ; Pc R
+//
+// Where Pl is the line number and Pc is the column number.
+// See: https://vt100.net/docs/vt510-rm/CPR.html
+const RequestCursorPositionReport = "\x1b[6n"
+
+// RequestExtendedCursorPositionReport (DECXCPR) is a sequence for requesting
+// the cursor position report including the current page number.
+//
+// CSI ? 6 n
+//
+// The terminal will report the cursor position as a CSI sequence in the
+// following format:
+//
+// CSI ? Pl ; Pc ; Pp R
+//
+// Where Pl is the line number, Pc is the column number, and Pp is the page
+// number.
+// See: https://vt100.net/docs/vt510-rm/DECXCPR.html
+const RequestExtendedCursorPositionReport = "\x1b[?6n"
+
+// CursorPositionReport (CPR) is a control sequence that reports the cursor's
+// position.
+//
+// CSI Pl ; Pc R
+//
+// Where Pl is the line number and Pc is the column number.
+//
+// See also https://vt100.net/docs/vt510-rm/CPR.html
+func CursorPositionReport(line, column int) string {
+ if line < 1 {
+ line = 1
+ }
+ if column < 1 {
+ column = 1
+ }
+ return "\x1b[" + strconv.Itoa(line) + ";" + strconv.Itoa(column) + "R"
+}
+
+// CPR is an alias for [CursorPositionReport].
+func CPR(line, column int) string {
+ return CursorPositionReport(line, column)
+}
+
+// ExtendedCursorPositionReport (DECXCPR) is a control sequence that reports the
+// cursor's position along with the page number (optional).
+//
+// CSI ? Pl ; Pc R
+// CSI ? Pl ; Pc ; Pv R
+//
+// Where Pl is the line number, Pc is the column number, and Pv is the page
+// number.
+//
+// If the page number is zero or negative, the returned sequence won't include
+// the page number.
+//
+// See also https://vt100.net/docs/vt510-rm/DECXCPR.html
+func ExtendedCursorPositionReport(line, column, page int) string {
+ if line < 1 {
+ line = 1
+ }
+ if column < 1 {
+ column = 1
+ }
+ if page < 1 {
+ return "\x1b[?" + strconv.Itoa(line) + ";" + strconv.Itoa(column) + "R"
+ }
+ return "\x1b[?" + strconv.Itoa(line) + ";" + strconv.Itoa(column) + ";" + strconv.Itoa(page) + "R"
+}
+
+// DECXCPR is an alias for [ExtendedCursorPositionReport].
+func DECXCPR(line, column, page int) string {
+ return ExtendedCursorPositionReport(line, column, page)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/style.go b/vendor/github.com/charmbracelet/x/ansi/style.go
new file mode 100644
index 0000000..46ddcaa
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/style.go
@@ -0,0 +1,660 @@
+package ansi
+
+import (
+ "image/color"
+ "strconv"
+ "strings"
+)
+
+// ResetStyle is a SGR (Select Graphic Rendition) style sequence that resets
+// all attributes.
+// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
+const ResetStyle = "\x1b[m"
+
+// Attr is a SGR (Select Graphic Rendition) style attribute.
+type Attr = int
+
+// Style represents an ANSI SGR (Select Graphic Rendition) style.
+type Style []string
+
+// String returns the ANSI SGR (Select Graphic Rendition) style sequence for
+// the given style.
+func (s Style) String() string {
+ if len(s) == 0 {
+ return ResetStyle
+ }
+ return "\x1b[" + strings.Join(s, ";") + "m"
+}
+
+// Styled returns a styled string with the given style applied.
+func (s Style) Styled(str string) string {
+ if len(s) == 0 {
+ return str
+ }
+ return s.String() + str + ResetStyle
+}
+
+// Reset appends the reset style attribute to the style.
+func (s Style) Reset() Style {
+ return append(s, resetAttr)
+}
+
+// Bold appends the bold style attribute to the style.
+func (s Style) Bold() Style {
+ return append(s, boldAttr)
+}
+
+// Faint appends the faint style attribute to the style.
+func (s Style) Faint() Style {
+ return append(s, faintAttr)
+}
+
+// Italic appends the italic style attribute to the style.
+func (s Style) Italic() Style {
+ return append(s, italicAttr)
+}
+
+// Underline appends the underline style attribute to the style.
+func (s Style) Underline() Style {
+ return append(s, underlineAttr)
+}
+
+// UnderlineStyle appends the underline style attribute to the style.
+func (s Style) UnderlineStyle(u UnderlineStyle) Style {
+ switch u {
+ case NoUnderlineStyle:
+ return s.NoUnderline()
+ case SingleUnderlineStyle:
+ return s.Underline()
+ case DoubleUnderlineStyle:
+ return append(s, doubleUnderlineStyle)
+ case CurlyUnderlineStyle:
+ return append(s, curlyUnderlineStyle)
+ case DottedUnderlineStyle:
+ return append(s, dottedUnderlineStyle)
+ case DashedUnderlineStyle:
+ return append(s, dashedUnderlineStyle)
+ }
+ return s
+}
+
+// DoubleUnderline appends the double underline style attribute to the style.
+// This is a convenience method for UnderlineStyle(DoubleUnderlineStyle).
+func (s Style) DoubleUnderline() Style {
+ return s.UnderlineStyle(DoubleUnderlineStyle)
+}
+
+// CurlyUnderline appends the curly underline style attribute to the style.
+// This is a convenience method for UnderlineStyle(CurlyUnderlineStyle).
+func (s Style) CurlyUnderline() Style {
+ return s.UnderlineStyle(CurlyUnderlineStyle)
+}
+
+// DottedUnderline appends the dotted underline style attribute to the style.
+// This is a convenience method for UnderlineStyle(DottedUnderlineStyle).
+func (s Style) DottedUnderline() Style {
+ return s.UnderlineStyle(DottedUnderlineStyle)
+}
+
+// DashedUnderline appends the dashed underline style attribute to the style.
+// This is a convenience method for UnderlineStyle(DashedUnderlineStyle).
+func (s Style) DashedUnderline() Style {
+ return s.UnderlineStyle(DashedUnderlineStyle)
+}
+
+// SlowBlink appends the slow blink style attribute to the style.
+func (s Style) SlowBlink() Style {
+ return append(s, slowBlinkAttr)
+}
+
+// RapidBlink appends the rapid blink style attribute to the style.
+func (s Style) RapidBlink() Style {
+ return append(s, rapidBlinkAttr)
+}
+
+// Reverse appends the reverse style attribute to the style.
+func (s Style) Reverse() Style {
+ return append(s, reverseAttr)
+}
+
+// Conceal appends the conceal style attribute to the style.
+func (s Style) Conceal() Style {
+ return append(s, concealAttr)
+}
+
+// Strikethrough appends the strikethrough style attribute to the style.
+func (s Style) Strikethrough() Style {
+ return append(s, strikethroughAttr)
+}
+
+// NoBold appends the no bold style attribute to the style.
+func (s Style) NoBold() Style {
+ return append(s, noBoldAttr)
+}
+
+// NormalIntensity appends the normal intensity style attribute to the style.
+func (s Style) NormalIntensity() Style {
+ return append(s, normalIntensityAttr)
+}
+
+// NoItalic appends the no italic style attribute to the style.
+func (s Style) NoItalic() Style {
+ return append(s, noItalicAttr)
+}
+
+// NoUnderline appends the no underline style attribute to the style.
+func (s Style) NoUnderline() Style {
+ return append(s, noUnderlineAttr)
+}
+
+// NoBlink appends the no blink style attribute to the style.
+func (s Style) NoBlink() Style {
+ return append(s, noBlinkAttr)
+}
+
+// NoReverse appends the no reverse style attribute to the style.
+func (s Style) NoReverse() Style {
+ return append(s, noReverseAttr)
+}
+
+// NoConceal appends the no conceal style attribute to the style.
+func (s Style) NoConceal() Style {
+ return append(s, noConcealAttr)
+}
+
+// NoStrikethrough appends the no strikethrough style attribute to the style.
+func (s Style) NoStrikethrough() Style {
+ return append(s, noStrikethroughAttr)
+}
+
+// DefaultForegroundColor appends the default foreground color style attribute to the style.
+func (s Style) DefaultForegroundColor() Style {
+ return append(s, defaultForegroundColorAttr)
+}
+
+// DefaultBackgroundColor appends the default background color style attribute to the style.
+func (s Style) DefaultBackgroundColor() Style {
+ return append(s, defaultBackgroundColorAttr)
+}
+
+// DefaultUnderlineColor appends the default underline color style attribute to the style.
+func (s Style) DefaultUnderlineColor() Style {
+ return append(s, defaultUnderlineColorAttr)
+}
+
+// ForegroundColor appends the foreground color style attribute to the style.
+func (s Style) ForegroundColor(c Color) Style {
+ return append(s, foregroundColorString(c))
+}
+
+// BackgroundColor appends the background color style attribute to the style.
+func (s Style) BackgroundColor(c Color) Style {
+ return append(s, backgroundColorString(c))
+}
+
+// UnderlineColor appends the underline color style attribute to the style.
+func (s Style) UnderlineColor(c Color) Style {
+ return append(s, underlineColorString(c))
+}
+
+// UnderlineStyle represents an ANSI SGR (Select Graphic Rendition) underline
+// style.
+type UnderlineStyle = byte
+
+const (
+ doubleUnderlineStyle = "4:2"
+ curlyUnderlineStyle = "4:3"
+ dottedUnderlineStyle = "4:4"
+ dashedUnderlineStyle = "4:5"
+)
+
+const (
+ // NoUnderlineStyle is the default underline style.
+ NoUnderlineStyle UnderlineStyle = iota
+ // SingleUnderlineStyle is a single underline style.
+ SingleUnderlineStyle
+ // DoubleUnderlineStyle is a double underline style.
+ DoubleUnderlineStyle
+ // CurlyUnderlineStyle is a curly underline style.
+ CurlyUnderlineStyle
+ // DottedUnderlineStyle is a dotted underline style.
+ DottedUnderlineStyle
+ // DashedUnderlineStyle is a dashed underline style.
+ DashedUnderlineStyle
+)
+
+// SGR (Select Graphic Rendition) style attributes.
+// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
+const (
+ ResetAttr Attr = 0
+ BoldAttr Attr = 1
+ FaintAttr Attr = 2
+ ItalicAttr Attr = 3
+ UnderlineAttr Attr = 4
+ SlowBlinkAttr Attr = 5
+ RapidBlinkAttr Attr = 6
+ ReverseAttr Attr = 7
+ ConcealAttr Attr = 8
+ StrikethroughAttr Attr = 9
+ NoBoldAttr Attr = 21 // Some terminals treat this as double underline.
+ NormalIntensityAttr Attr = 22
+ NoItalicAttr Attr = 23
+ NoUnderlineAttr Attr = 24
+ NoBlinkAttr Attr = 25
+ NoReverseAttr Attr = 27
+ NoConcealAttr Attr = 28
+ NoStrikethroughAttr Attr = 29
+ BlackForegroundColorAttr Attr = 30
+ RedForegroundColorAttr Attr = 31
+ GreenForegroundColorAttr Attr = 32
+ YellowForegroundColorAttr Attr = 33
+ BlueForegroundColorAttr Attr = 34
+ MagentaForegroundColorAttr Attr = 35
+ CyanForegroundColorAttr Attr = 36
+ WhiteForegroundColorAttr Attr = 37
+ ExtendedForegroundColorAttr Attr = 38
+ DefaultForegroundColorAttr Attr = 39
+ BlackBackgroundColorAttr Attr = 40
+ RedBackgroundColorAttr Attr = 41
+ GreenBackgroundColorAttr Attr = 42
+ YellowBackgroundColorAttr Attr = 43
+ BlueBackgroundColorAttr Attr = 44
+ MagentaBackgroundColorAttr Attr = 45
+ CyanBackgroundColorAttr Attr = 46
+ WhiteBackgroundColorAttr Attr = 47
+ ExtendedBackgroundColorAttr Attr = 48
+ DefaultBackgroundColorAttr Attr = 49
+ ExtendedUnderlineColorAttr Attr = 58
+ DefaultUnderlineColorAttr Attr = 59
+ BrightBlackForegroundColorAttr Attr = 90
+ BrightRedForegroundColorAttr Attr = 91
+ BrightGreenForegroundColorAttr Attr = 92
+ BrightYellowForegroundColorAttr Attr = 93
+ BrightBlueForegroundColorAttr Attr = 94
+ BrightMagentaForegroundColorAttr Attr = 95
+ BrightCyanForegroundColorAttr Attr = 96
+ BrightWhiteForegroundColorAttr Attr = 97
+ BrightBlackBackgroundColorAttr Attr = 100
+ BrightRedBackgroundColorAttr Attr = 101
+ BrightGreenBackgroundColorAttr Attr = 102
+ BrightYellowBackgroundColorAttr Attr = 103
+ BrightBlueBackgroundColorAttr Attr = 104
+ BrightMagentaBackgroundColorAttr Attr = 105
+ BrightCyanBackgroundColorAttr Attr = 106
+ BrightWhiteBackgroundColorAttr Attr = 107
+
+ RGBColorIntroducerAttr Attr = 2
+ ExtendedColorIntroducerAttr Attr = 5
+)
+
+const (
+ resetAttr = "0"
+ boldAttr = "1"
+ faintAttr = "2"
+ italicAttr = "3"
+ underlineAttr = "4"
+ slowBlinkAttr = "5"
+ rapidBlinkAttr = "6"
+ reverseAttr = "7"
+ concealAttr = "8"
+ strikethroughAttr = "9"
+ noBoldAttr = "21"
+ normalIntensityAttr = "22"
+ noItalicAttr = "23"
+ noUnderlineAttr = "24"
+ noBlinkAttr = "25"
+ noReverseAttr = "27"
+ noConcealAttr = "28"
+ noStrikethroughAttr = "29"
+ blackForegroundColorAttr = "30"
+ redForegroundColorAttr = "31"
+ greenForegroundColorAttr = "32"
+ yellowForegroundColorAttr = "33"
+ blueForegroundColorAttr = "34"
+ magentaForegroundColorAttr = "35"
+ cyanForegroundColorAttr = "36"
+ whiteForegroundColorAttr = "37"
+ extendedForegroundColorAttr = "38"
+ defaultForegroundColorAttr = "39"
+ blackBackgroundColorAttr = "40"
+ redBackgroundColorAttr = "41"
+ greenBackgroundColorAttr = "42"
+ yellowBackgroundColorAttr = "43"
+ blueBackgroundColorAttr = "44"
+ magentaBackgroundColorAttr = "45"
+ cyanBackgroundColorAttr = "46"
+ whiteBackgroundColorAttr = "47"
+ extendedBackgroundColorAttr = "48"
+ defaultBackgroundColorAttr = "49"
+ extendedUnderlineColorAttr = "58"
+ defaultUnderlineColorAttr = "59"
+ brightBlackForegroundColorAttr = "90"
+ brightRedForegroundColorAttr = "91"
+ brightGreenForegroundColorAttr = "92"
+ brightYellowForegroundColorAttr = "93"
+ brightBlueForegroundColorAttr = "94"
+ brightMagentaForegroundColorAttr = "95"
+ brightCyanForegroundColorAttr = "96"
+ brightWhiteForegroundColorAttr = "97"
+ brightBlackBackgroundColorAttr = "100"
+ brightRedBackgroundColorAttr = "101"
+ brightGreenBackgroundColorAttr = "102"
+ brightYellowBackgroundColorAttr = "103"
+ brightBlueBackgroundColorAttr = "104"
+ brightMagentaBackgroundColorAttr = "105"
+ brightCyanBackgroundColorAttr = "106"
+ brightWhiteBackgroundColorAttr = "107"
+)
+
+// foregroundColorString returns the style SGR attribute for the given
+// foreground color.
+// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
+func foregroundColorString(c Color) string {
+ switch c := c.(type) {
+ case BasicColor:
+ // 3-bit or 4-bit ANSI foreground
+ // "3" or "9" where n is the color number from 0 to 7
+ switch c {
+ case Black:
+ return blackForegroundColorAttr
+ case Red:
+ return redForegroundColorAttr
+ case Green:
+ return greenForegroundColorAttr
+ case Yellow:
+ return yellowForegroundColorAttr
+ case Blue:
+ return blueForegroundColorAttr
+ case Magenta:
+ return magentaForegroundColorAttr
+ case Cyan:
+ return cyanForegroundColorAttr
+ case White:
+ return whiteForegroundColorAttr
+ case BrightBlack:
+ return brightBlackForegroundColorAttr
+ case BrightRed:
+ return brightRedForegroundColorAttr
+ case BrightGreen:
+ return brightGreenForegroundColorAttr
+ case BrightYellow:
+ return brightYellowForegroundColorAttr
+ case BrightBlue:
+ return brightBlueForegroundColorAttr
+ case BrightMagenta:
+ return brightMagentaForegroundColorAttr
+ case BrightCyan:
+ return brightCyanForegroundColorAttr
+ case BrightWhite:
+ return brightWhiteForegroundColorAttr
+ }
+ case ExtendedColor:
+ // 256-color ANSI foreground
+ // "38;5;"
+ return "38;5;" + strconv.FormatUint(uint64(c), 10)
+ case TrueColor, color.Color:
+ // 24-bit "true color" foreground
+ // "38;2;;;"
+ r, g, b, _ := c.RGBA()
+ return "38;2;" +
+ strconv.FormatUint(uint64(shift(r)), 10) + ";" +
+ strconv.FormatUint(uint64(shift(g)), 10) + ";" +
+ strconv.FormatUint(uint64(shift(b)), 10)
+ }
+ return defaultForegroundColorAttr
+}
+
+// backgroundColorString returns the style SGR attribute for the given
+// background color.
+// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
+func backgroundColorString(c Color) string {
+ switch c := c.(type) {
+ case BasicColor:
+ // 3-bit or 4-bit ANSI foreground
+ // "4" or "10" where n is the color number from 0 to 7
+ switch c {
+ case Black:
+ return blackBackgroundColorAttr
+ case Red:
+ return redBackgroundColorAttr
+ case Green:
+ return greenBackgroundColorAttr
+ case Yellow:
+ return yellowBackgroundColorAttr
+ case Blue:
+ return blueBackgroundColorAttr
+ case Magenta:
+ return magentaBackgroundColorAttr
+ case Cyan:
+ return cyanBackgroundColorAttr
+ case White:
+ return whiteBackgroundColorAttr
+ case BrightBlack:
+ return brightBlackBackgroundColorAttr
+ case BrightRed:
+ return brightRedBackgroundColorAttr
+ case BrightGreen:
+ return brightGreenBackgroundColorAttr
+ case BrightYellow:
+ return brightYellowBackgroundColorAttr
+ case BrightBlue:
+ return brightBlueBackgroundColorAttr
+ case BrightMagenta:
+ return brightMagentaBackgroundColorAttr
+ case BrightCyan:
+ return brightCyanBackgroundColorAttr
+ case BrightWhite:
+ return brightWhiteBackgroundColorAttr
+ }
+ case ExtendedColor:
+ // 256-color ANSI foreground
+ // "48;5;"
+ return "48;5;" + strconv.FormatUint(uint64(c), 10)
+ case TrueColor, color.Color:
+ // 24-bit "true color" foreground
+ // "38;2;;;"
+ r, g, b, _ := c.RGBA()
+ return "48;2;" +
+ strconv.FormatUint(uint64(shift(r)), 10) + ";" +
+ strconv.FormatUint(uint64(shift(g)), 10) + ";" +
+ strconv.FormatUint(uint64(shift(b)), 10)
+ }
+ return defaultBackgroundColorAttr
+}
+
+// underlineColorString returns the style SGR attribute for the given underline
+// color.
+// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
+func underlineColorString(c Color) string {
+ switch c := c.(type) {
+ // NOTE: we can't use 3-bit and 4-bit ANSI color codes with underline
+ // color, use 256-color instead.
+ //
+ // 256-color ANSI underline color
+ // "58;5;"
+ case BasicColor:
+ return "58;5;" + strconv.FormatUint(uint64(c), 10)
+ case ExtendedColor:
+ return "58;5;" + strconv.FormatUint(uint64(c), 10)
+ case TrueColor, color.Color:
+ // 24-bit "true color" foreground
+ // "38;2;;;"
+ r, g, b, _ := c.RGBA()
+ return "58;2;" +
+ strconv.FormatUint(uint64(shift(r)), 10) + ";" +
+ strconv.FormatUint(uint64(shift(g)), 10) + ";" +
+ strconv.FormatUint(uint64(shift(b)), 10)
+ }
+ return defaultUnderlineColorAttr
+}
+
+// ReadStyleColor decodes a color from a slice of parameters. It returns the
+// number of parameters read and the color. This function is used to read SGR
+// color parameters following the ITU T.416 standard.
+//
+// It supports reading the following color types:
+// - 0: implementation defined
+// - 1: transparent
+// - 2: RGB direct color
+// - 3: CMY direct color
+// - 4: CMYK direct color
+// - 5: indexed color
+// - 6: RGBA direct color (WezTerm extension)
+//
+// The parameters can be separated by semicolons (;) or colons (:). Mixing
+// separators is not allowed.
+//
+// The specs supports defining a color space id, a color tolerance value, and a
+// tolerance color space id. However, these values have no effect on the
+// returned color and will be ignored.
+//
+// This implementation includes a few modifications to the specs:
+// 1. Support for legacy color values separated by semicolons (;) with respect to RGB, and indexed colors
+// 2. Support ignoring and omitting the color space id (second parameter) with respect to RGB colors
+// 3. Support ignoring and omitting the 6th parameter with respect to RGB and CMY colors
+// 4. Support reading RGBA colors
+func ReadStyleColor(params Params, co *color.Color) (n int) {
+ if len(params) < 2 { // Need at least SGR type and color type
+ return 0
+ }
+
+ // First parameter indicates one of 38, 48, or 58 (foreground, background, or underline)
+ s := params[0]
+ p := params[1]
+ colorType := p.Param(0)
+ n = 2
+
+ paramsfn := func() (p1, p2, p3, p4 int) {
+ // Where should we start reading the color?
+ switch {
+ case s.HasMore() && p.HasMore() && len(params) > 8 && params[2].HasMore() && params[3].HasMore() && params[4].HasMore() && params[5].HasMore() && params[6].HasMore() && params[7].HasMore():
+ // We have color space id, a 6th parameter, a tolerance value, and a tolerance color space
+ n += 7
+ return params[3].Param(0), params[4].Param(0), params[5].Param(0), params[6].Param(0)
+ case s.HasMore() && p.HasMore() && len(params) > 7 && params[2].HasMore() && params[3].HasMore() && params[4].HasMore() && params[5].HasMore() && params[6].HasMore():
+ // We have color space id, a 6th parameter, and a tolerance value
+ n += 6
+ return params[3].Param(0), params[4].Param(0), params[5].Param(0), params[6].Param(0)
+ case s.HasMore() && p.HasMore() && len(params) > 6 && params[2].HasMore() && params[3].HasMore() && params[4].HasMore() && params[5].HasMore():
+ // We have color space id and a 6th parameter
+ // 48 : 4 : : 1 : 2 : 3 :4
+ n += 5
+ return params[3].Param(0), params[4].Param(0), params[5].Param(0), params[6].Param(0)
+ case s.HasMore() && p.HasMore() && len(params) > 5 && params[2].HasMore() && params[3].HasMore() && params[4].HasMore() && !params[5].HasMore():
+ // We have color space
+ // 48 : 3 : : 1 : 2 : 3
+ n += 4
+ return params[3].Param(0), params[4].Param(0), params[5].Param(0), -1
+ case s.HasMore() && p.HasMore() && p.Param(0) == 2 && params[2].HasMore() && params[3].HasMore() && !params[4].HasMore():
+ // We have color values separated by colons (:)
+ // 48 : 2 : 1 : 2 : 3
+ fallthrough
+ case !s.HasMore() && !p.HasMore() && p.Param(0) == 2 && !params[2].HasMore() && !params[3].HasMore() && !params[4].HasMore():
+ // Support legacy color values separated by semicolons (;)
+ // 48 ; 2 ; 1 ; 2 ; 3
+ n += 3
+ return params[2].Param(0), params[3].Param(0), params[4].Param(0), -1
+ }
+ // Ambiguous SGR color
+ return -1, -1, -1, -1
+ }
+
+ switch colorType {
+ case 0: // implementation defined
+ return 2
+ case 1: // transparent
+ *co = color.Transparent
+ return 2
+ case 2: // RGB direct color
+ if len(params) < 5 {
+ return 0
+ }
+
+ r, g, b, _ := paramsfn()
+ if r == -1 || g == -1 || b == -1 {
+ return 0
+ }
+
+ *co = color.RGBA{
+ R: uint8(r), //nolint:gosec
+ G: uint8(g), //nolint:gosec
+ B: uint8(b), //nolint:gosec
+ A: 0xff,
+ }
+ return
+
+ case 3: // CMY direct color
+ if len(params) < 5 {
+ return 0
+ }
+
+ c, m, y, _ := paramsfn()
+ if c == -1 || m == -1 || y == -1 {
+ return 0
+ }
+
+ *co = color.CMYK{
+ C: uint8(c), //nolint:gosec
+ M: uint8(m), //nolint:gosec
+ Y: uint8(y), //nolint:gosec
+ K: 0,
+ }
+ return
+
+ case 4: // CMYK direct color
+ if len(params) < 6 {
+ return 0
+ }
+
+ c, m, y, k := paramsfn()
+ if c == -1 || m == -1 || y == -1 || k == -1 {
+ return 0
+ }
+
+ *co = color.CMYK{
+ C: uint8(c), //nolint:gosec
+ M: uint8(m), //nolint:gosec
+ Y: uint8(y), //nolint:gosec
+ K: uint8(k), //nolint:gosec
+ }
+ return
+
+ case 5: // indexed color
+ if len(params) < 3 {
+ return 0
+ }
+ switch {
+ case s.HasMore() && p.HasMore() && !params[2].HasMore():
+ // Colon separated indexed color
+ // 38 : 5 : 234
+ case !s.HasMore() && !p.HasMore() && !params[2].HasMore():
+ // Legacy semicolon indexed color
+ // 38 ; 5 ; 234
+ default:
+ return 0
+ }
+ *co = ExtendedColor(params[2].Param(0)) //nolint:gosec
+ return 3
+
+ case 6: // RGBA direct color
+ if len(params) < 6 {
+ return 0
+ }
+
+ r, g, b, a := paramsfn()
+ if r == -1 || g == -1 || b == -1 || a == -1 {
+ return 0
+ }
+
+ *co = color.RGBA{
+ R: uint8(r), //nolint:gosec
+ G: uint8(g), //nolint:gosec
+ B: uint8(b), //nolint:gosec
+ A: uint8(a), //nolint:gosec
+ }
+ return
+
+ default:
+ return 0
+ }
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/termcap.go b/vendor/github.com/charmbracelet/x/ansi/termcap.go
new file mode 100644
index 0000000..3c5c7da
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/termcap.go
@@ -0,0 +1,41 @@
+package ansi
+
+import (
+ "encoding/hex"
+ "strings"
+)
+
+// RequestTermcap (XTGETTCAP) requests Termcap/Terminfo strings.
+//
+// DCS + q ST
+//
+// Where is a list of Termcap/Terminfo capabilities, encoded in 2-digit
+// hexadecimals, separated by semicolons.
+//
+// See: https://man7.org/linux/man-pages/man5/terminfo.5.html
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+func XTGETTCAP(caps ...string) string {
+ if len(caps) == 0 {
+ return ""
+ }
+
+ s := "\x1bP+q"
+ for i, c := range caps {
+ if i > 0 {
+ s += ";"
+ }
+ s += strings.ToUpper(hex.EncodeToString([]byte(c)))
+ }
+
+ return s + "\x1b\\"
+}
+
+// RequestTermcap is an alias for [XTGETTCAP].
+func RequestTermcap(caps ...string) string {
+ return XTGETTCAP(caps...)
+}
+
+// RequestTerminfo is an alias for [XTGETTCAP].
+func RequestTerminfo(caps ...string) string {
+ return XTGETTCAP(caps...)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/title.go b/vendor/github.com/charmbracelet/x/ansi/title.go
new file mode 100644
index 0000000..8fd8bf9
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/title.go
@@ -0,0 +1,32 @@
+package ansi
+
+// SetIconNameWindowTitle returns a sequence for setting the icon name and
+// window title.
+//
+// OSC 0 ; title ST
+// OSC 0 ; title BEL
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands
+func SetIconNameWindowTitle(s string) string {
+ return "\x1b]0;" + s + "\x07"
+}
+
+// SetIconName returns a sequence for setting the icon name.
+//
+// OSC 1 ; title ST
+// OSC 1 ; title BEL
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands
+func SetIconName(s string) string {
+ return "\x1b]1;" + s + "\x07"
+}
+
+// SetWindowTitle returns a sequence for setting the window title.
+//
+// OSC 2 ; title ST
+// OSC 2 ; title BEL
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands
+func SetWindowTitle(s string) string {
+ return "\x1b]2;" + s + "\x07"
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/truncate.go b/vendor/github.com/charmbracelet/x/ansi/truncate.go
new file mode 100644
index 0000000..1fa3efe
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/truncate.go
@@ -0,0 +1,282 @@
+package ansi
+
+import (
+ "bytes"
+
+ "github.com/charmbracelet/x/ansi/parser"
+ "github.com/mattn/go-runewidth"
+ "github.com/rivo/uniseg"
+)
+
+// Cut the string, without adding any prefix or tail strings. This function is
+// aware of ANSI escape codes and will not break them, and accounts for
+// wide-characters (such as East-Asian characters and emojis). Note that the
+// [left] parameter is inclusive, while [right] isn't.
+// This treats the text as a sequence of graphemes.
+func Cut(s string, left, right int) string {
+ return cut(GraphemeWidth, s, left, right)
+}
+
+// CutWc the string, without adding any prefix or tail strings. This function is
+// aware of ANSI escape codes and will not break them, and accounts for
+// wide-characters (such as East-Asian characters and emojis). Note that the
+// [left] parameter is inclusive, while [right] isn't.
+// This treats the text as a sequence of wide characters and runes.
+func CutWc(s string, left, right int) string {
+ return cut(WcWidth, s, left, right)
+}
+
+func cut(m Method, s string, left, right int) string {
+ if right <= left {
+ return ""
+ }
+
+ truncate := Truncate
+ truncateLeft := TruncateLeft
+ if m == WcWidth {
+ truncate = TruncateWc
+ truncateLeft = TruncateWc
+ }
+
+ if left == 0 {
+ return truncate(s, right, "")
+ }
+ return truncateLeft(Truncate(s, right, ""), left, "")
+}
+
+// Truncate truncates a string to a given length, adding a tail to the end if
+// the string is longer than the given length. This function is aware of ANSI
+// escape codes and will not break them, and accounts for wide-characters (such
+// as East-Asian characters and emojis).
+// This treats the text as a sequence of graphemes.
+func Truncate(s string, length int, tail string) string {
+ return truncate(GraphemeWidth, s, length, tail)
+}
+
+// TruncateWc truncates a string to a given length, adding a tail to the end if
+// the string is longer than the given length. This function is aware of ANSI
+// escape codes and will not break them, and accounts for wide-characters (such
+// as East-Asian characters and emojis).
+// This treats the text as a sequence of wide characters and runes.
+func TruncateWc(s string, length int, tail string) string {
+ return truncate(WcWidth, s, length, tail)
+}
+
+func truncate(m Method, s string, length int, tail string) string {
+ if sw := StringWidth(s); sw <= length {
+ return s
+ }
+
+ tw := StringWidth(tail)
+ length -= tw
+ if length < 0 {
+ return ""
+ }
+
+ var cluster []byte
+ var buf bytes.Buffer
+ curWidth := 0
+ ignoring := false
+ pstate := parser.GroundState // initial state
+ b := []byte(s)
+ i := 0
+
+ // Here we iterate over the bytes of the string and collect printable
+ // characters and runes. We also keep track of the width of the string
+ // in cells.
+ //
+ // Once we reach the given length, we start ignoring characters and only
+ // collect ANSI escape codes until we reach the end of string.
+ for i < len(b) {
+ state, action := parser.Table.Transition(pstate, b[i])
+ if state == parser.Utf8State {
+ // This action happens when we transition to the Utf8State.
+ var width int
+ cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1)
+ if m == WcWidth {
+ width = runewidth.StringWidth(string(cluster))
+ }
+
+ // increment the index by the length of the cluster
+ i += len(cluster)
+
+ // Are we ignoring? Skip to the next byte
+ if ignoring {
+ continue
+ }
+
+ // Is this gonna be too wide?
+ // If so write the tail and stop collecting.
+ if curWidth+width > length && !ignoring {
+ ignoring = true
+ buf.WriteString(tail)
+ }
+
+ if curWidth+width > length {
+ continue
+ }
+
+ curWidth += width
+ buf.Write(cluster)
+
+ // Done collecting, now we're back in the ground state.
+ pstate = parser.GroundState
+ continue
+ }
+
+ switch action {
+ case parser.PrintAction:
+ // Is this gonna be too wide?
+ // If so write the tail and stop collecting.
+ if curWidth >= length && !ignoring {
+ ignoring = true
+ buf.WriteString(tail)
+ }
+
+ // Skip to the next byte if we're ignoring
+ if ignoring {
+ i++
+ continue
+ }
+
+ // collects printable ASCII
+ curWidth++
+ fallthrough
+ default:
+ buf.WriteByte(b[i])
+ i++
+ }
+
+ // Transition to the next state.
+ pstate = state
+
+ // Once we reach the given length, we start ignoring runes and write
+ // the tail to the buffer.
+ if curWidth > length && !ignoring {
+ ignoring = true
+ buf.WriteString(tail)
+ }
+ }
+
+ return buf.String()
+}
+
+// TruncateLeft truncates a string from the left side by removing n characters,
+// adding a prefix to the beginning if the string is longer than n.
+// This function is aware of ANSI escape codes and will not break them, and
+// accounts for wide-characters (such as East-Asian characters and emojis).
+// This treats the text as a sequence of graphemes.
+func TruncateLeft(s string, n int, prefix string) string {
+ return truncateLeft(GraphemeWidth, s, n, prefix)
+}
+
+// TruncateLeftWc truncates a string from the left side by removing n characters,
+// adding a prefix to the beginning if the string is longer than n.
+// This function is aware of ANSI escape codes and will not break them, and
+// accounts for wide-characters (such as East-Asian characters and emojis).
+// This treats the text as a sequence of wide characters and runes.
+func TruncateLeftWc(s string, n int, prefix string) string {
+ return truncateLeft(WcWidth, s, n, prefix)
+}
+
+func truncateLeft(m Method, s string, n int, prefix string) string {
+ if n <= 0 {
+ return s
+ }
+
+ var cluster []byte
+ var buf bytes.Buffer
+ curWidth := 0
+ ignoring := true
+ pstate := parser.GroundState
+ b := []byte(s)
+ i := 0
+
+ for i < len(b) {
+ if !ignoring {
+ buf.Write(b[i:])
+ break
+ }
+
+ state, action := parser.Table.Transition(pstate, b[i])
+ if state == parser.Utf8State {
+ var width int
+ cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1)
+ if m == WcWidth {
+ width = runewidth.StringWidth(string(cluster))
+ }
+
+ i += len(cluster)
+ curWidth += width
+
+ if curWidth > n && ignoring {
+ ignoring = false
+ buf.WriteString(prefix)
+ }
+
+ if ignoring {
+ continue
+ }
+
+ if curWidth > n {
+ buf.Write(cluster)
+ }
+
+ pstate = parser.GroundState
+ continue
+ }
+
+ switch action {
+ case parser.PrintAction:
+ curWidth++
+
+ if curWidth > n && ignoring {
+ ignoring = false
+ buf.WriteString(prefix)
+ }
+
+ if ignoring {
+ i++
+ continue
+ }
+
+ fallthrough
+ default:
+ buf.WriteByte(b[i])
+ i++
+ }
+
+ pstate = state
+ if curWidth > n && ignoring {
+ ignoring = false
+ buf.WriteString(prefix)
+ }
+ }
+
+ return buf.String()
+}
+
+// ByteToGraphemeRange takes start and stop byte positions and converts them to
+// grapheme-aware char positions.
+// You can use this with [Truncate], [TruncateLeft], and [Cut].
+func ByteToGraphemeRange(str string, byteStart, byteStop int) (charStart, charStop int) {
+ bytePos, charPos := 0, 0
+ gr := uniseg.NewGraphemes(str)
+ for byteStart > bytePos {
+ if !gr.Next() {
+ break
+ }
+ bytePos += len(gr.Str())
+ charPos += max(1, gr.Width())
+ }
+ charStart = charPos
+ for byteStop > bytePos {
+ if !gr.Next() {
+ break
+ }
+ bytePos += len(gr.Str())
+ charPos += max(1, gr.Width())
+ }
+ charStop = charPos
+ return
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/util.go b/vendor/github.com/charmbracelet/x/ansi/util.go
new file mode 100644
index 0000000..301ef15
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/util.go
@@ -0,0 +1,106 @@
+package ansi
+
+import (
+ "fmt"
+ "image/color"
+ "strconv"
+ "strings"
+
+ "github.com/lucasb-eyer/go-colorful"
+)
+
+// colorToHexString returns a hex string representation of a color.
+func colorToHexString(c color.Color) string {
+ if c == nil {
+ return ""
+ }
+ shift := func(v uint32) uint32 {
+ if v > 0xff {
+ return v >> 8
+ }
+ return v
+ }
+ r, g, b, _ := c.RGBA()
+ r, g, b = shift(r), shift(g), shift(b)
+ return fmt.Sprintf("#%02x%02x%02x", r, g, b)
+}
+
+// rgbToHex converts red, green, and blue values to a hexadecimal value.
+//
+// hex := rgbToHex(0, 0, 255) // 0x0000FF
+func rgbToHex(r, g, b uint32) uint32 {
+ return r<<16 + g<<8 + b
+}
+
+type shiftable interface {
+ ~uint | ~uint16 | ~uint32 | ~uint64
+}
+
+func shift[T shiftable](x T) T {
+ if x > 0xff {
+ x >>= 8
+ }
+ return x
+}
+
+// XParseColor is a helper function that parses a string into a color.Color. It
+// provides a similar interface to the XParseColor function in Xlib. It
+// supports the following formats:
+//
+// - #RGB
+// - #RRGGBB
+// - rgb:RRRR/GGGG/BBBB
+// - rgba:RRRR/GGGG/BBBB/AAAA
+//
+// If the string is not a valid color, nil is returned.
+//
+// See: https://linux.die.net/man/3/xparsecolor
+func XParseColor(s string) color.Color {
+ switch {
+ case strings.HasPrefix(s, "#"):
+ c, err := colorful.Hex(s)
+ if err != nil {
+ return nil
+ }
+
+ return c
+ case strings.HasPrefix(s, "rgb:"):
+ parts := strings.Split(s[4:], "/")
+ if len(parts) != 3 {
+ return nil
+ }
+
+ r, _ := strconv.ParseUint(parts[0], 16, 32)
+ g, _ := strconv.ParseUint(parts[1], 16, 32)
+ b, _ := strconv.ParseUint(parts[2], 16, 32)
+
+ return color.RGBA{uint8(shift(r)), uint8(shift(g)), uint8(shift(b)), 255} //nolint:gosec
+ case strings.HasPrefix(s, "rgba:"):
+ parts := strings.Split(s[5:], "/")
+ if len(parts) != 4 {
+ return nil
+ }
+
+ r, _ := strconv.ParseUint(parts[0], 16, 32)
+ g, _ := strconv.ParseUint(parts[1], 16, 32)
+ b, _ := strconv.ParseUint(parts[2], 16, 32)
+ a, _ := strconv.ParseUint(parts[3], 16, 32)
+
+ return color.RGBA{uint8(shift(r)), uint8(shift(g)), uint8(shift(b)), uint8(shift(a))} //nolint:gosec
+ }
+ return nil
+}
+
+type ordered interface {
+ ~int | ~int8 | ~int16 | ~int32 | ~int64 |
+ ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
+ ~float32 | ~float64 |
+ ~string
+}
+
+func max[T ordered](a, b T) T { //nolint:predeclared
+ if a > b {
+ return a
+ }
+ return b
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/width.go b/vendor/github.com/charmbracelet/x/ansi/width.go
new file mode 100644
index 0000000..d0487d3
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/width.go
@@ -0,0 +1,113 @@
+package ansi
+
+import (
+ "bytes"
+
+ "github.com/charmbracelet/x/ansi/parser"
+ "github.com/mattn/go-runewidth"
+ "github.com/rivo/uniseg"
+)
+
+// Strip removes ANSI escape codes from a string.
+func Strip(s string) string {
+ var (
+ buf bytes.Buffer // buffer for collecting printable characters
+ ri int // rune index
+ rw int // rune width
+ pstate = parser.GroundState // initial state
+ )
+
+ // This implements a subset of the Parser to only collect runes and
+ // printable characters.
+ for i := 0; i < len(s); i++ {
+ if pstate == parser.Utf8State {
+ // During this state, collect rw bytes to form a valid rune in the
+ // buffer. After getting all the rune bytes into the buffer,
+ // transition to GroundState and reset the counters.
+ buf.WriteByte(s[i])
+ ri++
+ if ri < rw {
+ continue
+ }
+ pstate = parser.GroundState
+ ri = 0
+ rw = 0
+ continue
+ }
+
+ state, action := parser.Table.Transition(pstate, s[i])
+ switch action {
+ case parser.CollectAction:
+ if state == parser.Utf8State {
+ // This action happens when we transition to the Utf8State.
+ rw = utf8ByteLen(s[i])
+ buf.WriteByte(s[i])
+ ri++
+ }
+ case parser.PrintAction, parser.ExecuteAction:
+ // collects printable ASCII and non-printable characters
+ buf.WriteByte(s[i])
+ }
+
+ // Transition to the next state.
+ // The Utf8State is managed separately above.
+ if pstate != parser.Utf8State {
+ pstate = state
+ }
+ }
+
+ return buf.String()
+}
+
+// StringWidth returns the width of a string in cells. This is the number of
+// cells that the string will occupy when printed in a terminal. ANSI escape
+// codes are ignored and wide characters (such as East Asians and emojis) are
+// accounted for.
+// This treats the text as a sequence of grapheme clusters.
+func StringWidth(s string) int {
+ return stringWidth(GraphemeWidth, s)
+}
+
+// StringWidthWc returns the width of a string in cells. This is the number of
+// cells that the string will occupy when printed in a terminal. ANSI escape
+// codes are ignored and wide characters (such as East Asians and emojis) are
+// accounted for.
+// This treats the text as a sequence of wide characters and runes.
+func StringWidthWc(s string) int {
+ return stringWidth(WcWidth, s)
+}
+
+func stringWidth(m Method, s string) int {
+ if s == "" {
+ return 0
+ }
+
+ var (
+ pstate = parser.GroundState // initial state
+ cluster string
+ width int
+ )
+
+ for i := 0; i < len(s); i++ {
+ state, action := parser.Table.Transition(pstate, s[i])
+ if state == parser.Utf8State {
+ var w int
+ cluster, _, w, _ = uniseg.FirstGraphemeClusterInString(s[i:], -1)
+ if m == WcWidth {
+ w = runewidth.StringWidth(cluster)
+ }
+ width += w
+ i += len(cluster) - 1
+ pstate = parser.GroundState
+ continue
+ }
+
+ if action == parser.PrintAction {
+ width++
+ }
+
+ pstate = state
+ }
+
+ return width
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/winop.go b/vendor/github.com/charmbracelet/x/ansi/winop.go
new file mode 100644
index 0000000..0238780
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/winop.go
@@ -0,0 +1,53 @@
+package ansi
+
+import (
+ "strconv"
+ "strings"
+)
+
+const (
+ // ResizeWindowWinOp is a window operation that resizes the terminal
+ // window.
+ ResizeWindowWinOp = 4
+
+ // RequestWindowSizeWinOp is a window operation that requests a report of
+ // the size of the terminal window in pixels. The response is in the form:
+ // CSI 4 ; height ; width t
+ RequestWindowSizeWinOp = 14
+
+ // RequestCellSizeWinOp is a window operation that requests a report of
+ // the size of the terminal cell size in pixels. The response is in the form:
+ // CSI 6 ; height ; width t
+ RequestCellSizeWinOp = 16
+)
+
+// WindowOp (XTWINOPS) is a sequence that manipulates the terminal window.
+//
+// CSI Ps ; Ps ; Ps t
+//
+// Ps is a semicolon-separated list of parameters.
+// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps;Ps;Ps-t.1EB0
+func WindowOp(p int, ps ...int) string {
+ if p <= 0 {
+ return ""
+ }
+
+ if len(ps) == 0 {
+ return "\x1b[" + strconv.Itoa(p) + "t"
+ }
+
+ params := make([]string, 0, len(ps)+1)
+ params = append(params, strconv.Itoa(p))
+ for _, p := range ps {
+ if p >= 0 {
+ params = append(params, strconv.Itoa(p))
+ }
+ }
+
+ return "\x1b[" + strings.Join(params, ";") + "t"
+}
+
+// XTWINOPS is an alias for [WindowOp].
+func XTWINOPS(p int, ps ...int) string {
+ return WindowOp(p, ps...)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/wrap.go b/vendor/github.com/charmbracelet/x/ansi/wrap.go
new file mode 100644
index 0000000..6b99580
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/wrap.go
@@ -0,0 +1,467 @@
+package ansi
+
+import (
+ "bytes"
+ "unicode"
+ "unicode/utf8"
+
+ "github.com/charmbracelet/x/ansi/parser"
+ "github.com/mattn/go-runewidth"
+ "github.com/rivo/uniseg"
+)
+
+// nbsp is a non-breaking space
+const nbsp = 0xA0
+
+// Hardwrap wraps a string or a block of text to a given line length, breaking
+// word boundaries. This will preserve ANSI escape codes and will account for
+// wide-characters in the string.
+// When preserveSpace is true, spaces at the beginning of a line will be
+// preserved.
+// This treats the text as a sequence of graphemes.
+func Hardwrap(s string, limit int, preserveSpace bool) string {
+ return hardwrap(GraphemeWidth, s, limit, preserveSpace)
+}
+
+// HardwrapWc wraps a string or a block of text to a given line length, breaking
+// word boundaries. This will preserve ANSI escape codes and will account for
+// wide-characters in the string.
+// When preserveSpace is true, spaces at the beginning of a line will be
+// preserved.
+// This treats the text as a sequence of wide characters and runes.
+func HardwrapWc(s string, limit int, preserveSpace bool) string {
+ return hardwrap(WcWidth, s, limit, preserveSpace)
+}
+
+func hardwrap(m Method, s string, limit int, preserveSpace bool) string {
+ if limit < 1 {
+ return s
+ }
+
+ var (
+ cluster []byte
+ buf bytes.Buffer
+ curWidth int
+ forceNewline bool
+ pstate = parser.GroundState // initial state
+ b = []byte(s)
+ )
+
+ addNewline := func() {
+ buf.WriteByte('\n')
+ curWidth = 0
+ }
+
+ i := 0
+ for i < len(b) {
+ state, action := parser.Table.Transition(pstate, b[i])
+ if state == parser.Utf8State {
+ var width int
+ cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1)
+ if m == WcWidth {
+ width = runewidth.StringWidth(string(cluster))
+ }
+ i += len(cluster)
+
+ if curWidth+width > limit {
+ addNewline()
+ }
+ if !preserveSpace && curWidth == 0 && len(cluster) <= 4 {
+ // Skip spaces at the beginning of a line
+ if r, _ := utf8.DecodeRune(cluster); r != utf8.RuneError && unicode.IsSpace(r) {
+ pstate = parser.GroundState
+ continue
+ }
+ }
+
+ buf.Write(cluster)
+ curWidth += width
+ pstate = parser.GroundState
+ continue
+ }
+
+ switch action {
+ case parser.PrintAction, parser.ExecuteAction:
+ if b[i] == '\n' {
+ addNewline()
+ forceNewline = false
+ break
+ }
+
+ if curWidth+1 > limit {
+ addNewline()
+ forceNewline = true
+ }
+
+ // Skip spaces at the beginning of a line
+ if curWidth == 0 {
+ if !preserveSpace && forceNewline && unicode.IsSpace(rune(b[i])) {
+ break
+ }
+ forceNewline = false
+ }
+
+ buf.WriteByte(b[i])
+ if action == parser.PrintAction {
+ curWidth++
+ }
+ default:
+ buf.WriteByte(b[i])
+ }
+
+ // We manage the UTF8 state separately manually above.
+ if pstate != parser.Utf8State {
+ pstate = state
+ }
+ i++
+ }
+
+ return buf.String()
+}
+
+// Wordwrap wraps a string or a block of text to a given line length, not
+// breaking word boundaries. This will preserve ANSI escape codes and will
+// account for wide-characters in the string.
+// The breakpoints string is a list of characters that are considered
+// breakpoints for word wrapping. A hyphen (-) is always considered a
+// breakpoint.
+//
+// Note: breakpoints must be a string of 1-cell wide rune characters.
+//
+// This treats the text as a sequence of graphemes.
+func Wordwrap(s string, limit int, breakpoints string) string {
+ return wordwrap(GraphemeWidth, s, limit, breakpoints)
+}
+
+// WordwrapWc wraps a string or a block of text to a given line length, not
+// breaking word boundaries. This will preserve ANSI escape codes and will
+// account for wide-characters in the string.
+// The breakpoints string is a list of characters that are considered
+// breakpoints for word wrapping. A hyphen (-) is always considered a
+// breakpoint.
+//
+// Note: breakpoints must be a string of 1-cell wide rune characters.
+//
+// This treats the text as a sequence of wide characters and runes.
+func WordwrapWc(s string, limit int, breakpoints string) string {
+ return wordwrap(WcWidth, s, limit, breakpoints)
+}
+
+func wordwrap(m Method, s string, limit int, breakpoints string) string {
+ if limit < 1 {
+ return s
+ }
+
+ var (
+ cluster []byte
+ buf bytes.Buffer
+ word bytes.Buffer
+ space bytes.Buffer
+ curWidth int
+ wordLen int
+ pstate = parser.GroundState // initial state
+ b = []byte(s)
+ )
+
+ addSpace := func() {
+ curWidth += space.Len()
+ buf.Write(space.Bytes())
+ space.Reset()
+ }
+
+ addWord := func() {
+ if word.Len() == 0 {
+ return
+ }
+
+ addSpace()
+ curWidth += wordLen
+ buf.Write(word.Bytes())
+ word.Reset()
+ wordLen = 0
+ }
+
+ addNewline := func() {
+ buf.WriteByte('\n')
+ curWidth = 0
+ space.Reset()
+ }
+
+ i := 0
+ for i < len(b) {
+ state, action := parser.Table.Transition(pstate, b[i])
+ if state == parser.Utf8State {
+ var width int
+ cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1)
+ if m == WcWidth {
+ width = runewidth.StringWidth(string(cluster))
+ }
+ i += len(cluster)
+
+ r, _ := utf8.DecodeRune(cluster)
+ if r != utf8.RuneError && unicode.IsSpace(r) && r != nbsp {
+ addWord()
+ space.WriteRune(r)
+ } else if bytes.ContainsAny(cluster, breakpoints) {
+ addSpace()
+ addWord()
+ buf.Write(cluster)
+ curWidth++
+ } else {
+ word.Write(cluster)
+ wordLen += width
+ if curWidth+space.Len()+wordLen > limit &&
+ wordLen < limit {
+ addNewline()
+ }
+ }
+
+ pstate = parser.GroundState
+ continue
+ }
+
+ switch action {
+ case parser.PrintAction, parser.ExecuteAction:
+ r := rune(b[i])
+ switch {
+ case r == '\n':
+ if wordLen == 0 {
+ if curWidth+space.Len() > limit {
+ curWidth = 0
+ } else {
+ buf.Write(space.Bytes())
+ }
+ space.Reset()
+ }
+
+ addWord()
+ addNewline()
+ case unicode.IsSpace(r):
+ addWord()
+ space.WriteByte(b[i])
+ case r == '-':
+ fallthrough
+ case runeContainsAny(r, breakpoints):
+ addSpace()
+ addWord()
+ buf.WriteByte(b[i])
+ curWidth++
+ default:
+ word.WriteByte(b[i])
+ wordLen++
+ if curWidth+space.Len()+wordLen > limit &&
+ wordLen < limit {
+ addNewline()
+ }
+ }
+
+ default:
+ word.WriteByte(b[i])
+ }
+
+ // We manage the UTF8 state separately manually above.
+ if pstate != parser.Utf8State {
+ pstate = state
+ }
+ i++
+ }
+
+ addWord()
+
+ return buf.String()
+}
+
+// Wrap wraps a string or a block of text to a given line length, breaking word
+// boundaries if necessary. This will preserve ANSI escape codes and will
+// account for wide-characters in the string. The breakpoints string is a list
+// of characters that are considered breakpoints for word wrapping. A hyphen
+// (-) is always considered a breakpoint.
+//
+// Note: breakpoints must be a string of 1-cell wide rune characters.
+//
+// This treats the text as a sequence of graphemes.
+func Wrap(s string, limit int, breakpoints string) string {
+ return wrap(GraphemeWidth, s, limit, breakpoints)
+}
+
+// WrapWc wraps a string or a block of text to a given line length, breaking word
+// boundaries if necessary. This will preserve ANSI escape codes and will
+// account for wide-characters in the string. The breakpoints string is a list
+// of characters that are considered breakpoints for word wrapping. A hyphen
+// (-) is always considered a breakpoint.
+//
+// Note: breakpoints must be a string of 1-cell wide rune characters.
+//
+// This treats the text as a sequence of wide characters and runes.
+func WrapWc(s string, limit int, breakpoints string) string {
+ return wrap(WcWidth, s, limit, breakpoints)
+}
+
+func wrap(m Method, s string, limit int, breakpoints string) string {
+ if limit < 1 {
+ return s
+ }
+
+ var (
+ cluster []byte
+ buf bytes.Buffer
+ word bytes.Buffer
+ space bytes.Buffer
+ curWidth int // written width of the line
+ wordLen int // word buffer len without ANSI escape codes
+ pstate = parser.GroundState // initial state
+ b = []byte(s)
+ )
+
+ addSpace := func() {
+ curWidth += space.Len()
+ buf.Write(space.Bytes())
+ space.Reset()
+ }
+
+ addWord := func() {
+ if word.Len() == 0 {
+ return
+ }
+
+ addSpace()
+ curWidth += wordLen
+ buf.Write(word.Bytes())
+ word.Reset()
+ wordLen = 0
+ }
+
+ addNewline := func() {
+ buf.WriteByte('\n')
+ curWidth = 0
+ space.Reset()
+ }
+
+ i := 0
+ for i < len(b) {
+ state, action := parser.Table.Transition(pstate, b[i])
+ if state == parser.Utf8State {
+ var width int
+ cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1)
+ if m == WcWidth {
+ width = runewidth.StringWidth(string(cluster))
+ }
+ i += len(cluster)
+
+ r, _ := utf8.DecodeRune(cluster)
+ switch {
+ case r != utf8.RuneError && unicode.IsSpace(r) && r != nbsp: // nbsp is a non-breaking space
+ addWord()
+ space.WriteRune(r)
+ case bytes.ContainsAny(cluster, breakpoints):
+ addSpace()
+ if curWidth+wordLen+width > limit {
+ word.Write(cluster)
+ wordLen += width
+ } else {
+ addWord()
+ buf.Write(cluster)
+ curWidth += width
+ }
+ default:
+ if wordLen+width > limit {
+ // Hardwrap the word if it's too long
+ addWord()
+ }
+
+ word.Write(cluster)
+ wordLen += width
+
+ if curWidth+wordLen+space.Len() > limit {
+ addNewline()
+ }
+ }
+
+ pstate = parser.GroundState
+ continue
+ }
+
+ switch action {
+ case parser.PrintAction, parser.ExecuteAction:
+ switch r := rune(b[i]); {
+ case r == '\n':
+ if wordLen == 0 {
+ if curWidth+space.Len() > limit {
+ curWidth = 0
+ } else {
+ // preserve whitespaces
+ buf.Write(space.Bytes())
+ }
+ space.Reset()
+ }
+
+ addWord()
+ addNewline()
+ case unicode.IsSpace(r):
+ addWord()
+ space.WriteRune(r)
+ case r == '-':
+ fallthrough
+ case runeContainsAny(r, breakpoints):
+ addSpace()
+ if curWidth+wordLen >= limit {
+ // We can't fit the breakpoint in the current line, treat
+ // it as part of the word.
+ word.WriteRune(r)
+ wordLen++
+ } else {
+ addWord()
+ buf.WriteRune(r)
+ curWidth++
+ }
+ default:
+ if curWidth == limit {
+ addNewline()
+ }
+ word.WriteRune(r)
+ wordLen++
+
+ if wordLen == limit {
+ // Hardwrap the word if it's too long
+ addWord()
+ }
+
+ if curWidth+wordLen+space.Len() > limit {
+ addNewline()
+ }
+ }
+
+ default:
+ word.WriteByte(b[i])
+ }
+
+ // We manage the UTF8 state separately manually above.
+ if pstate != parser.Utf8State {
+ pstate = state
+ }
+ i++
+ }
+
+ if wordLen == 0 {
+ if curWidth+space.Len() > limit {
+ curWidth = 0
+ } else {
+ // preserve whitespaces
+ buf.Write(space.Bytes())
+ }
+ space.Reset()
+ }
+
+ addWord()
+
+ return buf.String()
+}
+
+func runeContainsAny(r rune, s string) bool {
+ for _, c := range s {
+ if c == r {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/xterm.go b/vendor/github.com/charmbracelet/x/ansi/xterm.go
new file mode 100644
index 0000000..83fd4bd
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/xterm.go
@@ -0,0 +1,138 @@
+package ansi
+
+import "strconv"
+
+// KeyModifierOptions (XTMODKEYS) sets/resets xterm key modifier options.
+//
+// Default is 0.
+//
+// CSI > Pp m
+// CSI > Pp ; Pv m
+//
+// If Pv is omitted, the resource is reset to its initial value.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_
+func KeyModifierOptions(p int, vs ...int) string {
+ var pp, pv string
+ if p > 0 {
+ pp = strconv.Itoa(p)
+ }
+
+ if len(vs) == 0 {
+ return "\x1b[>" + strconv.Itoa(p) + "m"
+ }
+
+ v := vs[0]
+ if v > 0 {
+ pv = strconv.Itoa(v)
+ return "\x1b[>" + pp + ";" + pv + "m"
+ }
+
+ return "\x1b[>" + pp + "m"
+}
+
+// XTMODKEYS is an alias for [KeyModifierOptions].
+func XTMODKEYS(p int, vs ...int) string {
+ return KeyModifierOptions(p, vs...)
+}
+
+// SetKeyModifierOptions sets xterm key modifier options.
+// This is an alias for [KeyModifierOptions].
+func SetKeyModifierOptions(pp int, pv int) string {
+ return KeyModifierOptions(pp, pv)
+}
+
+// ResetKeyModifierOptions resets xterm key modifier options.
+// This is an alias for [KeyModifierOptions].
+func ResetKeyModifierOptions(pp int) string {
+ return KeyModifierOptions(pp)
+}
+
+// QueryKeyModifierOptions (XTQMODKEYS) requests xterm key modifier options.
+//
+// Default is 0.
+//
+// CSI ? Pp m
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_
+func QueryKeyModifierOptions(pp int) string {
+ var p string
+ if pp > 0 {
+ p = strconv.Itoa(pp)
+ }
+ return "\x1b[?" + p + "m"
+}
+
+// XTQMODKEYS is an alias for [QueryKeyModifierOptions].
+func XTQMODKEYS(pp int) string {
+ return QueryKeyModifierOptions(pp)
+}
+
+// Modify Other Keys (modifyOtherKeys) is an xterm feature that allows the
+// terminal to modify the behavior of certain keys to send different escape
+// sequences when pressed.
+//
+// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys
+const (
+ SetModifyOtherKeys1 = "\x1b[>4;1m"
+ SetModifyOtherKeys2 = "\x1b[>4;2m"
+ ResetModifyOtherKeys = "\x1b[>4m"
+ QueryModifyOtherKeys = "\x1b[?4m"
+)
+
+// ModifyOtherKeys returns a sequence that sets XTerm modifyOtherKeys mode.
+// The mode argument specifies the mode to set.
+//
+// 0: Disable modifyOtherKeys mode.
+// 1: Enable modifyOtherKeys mode 1.
+// 2: Enable modifyOtherKeys mode 2.
+//
+// CSI > 4 ; mode m
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_
+// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys
+//
+// Deprecated: use [SetModifyOtherKeys1] or [SetModifyOtherKeys2] instead.
+func ModifyOtherKeys(mode int) string {
+ return "\x1b[>4;" + strconv.Itoa(mode) + "m"
+}
+
+// DisableModifyOtherKeys disables the modifyOtherKeys mode.
+//
+// CSI > 4 ; 0 m
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_
+// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys
+//
+// Deprecated: use [ResetModifyOtherKeys] instead.
+const DisableModifyOtherKeys = "\x1b[>4;0m"
+
+// EnableModifyOtherKeys1 enables the modifyOtherKeys mode 1.
+//
+// CSI > 4 ; 1 m
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_
+// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys
+//
+// Deprecated: use [SetModifyOtherKeys1] instead.
+const EnableModifyOtherKeys1 = "\x1b[>4;1m"
+
+// EnableModifyOtherKeys2 enables the modifyOtherKeys mode 2.
+//
+// CSI > 4 ; 2 m
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_
+// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys
+//
+// Deprecated: use [SetModifyOtherKeys2] instead.
+const EnableModifyOtherKeys2 = "\x1b[>4;2m"
+
+// RequestModifyOtherKeys requests the modifyOtherKeys mode.
+//
+// CSI ? 4 m
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_
+// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys
+//
+// Deprecated: use [QueryModifyOtherKeys] instead.
+const RequestModifyOtherKeys = "\x1b[?4m"
diff --git a/vendor/github.com/charmbracelet/x/term/LICENSE b/vendor/github.com/charmbracelet/x/term/LICENSE
new file mode 100644
index 0000000..65a5654
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 Charmbracelet, Inc.
+
+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/vendor/github.com/charmbracelet/x/term/term.go b/vendor/github.com/charmbracelet/x/term/term.go
new file mode 100644
index 0000000..58d6522
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term.go
@@ -0,0 +1,49 @@
+package term
+
+// State contains platform-specific state of a terminal.
+type State struct {
+ state
+}
+
+// IsTerminal returns whether the given file descriptor is a terminal.
+func IsTerminal(fd uintptr) bool {
+ return isTerminal(fd)
+}
+
+// MakeRaw puts the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+func MakeRaw(fd uintptr) (*State, error) {
+ return makeRaw(fd)
+}
+
+// GetState returns the current state of a terminal which may be useful to
+// restore the terminal after a signal.
+func GetState(fd uintptr) (*State, error) {
+ return getState(fd)
+}
+
+// SetState sets the given state of the terminal.
+func SetState(fd uintptr, state *State) error {
+ return setState(fd, state)
+}
+
+// Restore restores the terminal connected to the given file descriptor to a
+// previous state.
+func Restore(fd uintptr, oldState *State) error {
+ return restore(fd, oldState)
+}
+
+// GetSize returns the visible dimensions of the given terminal.
+//
+// These dimensions don't include any scrollback buffer height.
+func GetSize(fd uintptr) (width, height int, err error) {
+ return getSize(fd)
+}
+
+// ReadPassword reads a line of input from a terminal without local echo. This
+// is commonly used for inputting passwords and other sensitive data. The slice
+// returned does not include the \n.
+func ReadPassword(fd uintptr) ([]byte, error) {
+ return readPassword(fd)
+}
diff --git a/vendor/github.com/charmbracelet/x/term/term_other.go b/vendor/github.com/charmbracelet/x/term/term_other.go
new file mode 100644
index 0000000..092c7e9
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term_other.go
@@ -0,0 +1,39 @@
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !zos && !windows && !solaris && !plan9
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!zos,!windows,!solaris,!plan9
+
+package term
+
+import (
+ "fmt"
+ "runtime"
+)
+
+type state struct{}
+
+func isTerminal(fd uintptr) bool {
+ return false
+}
+
+func makeRaw(fd uintptr) (*State, error) {
+ return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func getState(fd uintptr) (*State, error) {
+ return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func restore(fd uintptr, state *State) error {
+ return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func getSize(fd uintptr) (width, height int, err error) {
+ return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func setState(fd uintptr, state *State) error {
+ return fmt.Errorf("terminal: SetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func readPassword(fd uintptr) ([]byte, error) {
+ return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
diff --git a/vendor/github.com/charmbracelet/x/term/term_unix.go b/vendor/github.com/charmbracelet/x/term/term_unix.go
new file mode 100644
index 0000000..1459cb1
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term_unix.go
@@ -0,0 +1,96 @@
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
+
+package term
+
+import (
+ "golang.org/x/sys/unix"
+)
+
+type state struct {
+ unix.Termios
+}
+
+func isTerminal(fd uintptr) bool {
+ _, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios)
+ return err == nil
+}
+
+func makeRaw(fd uintptr) (*State, error) {
+ termios, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios)
+ if err != nil {
+ return nil, err
+ }
+
+ oldState := State{state{Termios: *termios}}
+
+ // This attempts to replicate the behaviour documented for cfmakeraw in
+ // the termios(3) manpage.
+ termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON
+ termios.Oflag &^= unix.OPOST
+ termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN
+ termios.Cflag &^= unix.CSIZE | unix.PARENB
+ termios.Cflag |= unix.CS8
+ termios.Cc[unix.VMIN] = 1
+ termios.Cc[unix.VTIME] = 0
+ if err := unix.IoctlSetTermios(int(fd), ioctlWriteTermios, termios); err != nil {
+ return nil, err
+ }
+
+ return &oldState, nil
+}
+
+func setState(fd uintptr, state *State) error {
+ var termios *unix.Termios
+ if state != nil {
+ termios = &state.Termios
+ }
+ return unix.IoctlSetTermios(int(fd), ioctlWriteTermios, termios)
+}
+
+func getState(fd uintptr) (*State, error) {
+ termios, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios)
+ if err != nil {
+ return nil, err
+ }
+
+ return &State{state{Termios: *termios}}, nil
+}
+
+func restore(fd uintptr, state *State) error {
+ return unix.IoctlSetTermios(int(fd), ioctlWriteTermios, &state.Termios)
+}
+
+func getSize(fd uintptr) (width, height int, err error) {
+ ws, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ)
+ if err != nil {
+ return 0, 0, err
+ }
+ return int(ws.Col), int(ws.Row), nil
+}
+
+// passwordReader is an io.Reader that reads from a specific file descriptor.
+type passwordReader int
+
+func (r passwordReader) Read(buf []byte) (int, error) {
+ return unix.Read(int(r), buf)
+}
+
+func readPassword(fd uintptr) ([]byte, error) {
+ termios, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios)
+ if err != nil {
+ return nil, err
+ }
+
+ newState := *termios
+ newState.Lflag &^= unix.ECHO
+ newState.Lflag |= unix.ICANON | unix.ISIG
+ newState.Iflag |= unix.ICRNL
+ if err := unix.IoctlSetTermios(int(fd), ioctlWriteTermios, &newState); err != nil {
+ return nil, err
+ }
+
+ defer unix.IoctlSetTermios(int(fd), ioctlWriteTermios, termios)
+
+ return readPasswordLine(passwordReader(fd))
+}
diff --git a/vendor/github.com/charmbracelet/x/term/term_unix_bsd.go b/vendor/github.com/charmbracelet/x/term/term_unix_bsd.go
new file mode 100644
index 0000000..b435031
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term_unix_bsd.go
@@ -0,0 +1,11 @@
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package term
+
+import "golang.org/x/sys/unix"
+
+const (
+ ioctlReadTermios = unix.TIOCGETA
+ ioctlWriteTermios = unix.TIOCSETA
+)
diff --git a/vendor/github.com/charmbracelet/x/term/term_unix_other.go b/vendor/github.com/charmbracelet/x/term/term_unix_other.go
new file mode 100644
index 0000000..ee2a29e
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term_unix_other.go
@@ -0,0 +1,11 @@
+//go:build aix || linux || solaris || zos
+// +build aix linux solaris zos
+
+package term
+
+import "golang.org/x/sys/unix"
+
+const (
+ ioctlReadTermios = unix.TCGETS
+ ioctlWriteTermios = unix.TCSETS
+)
diff --git a/vendor/github.com/charmbracelet/x/term/term_windows.go b/vendor/github.com/charmbracelet/x/term/term_windows.go
new file mode 100644
index 0000000..fe7afde
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term_windows.go
@@ -0,0 +1,87 @@
+//go:build windows
+// +build windows
+
+package term
+
+import (
+ "os"
+
+ "golang.org/x/sys/windows"
+)
+
+type state struct {
+ Mode uint32
+}
+
+func isTerminal(fd uintptr) bool {
+ var st uint32
+ err := windows.GetConsoleMode(windows.Handle(fd), &st)
+ return err == nil
+}
+
+func makeRaw(fd uintptr) (*State, error) {
+ var st uint32
+ if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
+ return nil, err
+ }
+ raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT)
+ raw |= windows.ENABLE_VIRTUAL_TERMINAL_INPUT
+ if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil {
+ return nil, err
+ }
+ return &State{state{st}}, nil
+}
+
+func setState(fd uintptr, state *State) error {
+ var mode uint32
+ if state != nil {
+ mode = state.Mode
+ }
+ return windows.SetConsoleMode(windows.Handle(fd), mode)
+}
+
+func getState(fd uintptr) (*State, error) {
+ var st uint32
+ if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
+ return nil, err
+ }
+ return &State{state{st}}, nil
+}
+
+func restore(fd uintptr, state *State) error {
+ return windows.SetConsoleMode(windows.Handle(fd), state.Mode)
+}
+
+func getSize(fd uintptr) (width, height int, err error) {
+ var info windows.ConsoleScreenBufferInfo
+ if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil {
+ return 0, 0, err
+ }
+ return int(info.Window.Right - info.Window.Left + 1), int(info.Window.Bottom - info.Window.Top + 1), nil
+}
+
+func readPassword(fd uintptr) ([]byte, error) {
+ var st uint32
+ if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
+ return nil, err
+ }
+ old := st
+
+ st &^= (windows.ENABLE_ECHO_INPUT | windows.ENABLE_LINE_INPUT)
+ st |= (windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_PROCESSED_INPUT)
+ if err := windows.SetConsoleMode(windows.Handle(fd), st); err != nil {
+ return nil, err
+ }
+
+ defer windows.SetConsoleMode(windows.Handle(fd), old)
+
+ var h windows.Handle
+ p, _ := windows.GetCurrentProcess()
+ if err := windows.DuplicateHandle(p, windows.Handle(fd), p, &h, 0, false, windows.DUPLICATE_SAME_ACCESS); err != nil {
+ return nil, err
+ }
+
+ f := os.NewFile(uintptr(h), "stdin")
+ defer f.Close()
+ return readPasswordLine(f)
+}
diff --git a/vendor/github.com/charmbracelet/x/term/terminal.go b/vendor/github.com/charmbracelet/x/term/terminal.go
new file mode 100644
index 0000000..8963163
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/terminal.go
@@ -0,0 +1,12 @@
+package term
+
+import (
+ "io"
+)
+
+// File represents a file that has a file descriptor and can be read from,
+// written to, and closed.
+type File interface {
+ io.ReadWriteCloser
+ Fd() uintptr
+}
diff --git a/vendor/github.com/charmbracelet/x/term/util.go b/vendor/github.com/charmbracelet/x/term/util.go
new file mode 100644
index 0000000..b731341
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/util.go
@@ -0,0 +1,47 @@
+package term
+
+import (
+ "io"
+ "runtime"
+)
+
+// readPasswordLine reads from reader until it finds \n or io.EOF.
+// The slice returned does not include the \n.
+// readPasswordLine also ignores any \r it finds.
+// Windows uses \r as end of line. So, on Windows, readPasswordLine
+// reads until it finds \r and ignores any \n it finds during processing.
+func readPasswordLine(reader io.Reader) ([]byte, error) {
+ var buf [1]byte
+ var ret []byte
+
+ for {
+ n, err := reader.Read(buf[:])
+ if n > 0 {
+ switch buf[0] {
+ case '\b':
+ if len(ret) > 0 {
+ ret = ret[:len(ret)-1]
+ }
+ case '\n':
+ if runtime.GOOS != "windows" {
+ return ret, nil
+ }
+ // otherwise ignore \n
+ case '\r':
+ if runtime.GOOS == "windows" {
+ return ret, nil
+ }
+ // otherwise ignore \r
+ default:
+ ret = append(ret, buf[0])
+ }
+ continue
+ }
+ if err != nil {
+ if err == io.EOF && len(ret) > 0 {
+ return ret, nil
+ }
+ return ret, err
+ }
+ }
+}
diff --git a/vendor/github.com/dlclark/regexp2/.gitignore b/vendor/github.com/dlclark/regexp2/.gitignore
new file mode 100644
index 0000000..fb844c3
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/.gitignore
@@ -0,0 +1,27 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+*.test
+*.prof
+*.out
+
+.DS_Store
diff --git a/vendor/github.com/dlclark/regexp2/.travis.yml b/vendor/github.com/dlclark/regexp2/.travis.yml
new file mode 100644
index 0000000..a2da6be
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/.travis.yml
@@ -0,0 +1,7 @@
+language: go
+arch:
+ - AMD64
+ - ppc64le
+go:
+ - 1.9
+ - tip
diff --git a/vendor/github.com/dlclark/regexp2/ATTRIB b/vendor/github.com/dlclark/regexp2/ATTRIB
new file mode 100644
index 0000000..cdf4560
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/ATTRIB
@@ -0,0 +1,133 @@
+============
+These pieces of code were ported from dotnet/corefx:
+
+syntax/charclass.go (from RegexCharClass.cs): ported to use the built-in Go unicode classes. Canonicalize is
+ a direct port, but most of the other code required large changes because the C# implementation
+ used a string to represent the CharSet data structure and I cleaned that up in my implementation.
+
+syntax/code.go (from RegexCode.cs): ported literally with various cleanups and layout to make it more Go-ish.
+
+syntax/escape.go (from RegexParser.cs): ported Escape method and added some optimizations. Unescape is inspired by
+ the C# implementation but couldn't be directly ported because of the lack of do-while syntax in Go.
+
+syntax/parser.go (from RegexpParser.cs and RegexOptions.cs): ported parser struct and associated methods as
+ literally as possible. Several language differences required changes. E.g. lack pre/post-fix increments as
+ expressions, lack of do-while loops, lack of overloads, etc.
+
+syntax/prefix.go (from RegexFCD.cs and RegexBoyerMoore.cs): ported as literally as possible and added support
+ for unicode chars that are longer than the 16-bit char in C# for the 32-bit rune in Go.
+
+syntax/replacerdata.go (from RegexReplacement.cs): conceptually ported and re-organized to handle differences
+ in charclass implementation, and fix odd code layout between RegexParser.cs, Regex.cs, and RegexReplacement.cs.
+
+syntax/tree.go (from RegexTree.cs and RegexNode.cs): ported literally as possible.
+
+syntax/writer.go (from RegexWriter.cs): ported literally with minor changes to make it more Go-ish.
+
+match.go (from RegexMatch.cs): ported, simplified, and changed to handle Go's lack of inheritence.
+
+regexp.go (from Regex.cs and RegexOptions.cs): conceptually serves the same "starting point", but is simplified
+ and changed to handle differences in C# strings and Go strings/runes.
+
+replace.go (from RegexReplacement.cs): ported closely and then cleaned up to combine the MatchEvaluator and
+ simple string replace implementations.
+
+runner.go (from RegexRunner.cs): ported literally as possible.
+
+regexp_test.go (from CaptureTests.cs and GroupNamesAndNumbers.cs): conceptually ported, but the code was
+ manually structured like Go tests.
+
+replace_test.go (from RegexReplaceStringTest0.cs): conceptually ported
+
+rtl_test.go (from RightToLeft.cs): conceptually ported
+---
+dotnet/corefx was released under this license:
+
+The MIT License (MIT)
+
+Copyright (c) Microsoft Corporation
+
+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.
+
+============
+These pieces of code are copied from the Go framework:
+
+- The overall directory structure of regexp2 was inspired by the Go runtime regexp package.
+- The optimization in the escape method of syntax/escape.go is from the Go runtime QuoteMeta() func in regexp/regexp.go
+- The method signatures in regexp.go are designed to match the Go framework regexp methods closely
+- func regexp2.MustCompile and func quote are almost identifical to the regexp package versions
+- BenchmarkMatch* and TestProgramTooLong* funcs in regexp_performance_test.go were copied from the framework
+ regexp/exec_test.go
+---
+The Go framework was released under this license:
+
+Copyright (c) 2012 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+============
+Some test data were gathered from the Mono project.
+
+regexp_mono_test.go: ported from https://github.com/mono/mono/blob/master/mcs/class/System/Test/System.Text.RegularExpressions/PerlTrials.cs
+---
+Mono tests released under this license:
+
+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/vendor/github.com/dlclark/regexp2/LICENSE b/vendor/github.com/dlclark/regexp2/LICENSE
new file mode 100644
index 0000000..fe83dfd
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) Doug Clark
+
+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/vendor/github.com/dlclark/regexp2/README.md b/vendor/github.com/dlclark/regexp2/README.md
new file mode 100644
index 0000000..9cbc1d8
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/README.md
@@ -0,0 +1,174 @@
+# regexp2 - full featured regular expressions for Go
+Regexp2 is a feature-rich RegExp engine for Go. It doesn't have constant time guarantees like the built-in `regexp` package, but it allows backtracking and is compatible with Perl5 and .NET. You'll likely be better off with the RE2 engine from the `regexp` package and should only use this if you need to write very complex patterns or require compatibility with .NET.
+
+## Basis of the engine
+The engine is ported from the .NET framework's System.Text.RegularExpressions.Regex engine. That engine was open sourced in 2015 under the MIT license. There are some fundamental differences between .NET strings and Go strings that required a bit of borrowing from the Go framework regex engine as well. I cleaned up a couple of the dirtier bits during the port (regexcharclass.cs was terrible), but the parse tree, code emmitted, and therefore patterns matched should be identical.
+
+## New Code Generation
+For extra performance use `regexp2` with [`regexp2cg`](https://github.com/dlclark/regexp2cg). It is a code generation utility for `regexp2` and you can likely improve your regexp runtime performance by 3-10x in hot code paths. As always you should benchmark your specifics to confirm the results. Give it a try!
+
+## Installing
+This is a go-gettable library, so install is easy:
+
+ go get github.com/dlclark/regexp2
+
+To use the new Code Generation (while it's in beta) you'll need to use the `code_gen` branch:
+
+ go get github.com/dlclark/regexp2@code_gen
+
+## Usage
+Usage is similar to the Go `regexp` package. Just like in `regexp`, you start by converting a regex into a state machine via the `Compile` or `MustCompile` methods. They ultimately do the same thing, but `MustCompile` will panic if the regex is invalid. You can then use the provided `Regexp` struct to find matches repeatedly. A `Regexp` struct is safe to use across goroutines.
+
+```go
+re := regexp2.MustCompile(`Your pattern`, 0)
+if isMatch, _ := re.MatchString(`Something to match`); isMatch {
+ //do something
+}
+```
+
+The only error that the `*Match*` methods *should* return is a Timeout if you set the `re.MatchTimeout` field. Any other error is a bug in the `regexp2` package. If you need more details about capture groups in a match then use the `FindStringMatch` method, like so:
+
+```go
+if m, _ := re.FindStringMatch(`Something to match`); m != nil {
+ // the whole match is always group 0
+ fmt.Printf("Group 0: %v\n", m.String())
+
+ // you can get all the groups too
+ gps := m.Groups()
+
+ // a group can be captured multiple times, so each cap is separately addressable
+ fmt.Printf("Group 1, first capture", gps[1].Captures[0].String())
+ fmt.Printf("Group 1, second capture", gps[1].Captures[1].String())
+}
+```
+
+Group 0 is embedded in the Match. Group 0 is an automatically-assigned group that encompasses the whole pattern. This means that `m.String()` is the same as `m.Group.String()` and `m.Groups()[0].String()`
+
+The __last__ capture is embedded in each group, so `g.String()` will return the same thing as `g.Capture.String()` and `g.Captures[len(g.Captures)-1].String()`.
+
+If you want to find multiple matches from a single input string you should use the `FindNextMatch` method. For example, to implement a function similar to `regexp.FindAllString`:
+
+```go
+func regexp2FindAllString(re *regexp2.Regexp, s string) []string {
+ var matches []string
+ m, _ := re.FindStringMatch(s)
+ for m != nil {
+ matches = append(matches, m.String())
+ m, _ = re.FindNextMatch(m)
+ }
+ return matches
+}
+```
+
+`FindNextMatch` is optmized so that it re-uses the underlying string/rune slice.
+
+The internals of `regexp2` always operate on `[]rune` so `Index` and `Length` data in a `Match` always reference a position in `rune`s rather than `byte`s (even if the input was given as a string). This is a dramatic difference between `regexp` and `regexp2`. It's advisable to use the provided `String()` methods to avoid having to work with indices.
+
+## Compare `regexp` and `regexp2`
+| Category | regexp | regexp2 |
+| --- | --- | --- |
+| Catastrophic backtracking possible | no, constant execution time guarantees | yes, if your pattern is at risk you can use the `re.MatchTimeout` field |
+| Python-style capture groups `(?Pre)` | yes | no (yes in RE2 compat mode) |
+| .NET-style capture groups `(?re)` or `(?'name're)` | no | yes |
+| comments `(?#comment)` | no | yes |
+| branch numbering reset `(?\|a\|b)` | no | no |
+| possessive match `(?>re)` | no | yes |
+| positive lookahead `(?=re)` | no | yes |
+| negative lookahead `(?!re)` | no | yes |
+| positive lookbehind `(?<=re)` | no | yes |
+| negative lookbehind `(?re)`)
+* change singleline behavior for `$` to only match end of string (like RE2) (see [#24](https://github.com/dlclark/regexp2/issues/24))
+* change the character classes `\d` `\s` and `\w` to match the same characters as RE2. NOTE: if you also use the `ECMAScript` option then this will change the `\s` character class to match ECMAScript instead of RE2. ECMAScript allows more whitespace characters in `\s` than RE2 (but still fewer than the the default behavior).
+* allow character escape sequences to have defaults. For example, by default `\_` isn't a known character escape and will fail to compile, but in RE2 mode it will match the literal character `_`
+
+```go
+re := regexp2.MustCompile(`Your RE2-compatible pattern`, regexp2.RE2)
+if isMatch, _ := re.MatchString(`Something to match`); isMatch {
+ //do something
+}
+```
+
+This feature is a work in progress and I'm open to ideas for more things to put here (maybe more relaxed character escaping rules?).
+
+## Catastrophic Backtracking and Timeouts
+
+`regexp2` supports features that can lead to catastrophic backtracking.
+`Regexp.MatchTimeout` can be set to to limit the impact of such behavior; the
+match will fail with an error after approximately MatchTimeout. No timeout
+checks are done by default.
+
+Timeout checking is not free. The current timeout checking implementation starts
+a background worker that updates a clock value approximately once every 100
+milliseconds. The matching code compares this value against the precomputed
+deadline for the match. The performance impact is as follows.
+
+1. A match with a timeout runs almost as fast as a match without a timeout.
+2. If any live matches have a timeout, there will be a background CPU load
+ (`~0.15%` currently on a modern machine). This load will remain constant
+ regardless of the number of matches done including matches done in parallel.
+3. If no live matches are using a timeout, the background load will remain
+ until the longest deadline (match timeout + the time when the match started)
+ is reached. E.g., if you set a timeout of one minute the load will persist
+ for approximately a minute even if the match finishes quickly.
+
+See [PR #58](https://github.com/dlclark/regexp2/pull/58) for more details and
+alternatives considered.
+
+## Goroutine leak error
+If you're using a library during unit tests (e.g. https://github.com/uber-go/goleak) that validates all goroutines are exited then you'll likely get an error if you or any of your dependencies use regex's with a MatchTimeout.
+To remedy the problem you'll need to tell the unit test to wait until the backgroup timeout goroutine is exited.
+
+```go
+func TestSomething(t *testing.T) {
+ defer goleak.VerifyNone(t)
+ defer regexp2.StopTimeoutClock()
+
+ // ... test
+}
+
+//or
+
+func TestMain(m *testing.M) {
+ // setup
+ // ...
+
+ // run
+ m.Run()
+
+ //tear down
+ regexp2.StopTimeoutClock()
+ goleak.VerifyNone(t)
+}
+```
+
+This will add ~100ms runtime to each test (or TestMain). If that's too much time you can set the clock cycle rate of the timeout goroutine in an init function in a test file. `regexp2.SetTimeoutCheckPeriod` isn't threadsafe so it must be setup before starting any regex's with Timeouts.
+
+```go
+func init() {
+ //speed up testing by making the timeout clock 1ms
+ regexp2.SetTimeoutCheckPeriod(time.Millisecond)
+}
+```
+
+## ECMAScript compatibility mode
+In this mode the engine provides compatibility with the [regex engine](https://tc39.es/ecma262/multipage/text-processing.html#sec-regexp-regular-expression-objects) described in the ECMAScript specification.
+
+Additionally a Unicode mode is provided which allows parsing of `\u{CodePoint}` syntax that is only when both are provided.
+
+## Library features that I'm still working on
+- Regex split
+
+## Potential bugs
+I've run a battery of tests against regexp2 from various sources and found the debug output matches the .NET engine, but .NET and Go handle strings very differently. I've attempted to handle these differences, but most of my testing deals with basic ASCII with a little bit of multi-byte Unicode. There's a chance that there are bugs in the string handling related to character sets with supplementary Unicode chars. Right-to-Left support is coded, but not well tested either.
+
+## Find a bug?
+I'm open to new issues and pull requests with tests if you find something odd!
diff --git a/vendor/github.com/dlclark/regexp2/fastclock.go b/vendor/github.com/dlclark/regexp2/fastclock.go
new file mode 100644
index 0000000..caf2c9d
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/fastclock.go
@@ -0,0 +1,129 @@
+package regexp2
+
+import (
+ "sync"
+ "sync/atomic"
+ "time"
+)
+
+// fasttime holds a time value (ticks since clock initialization)
+type fasttime int64
+
+// fastclock provides a fast clock implementation.
+//
+// A background goroutine periodically stores the current time
+// into an atomic variable.
+//
+// A deadline can be quickly checked for expiration by comparing
+// its value to the clock stored in the atomic variable.
+//
+// The goroutine automatically stops once clockEnd is reached.
+// (clockEnd covers the largest deadline seen so far + some
+// extra time). This ensures that if regexp2 with timeouts
+// stops being used we will stop background work.
+type fastclock struct {
+ // instances of atomicTime must be at the start of the struct (or at least 64-bit aligned)
+ // otherwise 32-bit architectures will panic
+
+ current atomicTime // Current time (approximate)
+ clockEnd atomicTime // When clock updater is supposed to stop (>= any existing deadline)
+
+ // current and clockEnd can be read via atomic loads.
+ // Reads and writes of other fields require mu to be held.
+ mu sync.Mutex
+ start time.Time // Time corresponding to fasttime(0)
+ running bool // Is a clock updater running?
+}
+
+var fast fastclock
+
+// reached returns true if current time is at or past t.
+func (t fasttime) reached() bool {
+ return fast.current.read() >= t
+}
+
+// makeDeadline returns a time that is approximately time.Now().Add(d)
+func makeDeadline(d time.Duration) fasttime {
+ // Increase the deadline since the clock we are reading may be
+ // just about to tick forwards.
+ end := fast.current.read() + durationToTicks(d+clockPeriod)
+
+ // Start or extend clock if necessary.
+ if end > fast.clockEnd.read() {
+ extendClock(end)
+ }
+ return end
+}
+
+// extendClock ensures that clock is live and will run until at least end.
+func extendClock(end fasttime) {
+ fast.mu.Lock()
+ defer fast.mu.Unlock()
+
+ if fast.start.IsZero() {
+ fast.start = time.Now()
+ }
+
+ // Extend the running time to cover end as well as a bit of slop.
+ if shutdown := end + durationToTicks(time.Second); shutdown > fast.clockEnd.read() {
+ fast.clockEnd.write(shutdown)
+ }
+
+ // Start clock if necessary
+ if !fast.running {
+ fast.running = true
+ go runClock()
+ }
+}
+
+// stop the timeout clock in the background
+// should only used for unit tests to abandon the background goroutine
+func stopClock() {
+ fast.mu.Lock()
+ if fast.running {
+ fast.clockEnd.write(fasttime(0))
+ }
+ fast.mu.Unlock()
+
+ // pause until not running
+ // get and release the lock
+ isRunning := true
+ for isRunning {
+ time.Sleep(clockPeriod / 2)
+ fast.mu.Lock()
+ isRunning = fast.running
+ fast.mu.Unlock()
+ }
+}
+
+func durationToTicks(d time.Duration) fasttime {
+ // Downscale nanoseconds to approximately a millisecond so that we can avoid
+ // overflow even if the caller passes in math.MaxInt64.
+ return fasttime(d) >> 20
+}
+
+const DefaultClockPeriod = 100 * time.Millisecond
+
+// clockPeriod is the approximate interval between updates of approximateClock.
+var clockPeriod = DefaultClockPeriod
+
+func runClock() {
+ fast.mu.Lock()
+ defer fast.mu.Unlock()
+
+ for fast.current.read() <= fast.clockEnd.read() {
+ // Unlock while sleeping.
+ fast.mu.Unlock()
+ time.Sleep(clockPeriod)
+ fast.mu.Lock()
+
+ newTime := durationToTicks(time.Since(fast.start))
+ fast.current.write(newTime)
+ }
+ fast.running = false
+}
+
+type atomicTime struct{ v int64 } // Should change to atomic.Int64 when we can use go 1.19
+
+func (t *atomicTime) read() fasttime { return fasttime(atomic.LoadInt64(&t.v)) }
+func (t *atomicTime) write(v fasttime) { atomic.StoreInt64(&t.v, int64(v)) }
diff --git a/vendor/github.com/dlclark/regexp2/match.go b/vendor/github.com/dlclark/regexp2/match.go
new file mode 100644
index 0000000..759cf8c
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/match.go
@@ -0,0 +1,349 @@
+package regexp2
+
+import (
+ "bytes"
+ "fmt"
+)
+
+// Match is a single regex result match that contains groups and repeated captures
+//
+// -Groups
+// -Capture
+type Match struct {
+ Group //embeded group 0
+
+ regex *Regexp
+ otherGroups []Group
+
+ // input to the match
+ textpos int
+ textstart int
+
+ capcount int
+ caps []int
+ sparseCaps map[int]int
+
+ // output from the match
+ matches [][]int
+ matchcount []int
+
+ // whether we've done any balancing with this match. If we
+ // have done balancing, we'll need to do extra work in Tidy().
+ balancing bool
+}
+
+// Group is an explicit or implit (group 0) matched group within the pattern
+type Group struct {
+ Capture // the last capture of this group is embeded for ease of use
+
+ Name string // group name
+ Captures []Capture // captures of this group
+}
+
+// Capture is a single capture of text within the larger original string
+type Capture struct {
+ // the original string
+ text []rune
+ // Index is the position in the underlying rune slice where the first character of
+ // captured substring was found. Even if you pass in a string this will be in Runes.
+ Index int
+ // Length is the number of runes in the captured substring.
+ Length int
+}
+
+// String returns the captured text as a String
+func (c *Capture) String() string {
+ return string(c.text[c.Index : c.Index+c.Length])
+}
+
+// Runes returns the captured text as a rune slice
+func (c *Capture) Runes() []rune {
+ return c.text[c.Index : c.Index+c.Length]
+}
+
+func newMatch(regex *Regexp, capcount int, text []rune, startpos int) *Match {
+ m := Match{
+ regex: regex,
+ matchcount: make([]int, capcount),
+ matches: make([][]int, capcount),
+ textstart: startpos,
+ balancing: false,
+ }
+ m.Name = "0"
+ m.text = text
+ m.matches[0] = make([]int, 2)
+ return &m
+}
+
+func newMatchSparse(regex *Regexp, caps map[int]int, capcount int, text []rune, startpos int) *Match {
+ m := newMatch(regex, capcount, text, startpos)
+ m.sparseCaps = caps
+ return m
+}
+
+func (m *Match) reset(text []rune, textstart int) {
+ m.text = text
+ m.textstart = textstart
+ for i := 0; i < len(m.matchcount); i++ {
+ m.matchcount[i] = 0
+ }
+ m.balancing = false
+}
+
+func (m *Match) tidy(textpos int) {
+
+ interval := m.matches[0]
+ m.Index = interval[0]
+ m.Length = interval[1]
+ m.textpos = textpos
+ m.capcount = m.matchcount[0]
+ //copy our root capture to the list
+ m.Group.Captures = []Capture{m.Group.Capture}
+
+ if m.balancing {
+ // The idea here is that we want to compact all of our unbalanced captures. To do that we
+ // use j basically as a count of how many unbalanced captures we have at any given time
+ // (really j is an index, but j/2 is the count). First we skip past all of the real captures
+ // until we find a balance captures. Then we check each subsequent entry. If it's a balance
+ // capture (it's negative), we decrement j. If it's a real capture, we increment j and copy
+ // it down to the last free position.
+ for cap := 0; cap < len(m.matchcount); cap++ {
+ limit := m.matchcount[cap] * 2
+ matcharray := m.matches[cap]
+
+ var i, j int
+
+ for i = 0; i < limit; i++ {
+ if matcharray[i] < 0 {
+ break
+ }
+ }
+
+ for j = i; i < limit; i++ {
+ if matcharray[i] < 0 {
+ // skip negative values
+ j--
+ } else {
+ // but if we find something positive (an actual capture), copy it back to the last
+ // unbalanced position.
+ if i != j {
+ matcharray[j] = matcharray[i]
+ }
+ j++
+ }
+ }
+
+ m.matchcount[cap] = j / 2
+ }
+
+ m.balancing = false
+ }
+}
+
+// isMatched tells if a group was matched by capnum
+func (m *Match) isMatched(cap int) bool {
+ return cap < len(m.matchcount) && m.matchcount[cap] > 0 && m.matches[cap][m.matchcount[cap]*2-1] != (-3+1)
+}
+
+// matchIndex returns the index of the last specified matched group by capnum
+func (m *Match) matchIndex(cap int) int {
+ i := m.matches[cap][m.matchcount[cap]*2-2]
+ if i >= 0 {
+ return i
+ }
+
+ return m.matches[cap][-3-i]
+}
+
+// matchLength returns the length of the last specified matched group by capnum
+func (m *Match) matchLength(cap int) int {
+ i := m.matches[cap][m.matchcount[cap]*2-1]
+ if i >= 0 {
+ return i
+ }
+
+ return m.matches[cap][-3-i]
+}
+
+// Nonpublic builder: add a capture to the group specified by "c"
+func (m *Match) addMatch(c, start, l int) {
+
+ if m.matches[c] == nil {
+ m.matches[c] = make([]int, 2)
+ }
+
+ capcount := m.matchcount[c]
+
+ if capcount*2+2 > len(m.matches[c]) {
+ oldmatches := m.matches[c]
+ newmatches := make([]int, capcount*8)
+ copy(newmatches, oldmatches[:capcount*2])
+ m.matches[c] = newmatches
+ }
+
+ m.matches[c][capcount*2] = start
+ m.matches[c][capcount*2+1] = l
+ m.matchcount[c] = capcount + 1
+ //log.Printf("addMatch: c=%v, i=%v, l=%v ... matches: %v", c, start, l, m.matches)
+}
+
+// Nonpublic builder: Add a capture to balance the specified group. This is used by the
+//
+// balanced match construct. (?...)
+//
+// If there were no such thing as backtracking, this would be as simple as calling RemoveMatch(c).
+// However, since we have backtracking, we need to keep track of everything.
+func (m *Match) balanceMatch(c int) {
+ m.balancing = true
+
+ // we'll look at the last capture first
+ capcount := m.matchcount[c]
+ target := capcount*2 - 2
+
+ // first see if it is negative, and therefore is a reference to the next available
+ // capture group for balancing. If it is, we'll reset target to point to that capture.
+ if m.matches[c][target] < 0 {
+ target = -3 - m.matches[c][target]
+ }
+
+ // move back to the previous capture
+ target -= 2
+
+ // if the previous capture is a reference, just copy that reference to the end. Otherwise, point to it.
+ if target >= 0 && m.matches[c][target] < 0 {
+ m.addMatch(c, m.matches[c][target], m.matches[c][target+1])
+ } else {
+ m.addMatch(c, -3-target, -4-target /* == -3 - (target + 1) */)
+ }
+}
+
+// Nonpublic builder: removes a group match by capnum
+func (m *Match) removeMatch(c int) {
+ m.matchcount[c]--
+}
+
+// GroupCount returns the number of groups this match has matched
+func (m *Match) GroupCount() int {
+ return len(m.matchcount)
+}
+
+// GroupByName returns a group based on the name of the group, or nil if the group name does not exist
+func (m *Match) GroupByName(name string) *Group {
+ num := m.regex.GroupNumberFromName(name)
+ if num < 0 {
+ return nil
+ }
+ return m.GroupByNumber(num)
+}
+
+// GroupByNumber returns a group based on the number of the group, or nil if the group number does not exist
+func (m *Match) GroupByNumber(num int) *Group {
+ // check our sparse map
+ if m.sparseCaps != nil {
+ if newNum, ok := m.sparseCaps[num]; ok {
+ num = newNum
+ }
+ }
+ if num >= len(m.matchcount) || num < 0 {
+ return nil
+ }
+
+ if num == 0 {
+ return &m.Group
+ }
+
+ m.populateOtherGroups()
+
+ return &m.otherGroups[num-1]
+}
+
+// Groups returns all the capture groups, starting with group 0 (the full match)
+func (m *Match) Groups() []Group {
+ m.populateOtherGroups()
+ g := make([]Group, len(m.otherGroups)+1)
+ g[0] = m.Group
+ copy(g[1:], m.otherGroups)
+ return g
+}
+
+func (m *Match) populateOtherGroups() {
+ // Construct all the Group objects first time called
+ if m.otherGroups == nil {
+ m.otherGroups = make([]Group, len(m.matchcount)-1)
+ for i := 0; i < len(m.otherGroups); i++ {
+ m.otherGroups[i] = newGroup(m.regex.GroupNameFromNumber(i+1), m.text, m.matches[i+1], m.matchcount[i+1])
+ }
+ }
+}
+
+func (m *Match) groupValueAppendToBuf(groupnum int, buf *bytes.Buffer) {
+ c := m.matchcount[groupnum]
+ if c == 0 {
+ return
+ }
+
+ matches := m.matches[groupnum]
+
+ index := matches[(c-1)*2]
+ last := index + matches[(c*2)-1]
+
+ for ; index < last; index++ {
+ buf.WriteRune(m.text[index])
+ }
+}
+
+func newGroup(name string, text []rune, caps []int, capcount int) Group {
+ g := Group{}
+ g.text = text
+ if capcount > 0 {
+ g.Index = caps[(capcount-1)*2]
+ g.Length = caps[(capcount*2)-1]
+ }
+ g.Name = name
+ g.Captures = make([]Capture, capcount)
+ for i := 0; i < capcount; i++ {
+ g.Captures[i] = Capture{
+ text: text,
+ Index: caps[i*2],
+ Length: caps[i*2+1],
+ }
+ }
+ //log.Printf("newGroup! capcount %v, %+v", capcount, g)
+
+ return g
+}
+
+func (m *Match) dump() string {
+ buf := &bytes.Buffer{}
+ buf.WriteRune('\n')
+ if len(m.sparseCaps) > 0 {
+ for k, v := range m.sparseCaps {
+ fmt.Fprintf(buf, "Slot %v -> %v\n", k, v)
+ }
+ }
+
+ for i, g := range m.Groups() {
+ fmt.Fprintf(buf, "Group %v (%v), %v caps:\n", i, g.Name, len(g.Captures))
+
+ for _, c := range g.Captures {
+ fmt.Fprintf(buf, " (%v, %v) %v\n", c.Index, c.Length, c.String())
+ }
+ }
+ /*
+ for i := 0; i < len(m.matchcount); i++ {
+ fmt.Fprintf(buf, "\nGroup %v (%v):\n", i, m.regex.GroupNameFromNumber(i))
+
+ for j := 0; j < m.matchcount[i]; j++ {
+ text := ""
+
+ if m.matches[i][j*2] >= 0 {
+ start := m.matches[i][j*2]
+ text = m.text[start : start+m.matches[i][j*2+1]]
+ }
+
+ fmt.Fprintf(buf, " (%v, %v) %v\n", m.matches[i][j*2], m.matches[i][j*2+1], text)
+ }
+ }
+ */
+ return buf.String()
+}
diff --git a/vendor/github.com/dlclark/regexp2/regexp.go b/vendor/github.com/dlclark/regexp2/regexp.go
new file mode 100644
index 0000000..a7ddbaf
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/regexp.go
@@ -0,0 +1,395 @@
+/*
+Package regexp2 is a regexp package that has an interface similar to Go's framework regexp engine but uses a
+more feature full regex engine behind the scenes.
+
+It doesn't have constant time guarantees, but it allows backtracking and is compatible with Perl5 and .NET.
+You'll likely be better off with the RE2 engine from the regexp package and should only use this if you
+need to write very complex patterns or require compatibility with .NET.
+*/
+package regexp2
+
+import (
+ "errors"
+ "math"
+ "strconv"
+ "sync"
+ "time"
+
+ "github.com/dlclark/regexp2/syntax"
+)
+
+var (
+ // DefaultMatchTimeout used when running regexp matches -- "forever"
+ DefaultMatchTimeout = time.Duration(math.MaxInt64)
+ // DefaultUnmarshalOptions used when unmarshaling a regex from text
+ DefaultUnmarshalOptions = None
+)
+
+// Regexp is the representation of a compiled regular expression.
+// A Regexp is safe for concurrent use by multiple goroutines.
+type Regexp struct {
+ // A match will time out if it takes (approximately) more than
+ // MatchTimeout. This is a safety check in case the match
+ // encounters catastrophic backtracking. The default value
+ // (DefaultMatchTimeout) causes all time out checking to be
+ // suppressed.
+ MatchTimeout time.Duration
+
+ // read-only after Compile
+ pattern string // as passed to Compile
+ options RegexOptions // options
+
+ caps map[int]int // capnum->index
+ capnames map[string]int //capture group name -> index
+ capslist []string //sorted list of capture group names
+ capsize int // size of the capture array
+
+ code *syntax.Code // compiled program
+
+ // cache of machines for running regexp
+ muRun *sync.Mutex
+ runner []*runner
+}
+
+// Compile parses a regular expression and returns, if successful,
+// a Regexp object that can be used to match against text.
+func Compile(expr string, opt RegexOptions) (*Regexp, error) {
+ // parse it
+ tree, err := syntax.Parse(expr, syntax.RegexOptions(opt))
+ if err != nil {
+ return nil, err
+ }
+
+ // translate it to code
+ code, err := syntax.Write(tree)
+ if err != nil {
+ return nil, err
+ }
+
+ // return it
+ return &Regexp{
+ pattern: expr,
+ options: opt,
+ caps: code.Caps,
+ capnames: tree.Capnames,
+ capslist: tree.Caplist,
+ capsize: code.Capsize,
+ code: code,
+ MatchTimeout: DefaultMatchTimeout,
+ muRun: &sync.Mutex{},
+ }, nil
+}
+
+// MustCompile is like Compile but panics if the expression cannot be parsed.
+// It simplifies safe initialization of global variables holding compiled regular
+// expressions.
+func MustCompile(str string, opt RegexOptions) *Regexp {
+ regexp, error := Compile(str, opt)
+ if error != nil {
+ panic(`regexp2: Compile(` + quote(str) + `): ` + error.Error())
+ }
+ return regexp
+}
+
+// Escape adds backslashes to any special characters in the input string
+func Escape(input string) string {
+ return syntax.Escape(input)
+}
+
+// Unescape removes any backslashes from previously-escaped special characters in the input string
+func Unescape(input string) (string, error) {
+ return syntax.Unescape(input)
+}
+
+// SetTimeoutPeriod is a debug function that sets the frequency of the timeout goroutine's sleep cycle.
+// Defaults to 100ms. The only benefit of setting this lower is that the 1 background goroutine that manages
+// timeouts may exit slightly sooner after all the timeouts have expired. See Github issue #63
+func SetTimeoutCheckPeriod(d time.Duration) {
+ clockPeriod = d
+}
+
+// StopTimeoutClock should only be used in unit tests to prevent the timeout clock goroutine
+// from appearing like a leaking goroutine
+func StopTimeoutClock() {
+ stopClock()
+}
+
+// String returns the source text used to compile the regular expression.
+func (re *Regexp) String() string {
+ return re.pattern
+}
+
+func quote(s string) string {
+ if strconv.CanBackquote(s) {
+ return "`" + s + "`"
+ }
+ return strconv.Quote(s)
+}
+
+// RegexOptions impact the runtime and parsing behavior
+// for each specific regex. They are setable in code as well
+// as in the regex pattern itself.
+type RegexOptions int32
+
+const (
+ None RegexOptions = 0x0
+ IgnoreCase = 0x0001 // "i"
+ Multiline = 0x0002 // "m"
+ ExplicitCapture = 0x0004 // "n"
+ Compiled = 0x0008 // "c"
+ Singleline = 0x0010 // "s"
+ IgnorePatternWhitespace = 0x0020 // "x"
+ RightToLeft = 0x0040 // "r"
+ Debug = 0x0080 // "d"
+ ECMAScript = 0x0100 // "e"
+ RE2 = 0x0200 // RE2 (regexp package) compatibility mode
+ Unicode = 0x0400 // "u"
+)
+
+func (re *Regexp) RightToLeft() bool {
+ return re.options&RightToLeft != 0
+}
+
+func (re *Regexp) Debug() bool {
+ return re.options&Debug != 0
+}
+
+// Replace searches the input string and replaces each match found with the replacement text.
+// Count will limit the number of matches attempted and startAt will allow
+// us to skip past possible matches at the start of the input (left or right depending on RightToLeft option).
+// Set startAt and count to -1 to go through the whole string
+func (re *Regexp) Replace(input, replacement string, startAt, count int) (string, error) {
+ data, err := syntax.NewReplacerData(replacement, re.caps, re.capsize, re.capnames, syntax.RegexOptions(re.options))
+ if err != nil {
+ return "", err
+ }
+ //TODO: cache ReplacerData
+
+ return replace(re, data, nil, input, startAt, count)
+}
+
+// ReplaceFunc searches the input string and replaces each match found using the string from the evaluator
+// Count will limit the number of matches attempted and startAt will allow
+// us to skip past possible matches at the start of the input (left or right depending on RightToLeft option).
+// Set startAt and count to -1 to go through the whole string.
+func (re *Regexp) ReplaceFunc(input string, evaluator MatchEvaluator, startAt, count int) (string, error) {
+ return replace(re, nil, evaluator, input, startAt, count)
+}
+
+// FindStringMatch searches the input string for a Regexp match
+func (re *Regexp) FindStringMatch(s string) (*Match, error) {
+ // convert string to runes
+ return re.run(false, -1, getRunes(s))
+}
+
+// FindRunesMatch searches the input rune slice for a Regexp match
+func (re *Regexp) FindRunesMatch(r []rune) (*Match, error) {
+ return re.run(false, -1, r)
+}
+
+// FindStringMatchStartingAt searches the input string for a Regexp match starting at the startAt index
+func (re *Regexp) FindStringMatchStartingAt(s string, startAt int) (*Match, error) {
+ if startAt > len(s) {
+ return nil, errors.New("startAt must be less than the length of the input string")
+ }
+ r, startAt := re.getRunesAndStart(s, startAt)
+ if startAt == -1 {
+ // we didn't find our start index in the string -- that's a problem
+ return nil, errors.New("startAt must align to the start of a valid rune in the input string")
+ }
+
+ return re.run(false, startAt, r)
+}
+
+// FindRunesMatchStartingAt searches the input rune slice for a Regexp match starting at the startAt index
+func (re *Regexp) FindRunesMatchStartingAt(r []rune, startAt int) (*Match, error) {
+ return re.run(false, startAt, r)
+}
+
+// FindNextMatch returns the next match in the same input string as the match parameter.
+// Will return nil if there is no next match or if given a nil match.
+func (re *Regexp) FindNextMatch(m *Match) (*Match, error) {
+ if m == nil {
+ return nil, nil
+ }
+
+ // If previous match was empty, advance by one before matching to prevent
+ // infinite loop
+ startAt := m.textpos
+ if m.Length == 0 {
+ if m.textpos == len(m.text) {
+ return nil, nil
+ }
+
+ if re.RightToLeft() {
+ startAt--
+ } else {
+ startAt++
+ }
+ }
+ return re.run(false, startAt, m.text)
+}
+
+// MatchString return true if the string matches the regex
+// error will be set if a timeout occurs
+func (re *Regexp) MatchString(s string) (bool, error) {
+ m, err := re.run(true, -1, getRunes(s))
+ if err != nil {
+ return false, err
+ }
+ return m != nil, nil
+}
+
+func (re *Regexp) getRunesAndStart(s string, startAt int) ([]rune, int) {
+ if startAt < 0 {
+ if re.RightToLeft() {
+ r := getRunes(s)
+ return r, len(r)
+ }
+ return getRunes(s), 0
+ }
+ ret := make([]rune, len(s))
+ i := 0
+ runeIdx := -1
+ for strIdx, r := range s {
+ if strIdx == startAt {
+ runeIdx = i
+ }
+ ret[i] = r
+ i++
+ }
+ if startAt == len(s) {
+ runeIdx = i
+ }
+ return ret[:i], runeIdx
+}
+
+func getRunes(s string) []rune {
+ return []rune(s)
+}
+
+// MatchRunes return true if the runes matches the regex
+// error will be set if a timeout occurs
+func (re *Regexp) MatchRunes(r []rune) (bool, error) {
+ m, err := re.run(true, -1, r)
+ if err != nil {
+ return false, err
+ }
+ return m != nil, nil
+}
+
+// GetGroupNames Returns the set of strings used to name capturing groups in the expression.
+func (re *Regexp) GetGroupNames() []string {
+ var result []string
+
+ if re.capslist == nil {
+ result = make([]string, re.capsize)
+
+ for i := 0; i < len(result); i++ {
+ result[i] = strconv.Itoa(i)
+ }
+ } else {
+ result = make([]string, len(re.capslist))
+ copy(result, re.capslist)
+ }
+
+ return result
+}
+
+// GetGroupNumbers returns the integer group numbers corresponding to a group name.
+func (re *Regexp) GetGroupNumbers() []int {
+ var result []int
+
+ if re.caps == nil {
+ result = make([]int, re.capsize)
+
+ for i := 0; i < len(result); i++ {
+ result[i] = i
+ }
+ } else {
+ result = make([]int, len(re.caps))
+
+ for k, v := range re.caps {
+ result[v] = k
+ }
+ }
+
+ return result
+}
+
+// GroupNameFromNumber retrieves a group name that corresponds to a group number.
+// It will return "" for and unknown group number. Unnamed groups automatically
+// receive a name that is the decimal string equivalent of its number.
+func (re *Regexp) GroupNameFromNumber(i int) string {
+ if re.capslist == nil {
+ if i >= 0 && i < re.capsize {
+ return strconv.Itoa(i)
+ }
+
+ return ""
+ }
+
+ if re.caps != nil {
+ var ok bool
+ if i, ok = re.caps[i]; !ok {
+ return ""
+ }
+ }
+
+ if i >= 0 && i < len(re.capslist) {
+ return re.capslist[i]
+ }
+
+ return ""
+}
+
+// GroupNumberFromName returns a group number that corresponds to a group name.
+// Returns -1 if the name is not a recognized group name. Numbered groups
+// automatically get a group name that is the decimal string equivalent of its number.
+func (re *Regexp) GroupNumberFromName(name string) int {
+ // look up name if we have a hashtable of names
+ if re.capnames != nil {
+ if k, ok := re.capnames[name]; ok {
+ return k
+ }
+
+ return -1
+ }
+
+ // convert to an int if it looks like a number
+ result := 0
+ for i := 0; i < len(name); i++ {
+ ch := name[i]
+
+ if ch > '9' || ch < '0' {
+ return -1
+ }
+
+ result *= 10
+ result += int(ch - '0')
+ }
+
+ // return int if it's in range
+ if result >= 0 && result < re.capsize {
+ return result
+ }
+
+ return -1
+}
+
+// MarshalText implements [encoding.TextMarshaler]. The output
+// matches that of calling the [Regexp.String] method.
+func (re *Regexp) MarshalText() ([]byte, error) {
+ return []byte(re.String()), nil
+}
+
+// UnmarshalText implements [encoding.TextUnmarshaler] by calling
+// [Compile] on the encoded value.
+func (re *Regexp) UnmarshalText(text []byte) error {
+ newRE, err := Compile(string(text), DefaultUnmarshalOptions)
+ if err != nil {
+ return err
+ }
+ *re = *newRE
+ return nil
+}
diff --git a/vendor/github.com/dlclark/regexp2/replace.go b/vendor/github.com/dlclark/regexp2/replace.go
new file mode 100644
index 0000000..0376bd9
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/replace.go
@@ -0,0 +1,177 @@
+package regexp2
+
+import (
+ "bytes"
+ "errors"
+
+ "github.com/dlclark/regexp2/syntax"
+)
+
+const (
+ replaceSpecials = 4
+ replaceLeftPortion = -1
+ replaceRightPortion = -2
+ replaceLastGroup = -3
+ replaceWholeString = -4
+)
+
+// MatchEvaluator is a function that takes a match and returns a replacement string to be used
+type MatchEvaluator func(Match) string
+
+// Three very similar algorithms appear below: replace (pattern),
+// replace (evaluator), and split.
+
+// Replace Replaces all occurrences of the regex in the string with the
+// replacement pattern.
+//
+// Note that the special case of no matches is handled on its own:
+// with no matches, the input string is returned unchanged.
+// The right-to-left case is split out because StringBuilder
+// doesn't handle right-to-left string building directly very well.
+func replace(regex *Regexp, data *syntax.ReplacerData, evaluator MatchEvaluator, input string, startAt, count int) (string, error) {
+ if count < -1 {
+ return "", errors.New("Count too small")
+ }
+ if count == 0 {
+ return "", nil
+ }
+
+ m, err := regex.FindStringMatchStartingAt(input, startAt)
+
+ if err != nil {
+ return "", err
+ }
+ if m == nil {
+ return input, nil
+ }
+
+ buf := &bytes.Buffer{}
+ text := m.text
+
+ if !regex.RightToLeft() {
+ prevat := 0
+ for m != nil {
+ if m.Index != prevat {
+ buf.WriteString(string(text[prevat:m.Index]))
+ }
+ prevat = m.Index + m.Length
+ if evaluator == nil {
+ replacementImpl(data, buf, m)
+ } else {
+ buf.WriteString(evaluator(*m))
+ }
+
+ count--
+ if count == 0 {
+ break
+ }
+ m, err = regex.FindNextMatch(m)
+ if err != nil {
+ return "", nil
+ }
+ }
+
+ if prevat < len(text) {
+ buf.WriteString(string(text[prevat:]))
+ }
+ } else {
+ prevat := len(text)
+ var al []string
+
+ for m != nil {
+ if m.Index+m.Length != prevat {
+ al = append(al, string(text[m.Index+m.Length:prevat]))
+ }
+ prevat = m.Index
+ if evaluator == nil {
+ replacementImplRTL(data, &al, m)
+ } else {
+ al = append(al, evaluator(*m))
+ }
+
+ count--
+ if count == 0 {
+ break
+ }
+ m, err = regex.FindNextMatch(m)
+ if err != nil {
+ return "", nil
+ }
+ }
+
+ if prevat > 0 {
+ buf.WriteString(string(text[:prevat]))
+ }
+
+ for i := len(al) - 1; i >= 0; i-- {
+ buf.WriteString(al[i])
+ }
+ }
+
+ return buf.String(), nil
+}
+
+// Given a Match, emits into the StringBuilder the evaluated
+// substitution pattern.
+func replacementImpl(data *syntax.ReplacerData, buf *bytes.Buffer, m *Match) {
+ for _, r := range data.Rules {
+
+ if r >= 0 { // string lookup
+ buf.WriteString(data.Strings[r])
+ } else if r < -replaceSpecials { // group lookup
+ m.groupValueAppendToBuf(-replaceSpecials-1-r, buf)
+ } else {
+ switch -replaceSpecials - 1 - r { // special insertion patterns
+ case replaceLeftPortion:
+ for i := 0; i < m.Index; i++ {
+ buf.WriteRune(m.text[i])
+ }
+ case replaceRightPortion:
+ for i := m.Index + m.Length; i < len(m.text); i++ {
+ buf.WriteRune(m.text[i])
+ }
+ case replaceLastGroup:
+ m.groupValueAppendToBuf(m.GroupCount()-1, buf)
+ case replaceWholeString:
+ for i := 0; i < len(m.text); i++ {
+ buf.WriteRune(m.text[i])
+ }
+ }
+ }
+ }
+}
+
+func replacementImplRTL(data *syntax.ReplacerData, al *[]string, m *Match) {
+ l := *al
+ buf := &bytes.Buffer{}
+
+ for _, r := range data.Rules {
+ buf.Reset()
+ if r >= 0 { // string lookup
+ l = append(l, data.Strings[r])
+ } else if r < -replaceSpecials { // group lookup
+ m.groupValueAppendToBuf(-replaceSpecials-1-r, buf)
+ l = append(l, buf.String())
+ } else {
+ switch -replaceSpecials - 1 - r { // special insertion patterns
+ case replaceLeftPortion:
+ for i := 0; i < m.Index; i++ {
+ buf.WriteRune(m.text[i])
+ }
+ case replaceRightPortion:
+ for i := m.Index + m.Length; i < len(m.text); i++ {
+ buf.WriteRune(m.text[i])
+ }
+ case replaceLastGroup:
+ m.groupValueAppendToBuf(m.GroupCount()-1, buf)
+ case replaceWholeString:
+ for i := 0; i < len(m.text); i++ {
+ buf.WriteRune(m.text[i])
+ }
+ }
+ l = append(l, buf.String())
+ }
+ }
+
+ *al = l
+}
diff --git a/vendor/github.com/dlclark/regexp2/runner.go b/vendor/github.com/dlclark/regexp2/runner.go
new file mode 100644
index 0000000..56759f1
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/runner.go
@@ -0,0 +1,1613 @@
+package regexp2
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "math"
+ "strconv"
+ "strings"
+ "time"
+ "unicode"
+
+ "github.com/dlclark/regexp2/syntax"
+)
+
+type runner struct {
+ re *Regexp
+ code *syntax.Code
+
+ runtextstart int // starting point for search
+
+ runtext []rune // text to search
+ runtextpos int // current position in text
+ runtextend int
+
+ // The backtracking stack. Opcodes use this to store data regarding
+ // what they have matched and where to backtrack to. Each "frame" on
+ // the stack takes the form of [CodePosition Data1 Data2...], where
+ // CodePosition is the position of the current opcode and
+ // the data values are all optional. The CodePosition can be negative, and
+ // these values (also called "back2") are used by the BranchMark family of opcodes
+ // to indicate whether they are backtracking after a successful or failed
+ // match.
+ // When we backtrack, we pop the CodePosition off the stack, set the current
+ // instruction pointer to that code position, and mark the opcode
+ // with a backtracking flag ("Back"). Each opcode then knows how to
+ // handle its own data.
+ runtrack []int
+ runtrackpos int
+
+ // This stack is used to track text positions across different opcodes.
+ // For example, in /(a*b)+/, the parentheses result in a SetMark/CaptureMark
+ // pair. SetMark records the text position before we match a*b. Then
+ // CaptureMark uses that position to figure out where the capture starts.
+ // Opcodes which push onto this stack are always paired with other opcodes
+ // which will pop the value from it later. A successful match should mean
+ // that this stack is empty.
+ runstack []int
+ runstackpos int
+
+ // The crawl stack is used to keep track of captures. Every time a group
+ // has a capture, we push its group number onto the runcrawl stack. In
+ // the case of a balanced match, we push BOTH groups onto the stack.
+ runcrawl []int
+ runcrawlpos int
+
+ runtrackcount int // count of states that may do backtracking
+
+ runmatch *Match // result object
+
+ ignoreTimeout bool
+ timeout time.Duration // timeout in milliseconds (needed for actual)
+ deadline fasttime
+
+ operator syntax.InstOp
+ codepos int
+ rightToLeft bool
+ caseInsensitive bool
+}
+
+// run searches for matches and can continue from the previous match
+//
+// quick is usually false, but can be true to not return matches, just put it in caches
+// textstart is -1 to start at the "beginning" (depending on Right-To-Left), otherwise an index in input
+// input is the string to search for our regex pattern
+func (re *Regexp) run(quick bool, textstart int, input []rune) (*Match, error) {
+
+ // get a cached runner
+ runner := re.getRunner()
+ defer re.putRunner(runner)
+
+ if textstart < 0 {
+ if re.RightToLeft() {
+ textstart = len(input)
+ } else {
+ textstart = 0
+ }
+ }
+
+ return runner.scan(input, textstart, quick, re.MatchTimeout)
+}
+
+// Scans the string to find the first match. Uses the Match object
+// both to feed text in and as a place to store matches that come out.
+//
+// All the action is in the Go() method. Our
+// responsibility is to load up the class members before
+// calling Go.
+//
+// The optimizer can compute a set of candidate starting characters,
+// and we could use a separate method Skip() that will quickly scan past
+// any characters that we know can't match.
+func (r *runner) scan(rt []rune, textstart int, quick bool, timeout time.Duration) (*Match, error) {
+ r.timeout = timeout
+ r.ignoreTimeout = (time.Duration(math.MaxInt64) == timeout)
+ r.runtextstart = textstart
+ r.runtext = rt
+ r.runtextend = len(rt)
+
+ stoppos := r.runtextend
+ bump := 1
+
+ if r.re.RightToLeft() {
+ bump = -1
+ stoppos = 0
+ }
+
+ r.runtextpos = textstart
+ initted := false
+
+ r.startTimeoutWatch()
+ for {
+ if r.re.Debug() {
+ //fmt.Printf("\nSearch content: %v\n", string(r.runtext))
+ fmt.Printf("\nSearch range: from 0 to %v\n", r.runtextend)
+ fmt.Printf("Firstchar search starting at %v stopping at %v\n", r.runtextpos, stoppos)
+ }
+
+ if r.findFirstChar() {
+ if err := r.checkTimeout(); err != nil {
+ return nil, err
+ }
+
+ if !initted {
+ r.initMatch()
+ initted = true
+ }
+
+ if r.re.Debug() {
+ fmt.Printf("Executing engine starting at %v\n\n", r.runtextpos)
+ }
+
+ if err := r.execute(); err != nil {
+ return nil, err
+ }
+
+ if r.runmatch.matchcount[0] > 0 {
+ // We'll return a match even if it touches a previous empty match
+ return r.tidyMatch(quick), nil
+ }
+
+ // reset state for another go
+ r.runtrackpos = len(r.runtrack)
+ r.runstackpos = len(r.runstack)
+ r.runcrawlpos = len(r.runcrawl)
+ }
+
+ // failure!
+
+ if r.runtextpos == stoppos {
+ r.tidyMatch(true)
+ return nil, nil
+ }
+
+ // Recognize leading []* and various anchors, and bump on failure accordingly
+
+ // r.bump by one and start again
+
+ r.runtextpos += bump
+ }
+ // We never get here
+}
+
+func (r *runner) execute() error {
+
+ r.goTo(0)
+
+ for {
+
+ if r.re.Debug() {
+ r.dumpState()
+ }
+
+ if err := r.checkTimeout(); err != nil {
+ return err
+ }
+
+ switch r.operator {
+ case syntax.Stop:
+ return nil
+
+ case syntax.Nothing:
+ break
+
+ case syntax.Goto:
+ r.goTo(r.operand(0))
+ continue
+
+ case syntax.Testref:
+ if !r.runmatch.isMatched(r.operand(0)) {
+ break
+ }
+ r.advance(1)
+ continue
+
+ case syntax.Lazybranch:
+ r.trackPush1(r.textPos())
+ r.advance(1)
+ continue
+
+ case syntax.Lazybranch | syntax.Back:
+ r.trackPop()
+ r.textto(r.trackPeek())
+ r.goTo(r.operand(0))
+ continue
+
+ case syntax.Setmark:
+ r.stackPush(r.textPos())
+ r.trackPush()
+ r.advance(0)
+ continue
+
+ case syntax.Nullmark:
+ r.stackPush(-1)
+ r.trackPush()
+ r.advance(0)
+ continue
+
+ case syntax.Setmark | syntax.Back, syntax.Nullmark | syntax.Back:
+ r.stackPop()
+ break
+
+ case syntax.Getmark:
+ r.stackPop()
+ r.trackPush1(r.stackPeek())
+ r.textto(r.stackPeek())
+ r.advance(0)
+ continue
+
+ case syntax.Getmark | syntax.Back:
+ r.trackPop()
+ r.stackPush(r.trackPeek())
+ break
+
+ case syntax.Capturemark:
+ if r.operand(1) != -1 && !r.runmatch.isMatched(r.operand(1)) {
+ break
+ }
+ r.stackPop()
+ if r.operand(1) != -1 {
+ r.transferCapture(r.operand(0), r.operand(1), r.stackPeek(), r.textPos())
+ } else {
+ r.capture(r.operand(0), r.stackPeek(), r.textPos())
+ }
+ r.trackPush1(r.stackPeek())
+
+ r.advance(2)
+
+ continue
+
+ case syntax.Capturemark | syntax.Back:
+ r.trackPop()
+ r.stackPush(r.trackPeek())
+ r.uncapture()
+ if r.operand(0) != -1 && r.operand(1) != -1 {
+ r.uncapture()
+ }
+
+ break
+
+ case syntax.Branchmark:
+ r.stackPop()
+
+ matched := r.textPos() - r.stackPeek()
+
+ if matched != 0 { // Nonempty match -> loop now
+ r.trackPush2(r.stackPeek(), r.textPos()) // Save old mark, textpos
+ r.stackPush(r.textPos()) // Make new mark
+ r.goTo(r.operand(0)) // Loop
+ } else { // Empty match -> straight now
+ r.trackPushNeg1(r.stackPeek()) // Save old mark
+ r.advance(1) // Straight
+ }
+ continue
+
+ case syntax.Branchmark | syntax.Back:
+ r.trackPopN(2)
+ r.stackPop()
+ r.textto(r.trackPeekN(1)) // Recall position
+ r.trackPushNeg1(r.trackPeek()) // Save old mark
+ r.advance(1) // Straight
+ continue
+
+ case syntax.Branchmark | syntax.Back2:
+ r.trackPop()
+ r.stackPush(r.trackPeek()) // Recall old mark
+ break // Backtrack
+
+ case syntax.Lazybranchmark:
+ {
+ // We hit this the first time through a lazy loop and after each
+ // successful match of the inner expression. It simply continues
+ // on and doesn't loop.
+ r.stackPop()
+
+ oldMarkPos := r.stackPeek()
+
+ if r.textPos() != oldMarkPos { // Nonempty match -> try to loop again by going to 'back' state
+ if oldMarkPos != -1 {
+ r.trackPush2(oldMarkPos, r.textPos()) // Save old mark, textpos
+ } else {
+ r.trackPush2(r.textPos(), r.textPos())
+ }
+ } else {
+ // The inner expression found an empty match, so we'll go directly to 'back2' if we
+ // backtrack. In this case, we need to push something on the stack, since back2 pops.
+ // However, in the case of ()+? or similar, this empty match may be legitimate, so push the text
+ // position associated with that empty match.
+ r.stackPush(oldMarkPos)
+
+ r.trackPushNeg1(r.stackPeek()) // Save old mark
+ }
+ r.advance(1)
+ continue
+ }
+
+ case syntax.Lazybranchmark | syntax.Back:
+
+ // After the first time, Lazybranchmark | syntax.Back occurs
+ // with each iteration of the loop, and therefore with every attempted
+ // match of the inner expression. We'll try to match the inner expression,
+ // then go back to Lazybranchmark if successful. If the inner expression
+ // fails, we go to Lazybranchmark | syntax.Back2
+
+ r.trackPopN(2)
+ pos := r.trackPeekN(1)
+ r.trackPushNeg1(r.trackPeek()) // Save old mark
+ r.stackPush(pos) // Make new mark
+ r.textto(pos) // Recall position
+ r.goTo(r.operand(0)) // Loop
+ continue
+
+ case syntax.Lazybranchmark | syntax.Back2:
+ // The lazy loop has failed. We'll do a true backtrack and
+ // start over before the lazy loop.
+ r.stackPop()
+ r.trackPop()
+ r.stackPush(r.trackPeek()) // Recall old mark
+ break
+
+ case syntax.Setcount:
+ r.stackPush2(r.textPos(), r.operand(0))
+ r.trackPush()
+ r.advance(1)
+ continue
+
+ case syntax.Nullcount:
+ r.stackPush2(-1, r.operand(0))
+ r.trackPush()
+ r.advance(1)
+ continue
+
+ case syntax.Setcount | syntax.Back:
+ r.stackPopN(2)
+ break
+
+ case syntax.Nullcount | syntax.Back:
+ r.stackPopN(2)
+ break
+
+ case syntax.Branchcount:
+ // r.stackPush:
+ // 0: Mark
+ // 1: Count
+
+ r.stackPopN(2)
+ mark := r.stackPeek()
+ count := r.stackPeekN(1)
+ matched := r.textPos() - mark
+
+ if count >= r.operand(1) || (matched == 0 && count >= 0) { // Max loops or empty match -> straight now
+ r.trackPushNeg2(mark, count) // Save old mark, count
+ r.advance(2) // Straight
+ } else { // Nonempty match -> count+loop now
+ r.trackPush1(mark) // remember mark
+ r.stackPush2(r.textPos(), count+1) // Make new mark, incr count
+ r.goTo(r.operand(0)) // Loop
+ }
+ continue
+
+ case syntax.Branchcount | syntax.Back:
+ // r.trackPush:
+ // 0: Previous mark
+ // r.stackPush:
+ // 0: Mark (= current pos, discarded)
+ // 1: Count
+ r.trackPop()
+ r.stackPopN(2)
+ if r.stackPeekN(1) > 0 { // Positive -> can go straight
+ r.textto(r.stackPeek()) // Zap to mark
+ r.trackPushNeg2(r.trackPeek(), r.stackPeekN(1)-1) // Save old mark, old count
+ r.advance(2) // Straight
+ continue
+ }
+ r.stackPush2(r.trackPeek(), r.stackPeekN(1)-1) // recall old mark, old count
+ break
+
+ case syntax.Branchcount | syntax.Back2:
+ // r.trackPush:
+ // 0: Previous mark
+ // 1: Previous count
+ r.trackPopN(2)
+ r.stackPush2(r.trackPeek(), r.trackPeekN(1)) // Recall old mark, old count
+ break // Backtrack
+
+ case syntax.Lazybranchcount:
+ // r.stackPush:
+ // 0: Mark
+ // 1: Count
+
+ r.stackPopN(2)
+ mark := r.stackPeek()
+ count := r.stackPeekN(1)
+
+ if count < 0 { // Negative count -> loop now
+ r.trackPushNeg1(mark) // Save old mark
+ r.stackPush2(r.textPos(), count+1) // Make new mark, incr count
+ r.goTo(r.operand(0)) // Loop
+ } else { // Nonneg count -> straight now
+ r.trackPush3(mark, count, r.textPos()) // Save mark, count, position
+ r.advance(2) // Straight
+ }
+ continue
+
+ case syntax.Lazybranchcount | syntax.Back:
+ // r.trackPush:
+ // 0: Mark
+ // 1: Count
+ // 2: r.textPos
+
+ r.trackPopN(3)
+ mark := r.trackPeek()
+ textpos := r.trackPeekN(2)
+
+ if r.trackPeekN(1) < r.operand(1) && textpos != mark { // Under limit and not empty match -> loop
+ r.textto(textpos) // Recall position
+ r.stackPush2(textpos, r.trackPeekN(1)+1) // Make new mark, incr count
+ r.trackPushNeg1(mark) // Save old mark
+ r.goTo(r.operand(0)) // Loop
+ continue
+ } else { // Max loops or empty match -> backtrack
+ r.stackPush2(r.trackPeek(), r.trackPeekN(1)) // Recall old mark, count
+ break // backtrack
+ }
+
+ case syntax.Lazybranchcount | syntax.Back2:
+ // r.trackPush:
+ // 0: Previous mark
+ // r.stackPush:
+ // 0: Mark (== current pos, discarded)
+ // 1: Count
+ r.trackPop()
+ r.stackPopN(2)
+ r.stackPush2(r.trackPeek(), r.stackPeekN(1)-1) // Recall old mark, count
+ break // Backtrack
+
+ case syntax.Setjump:
+ r.stackPush2(r.trackpos(), r.crawlpos())
+ r.trackPush()
+ r.advance(0)
+ continue
+
+ case syntax.Setjump | syntax.Back:
+ r.stackPopN(2)
+ break
+
+ case syntax.Backjump:
+ // r.stackPush:
+ // 0: Saved trackpos
+ // 1: r.crawlpos
+ r.stackPopN(2)
+ r.trackto(r.stackPeek())
+
+ for r.crawlpos() != r.stackPeekN(1) {
+ r.uncapture()
+ }
+
+ break
+
+ case syntax.Forejump:
+ // r.stackPush:
+ // 0: Saved trackpos
+ // 1: r.crawlpos
+ r.stackPopN(2)
+ r.trackto(r.stackPeek())
+ r.trackPush1(r.stackPeekN(1))
+ r.advance(0)
+ continue
+
+ case syntax.Forejump | syntax.Back:
+ // r.trackPush:
+ // 0: r.crawlpos
+ r.trackPop()
+
+ for r.crawlpos() != r.trackPeek() {
+ r.uncapture()
+ }
+
+ break
+
+ case syntax.Bol:
+ if r.leftchars() > 0 && r.charAt(r.textPos()-1) != '\n' {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.Eol:
+ if r.rightchars() > 0 && r.charAt(r.textPos()) != '\n' {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.Boundary:
+ if !r.isBoundary(r.textPos(), 0, r.runtextend) {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.Nonboundary:
+ if r.isBoundary(r.textPos(), 0, r.runtextend) {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.ECMABoundary:
+ if !r.isECMABoundary(r.textPos(), 0, r.runtextend) {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.NonECMABoundary:
+ if r.isECMABoundary(r.textPos(), 0, r.runtextend) {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.Beginning:
+ if r.leftchars() > 0 {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.Start:
+ if r.textPos() != r.textstart() {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.EndZ:
+ rchars := r.rightchars()
+ if rchars > 1 {
+ break
+ }
+ // RE2 and EcmaScript define $ as "asserts position at the end of the string"
+ // PCRE/.NET adds "or before the line terminator right at the end of the string (if any)"
+ if (r.re.options & (RE2 | ECMAScript)) != 0 {
+ // RE2/Ecmascript mode
+ if rchars > 0 {
+ break
+ }
+ } else if rchars == 1 && r.charAt(r.textPos()) != '\n' {
+ // "regular" mode
+ break
+ }
+
+ r.advance(0)
+ continue
+
+ case syntax.End:
+ if r.rightchars() > 0 {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.One:
+ if r.forwardchars() < 1 || r.forwardcharnext() != rune(r.operand(0)) {
+ break
+ }
+
+ r.advance(1)
+ continue
+
+ case syntax.Notone:
+ if r.forwardchars() < 1 || r.forwardcharnext() == rune(r.operand(0)) {
+ break
+ }
+
+ r.advance(1)
+ continue
+
+ case syntax.Set:
+
+ if r.forwardchars() < 1 || !r.code.Sets[r.operand(0)].CharIn(r.forwardcharnext()) {
+ break
+ }
+
+ r.advance(1)
+ continue
+
+ case syntax.Multi:
+ if !r.runematch(r.code.Strings[r.operand(0)]) {
+ break
+ }
+
+ r.advance(1)
+ continue
+
+ case syntax.Ref:
+
+ capnum := r.operand(0)
+
+ if r.runmatch.isMatched(capnum) {
+ if !r.refmatch(r.runmatch.matchIndex(capnum), r.runmatch.matchLength(capnum)) {
+ break
+ }
+ } else {
+ if (r.re.options & ECMAScript) == 0 {
+ break
+ }
+ }
+
+ r.advance(1)
+ continue
+
+ case syntax.Onerep:
+
+ c := r.operand(1)
+
+ if r.forwardchars() < c {
+ break
+ }
+
+ ch := rune(r.operand(0))
+
+ for c > 0 {
+ if r.forwardcharnext() != ch {
+ goto BreakBackward
+ }
+ c--
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Notonerep:
+
+ c := r.operand(1)
+
+ if r.forwardchars() < c {
+ break
+ }
+ ch := rune(r.operand(0))
+
+ for c > 0 {
+ if r.forwardcharnext() == ch {
+ goto BreakBackward
+ }
+ c--
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Setrep:
+
+ c := r.operand(1)
+
+ if r.forwardchars() < c {
+ break
+ }
+
+ set := r.code.Sets[r.operand(0)]
+
+ for c > 0 {
+ if !set.CharIn(r.forwardcharnext()) {
+ goto BreakBackward
+ }
+ c--
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Oneloop:
+
+ c := r.operand(1)
+
+ if c > r.forwardchars() {
+ c = r.forwardchars()
+ }
+
+ ch := rune(r.operand(0))
+ i := c
+
+ for ; i > 0; i-- {
+ if r.forwardcharnext() != ch {
+ r.backwardnext()
+ break
+ }
+ }
+
+ if c > i {
+ r.trackPush2(c-i-1, r.textPos()-r.bump())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Notoneloop:
+
+ c := r.operand(1)
+
+ if c > r.forwardchars() {
+ c = r.forwardchars()
+ }
+
+ ch := rune(r.operand(0))
+ i := c
+
+ for ; i > 0; i-- {
+ if r.forwardcharnext() == ch {
+ r.backwardnext()
+ break
+ }
+ }
+
+ if c > i {
+ r.trackPush2(c-i-1, r.textPos()-r.bump())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Setloop:
+
+ c := r.operand(1)
+
+ if c > r.forwardchars() {
+ c = r.forwardchars()
+ }
+
+ set := r.code.Sets[r.operand(0)]
+ i := c
+
+ for ; i > 0; i-- {
+ if !set.CharIn(r.forwardcharnext()) {
+ r.backwardnext()
+ break
+ }
+ }
+
+ if c > i {
+ r.trackPush2(c-i-1, r.textPos()-r.bump())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Oneloop | syntax.Back, syntax.Notoneloop | syntax.Back:
+
+ r.trackPopN(2)
+ i := r.trackPeek()
+ pos := r.trackPeekN(1)
+
+ r.textto(pos)
+
+ if i > 0 {
+ r.trackPush2(i-1, pos-r.bump())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Setloop | syntax.Back:
+
+ r.trackPopN(2)
+ i := r.trackPeek()
+ pos := r.trackPeekN(1)
+
+ r.textto(pos)
+
+ if i > 0 {
+ r.trackPush2(i-1, pos-r.bump())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Onelazy, syntax.Notonelazy:
+
+ c := r.operand(1)
+
+ if c > r.forwardchars() {
+ c = r.forwardchars()
+ }
+
+ if c > 0 {
+ r.trackPush2(c-1, r.textPos())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Setlazy:
+
+ c := r.operand(1)
+
+ if c > r.forwardchars() {
+ c = r.forwardchars()
+ }
+
+ if c > 0 {
+ r.trackPush2(c-1, r.textPos())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Onelazy | syntax.Back:
+
+ r.trackPopN(2)
+ pos := r.trackPeekN(1)
+ r.textto(pos)
+
+ if r.forwardcharnext() != rune(r.operand(0)) {
+ break
+ }
+
+ i := r.trackPeek()
+
+ if i > 0 {
+ r.trackPush2(i-1, pos+r.bump())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Notonelazy | syntax.Back:
+
+ r.trackPopN(2)
+ pos := r.trackPeekN(1)
+ r.textto(pos)
+
+ if r.forwardcharnext() == rune(r.operand(0)) {
+ break
+ }
+
+ i := r.trackPeek()
+
+ if i > 0 {
+ r.trackPush2(i-1, pos+r.bump())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Setlazy | syntax.Back:
+
+ r.trackPopN(2)
+ pos := r.trackPeekN(1)
+ r.textto(pos)
+
+ if !r.code.Sets[r.operand(0)].CharIn(r.forwardcharnext()) {
+ break
+ }
+
+ i := r.trackPeek()
+
+ if i > 0 {
+ r.trackPush2(i-1, pos+r.bump())
+ }
+
+ r.advance(2)
+ continue
+
+ default:
+ return errors.New("unknown state in regex runner")
+ }
+
+ BreakBackward:
+ ;
+
+ // "break Backward" comes here:
+ r.backtrack()
+ }
+}
+
+// increase the size of stack and track storage
+func (r *runner) ensureStorage() {
+ if r.runstackpos < r.runtrackcount*4 {
+ doubleIntSlice(&r.runstack, &r.runstackpos)
+ }
+ if r.runtrackpos < r.runtrackcount*4 {
+ doubleIntSlice(&r.runtrack, &r.runtrackpos)
+ }
+}
+
+func doubleIntSlice(s *[]int, pos *int) {
+ oldLen := len(*s)
+ newS := make([]int, oldLen*2)
+
+ copy(newS[oldLen:], *s)
+ *pos += oldLen
+ *s = newS
+}
+
+// Save a number on the longjump unrolling stack
+func (r *runner) crawl(i int) {
+ if r.runcrawlpos == 0 {
+ doubleIntSlice(&r.runcrawl, &r.runcrawlpos)
+ }
+ r.runcrawlpos--
+ r.runcrawl[r.runcrawlpos] = i
+}
+
+// Remove a number from the longjump unrolling stack
+func (r *runner) popcrawl() int {
+ val := r.runcrawl[r.runcrawlpos]
+ r.runcrawlpos++
+ return val
+}
+
+// Get the height of the stack
+func (r *runner) crawlpos() int {
+ return len(r.runcrawl) - r.runcrawlpos
+}
+
+func (r *runner) advance(i int) {
+ r.codepos += (i + 1)
+ r.setOperator(r.code.Codes[r.codepos])
+}
+
+func (r *runner) goTo(newpos int) {
+ // when branching backward or in place, ensure storage
+ if newpos <= r.codepos {
+ r.ensureStorage()
+ }
+
+ r.setOperator(r.code.Codes[newpos])
+ r.codepos = newpos
+}
+
+func (r *runner) textto(newpos int) {
+ r.runtextpos = newpos
+}
+
+func (r *runner) trackto(newpos int) {
+ r.runtrackpos = len(r.runtrack) - newpos
+}
+
+func (r *runner) textstart() int {
+ return r.runtextstart
+}
+
+func (r *runner) textPos() int {
+ return r.runtextpos
+}
+
+// push onto the backtracking stack
+func (r *runner) trackpos() int {
+ return len(r.runtrack) - r.runtrackpos
+}
+
+func (r *runner) trackPush() {
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = r.codepos
+}
+
+func (r *runner) trackPush1(I1 int) {
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I1
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = r.codepos
+}
+
+func (r *runner) trackPush2(I1, I2 int) {
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I1
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I2
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = r.codepos
+}
+
+func (r *runner) trackPush3(I1, I2, I3 int) {
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I1
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I2
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I3
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = r.codepos
+}
+
+func (r *runner) trackPushNeg1(I1 int) {
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I1
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = -r.codepos
+}
+
+func (r *runner) trackPushNeg2(I1, I2 int) {
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I1
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I2
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = -r.codepos
+}
+
+func (r *runner) backtrack() {
+ newpos := r.runtrack[r.runtrackpos]
+ r.runtrackpos++
+
+ if r.re.Debug() {
+ if newpos < 0 {
+ fmt.Printf(" Backtracking (back2) to code position %v\n", -newpos)
+ } else {
+ fmt.Printf(" Backtracking to code position %v\n", newpos)
+ }
+ }
+
+ if newpos < 0 {
+ newpos = -newpos
+ r.setOperator(r.code.Codes[newpos] | syntax.Back2)
+ } else {
+ r.setOperator(r.code.Codes[newpos] | syntax.Back)
+ }
+
+ // When branching backward, ensure storage
+ if newpos < r.codepos {
+ r.ensureStorage()
+ }
+
+ r.codepos = newpos
+}
+
+func (r *runner) setOperator(op int) {
+ r.caseInsensitive = (0 != (op & syntax.Ci))
+ r.rightToLeft = (0 != (op & syntax.Rtl))
+ r.operator = syntax.InstOp(op & ^(syntax.Rtl | syntax.Ci))
+}
+
+func (r *runner) trackPop() {
+ r.runtrackpos++
+}
+
+// pop framesize items from the backtracking stack
+func (r *runner) trackPopN(framesize int) {
+ r.runtrackpos += framesize
+}
+
+// Technically we are actually peeking at items already popped. So if you want to
+// get and pop the top item from the stack, you do
+// r.trackPop();
+// r.trackPeek();
+func (r *runner) trackPeek() int {
+ return r.runtrack[r.runtrackpos-1]
+}
+
+// get the ith element down on the backtracking stack
+func (r *runner) trackPeekN(i int) int {
+ return r.runtrack[r.runtrackpos-i-1]
+}
+
+// Push onto the grouping stack
+func (r *runner) stackPush(I1 int) {
+ r.runstackpos--
+ r.runstack[r.runstackpos] = I1
+}
+
+func (r *runner) stackPush2(I1, I2 int) {
+ r.runstackpos--
+ r.runstack[r.runstackpos] = I1
+ r.runstackpos--
+ r.runstack[r.runstackpos] = I2
+}
+
+func (r *runner) stackPop() {
+ r.runstackpos++
+}
+
+// pop framesize items from the grouping stack
+func (r *runner) stackPopN(framesize int) {
+ r.runstackpos += framesize
+}
+
+// Technically we are actually peeking at items already popped. So if you want to
+// get and pop the top item from the stack, you do
+// r.stackPop();
+// r.stackPeek();
+func (r *runner) stackPeek() int {
+ return r.runstack[r.runstackpos-1]
+}
+
+// get the ith element down on the grouping stack
+func (r *runner) stackPeekN(i int) int {
+ return r.runstack[r.runstackpos-i-1]
+}
+
+func (r *runner) operand(i int) int {
+ return r.code.Codes[r.codepos+i+1]
+}
+
+func (r *runner) leftchars() int {
+ return r.runtextpos
+}
+
+func (r *runner) rightchars() int {
+ return r.runtextend - r.runtextpos
+}
+
+func (r *runner) bump() int {
+ if r.rightToLeft {
+ return -1
+ }
+ return 1
+}
+
+func (r *runner) forwardchars() int {
+ if r.rightToLeft {
+ return r.runtextpos
+ }
+ return r.runtextend - r.runtextpos
+}
+
+func (r *runner) forwardcharnext() rune {
+ var ch rune
+ if r.rightToLeft {
+ r.runtextpos--
+ ch = r.runtext[r.runtextpos]
+ } else {
+ ch = r.runtext[r.runtextpos]
+ r.runtextpos++
+ }
+
+ if r.caseInsensitive {
+ return unicode.ToLower(ch)
+ }
+ return ch
+}
+
+func (r *runner) runematch(str []rune) bool {
+ var pos int
+
+ c := len(str)
+ if !r.rightToLeft {
+ if r.runtextend-r.runtextpos < c {
+ return false
+ }
+
+ pos = r.runtextpos + c
+ } else {
+ if r.runtextpos-0 < c {
+ return false
+ }
+
+ pos = r.runtextpos
+ }
+
+ if !r.caseInsensitive {
+ for c != 0 {
+ c--
+ pos--
+ if str[c] != r.runtext[pos] {
+ return false
+ }
+ }
+ } else {
+ for c != 0 {
+ c--
+ pos--
+ if str[c] != unicode.ToLower(r.runtext[pos]) {
+ return false
+ }
+ }
+ }
+
+ if !r.rightToLeft {
+ pos += len(str)
+ }
+
+ r.runtextpos = pos
+
+ return true
+}
+
+func (r *runner) refmatch(index, len int) bool {
+ var c, pos, cmpos int
+
+ if !r.rightToLeft {
+ if r.runtextend-r.runtextpos < len {
+ return false
+ }
+
+ pos = r.runtextpos + len
+ } else {
+ if r.runtextpos-0 < len {
+ return false
+ }
+
+ pos = r.runtextpos
+ }
+ cmpos = index + len
+
+ c = len
+
+ if !r.caseInsensitive {
+ for c != 0 {
+ c--
+ cmpos--
+ pos--
+ if r.runtext[cmpos] != r.runtext[pos] {
+ return false
+ }
+
+ }
+ } else {
+ for c != 0 {
+ c--
+ cmpos--
+ pos--
+
+ if unicode.ToLower(r.runtext[cmpos]) != unicode.ToLower(r.runtext[pos]) {
+ return false
+ }
+ }
+ }
+
+ if !r.rightToLeft {
+ pos += len
+ }
+
+ r.runtextpos = pos
+
+ return true
+}
+
+func (r *runner) backwardnext() {
+ if r.rightToLeft {
+ r.runtextpos++
+ } else {
+ r.runtextpos--
+ }
+}
+
+func (r *runner) charAt(j int) rune {
+ return r.runtext[j]
+}
+
+func (r *runner) findFirstChar() bool {
+
+ if 0 != (r.code.Anchors & (syntax.AnchorBeginning | syntax.AnchorStart | syntax.AnchorEndZ | syntax.AnchorEnd)) {
+ if !r.code.RightToLeft {
+ if (0 != (r.code.Anchors&syntax.AnchorBeginning) && r.runtextpos > 0) ||
+ (0 != (r.code.Anchors&syntax.AnchorStart) && r.runtextpos > r.runtextstart) {
+ r.runtextpos = r.runtextend
+ return false
+ }
+ if 0 != (r.code.Anchors&syntax.AnchorEndZ) && r.runtextpos < r.runtextend-1 {
+ r.runtextpos = r.runtextend - 1
+ } else if 0 != (r.code.Anchors&syntax.AnchorEnd) && r.runtextpos < r.runtextend {
+ r.runtextpos = r.runtextend
+ }
+ } else {
+ if (0 != (r.code.Anchors&syntax.AnchorEnd) && r.runtextpos < r.runtextend) ||
+ (0 != (r.code.Anchors&syntax.AnchorEndZ) && (r.runtextpos < r.runtextend-1 ||
+ (r.runtextpos == r.runtextend-1 && r.charAt(r.runtextpos) != '\n'))) ||
+ (0 != (r.code.Anchors&syntax.AnchorStart) && r.runtextpos < r.runtextstart) {
+ r.runtextpos = 0
+ return false
+ }
+ if 0 != (r.code.Anchors&syntax.AnchorBeginning) && r.runtextpos > 0 {
+ r.runtextpos = 0
+ }
+ }
+
+ if r.code.BmPrefix != nil {
+ return r.code.BmPrefix.IsMatch(r.runtext, r.runtextpos, 0, r.runtextend)
+ }
+
+ return true // found a valid start or end anchor
+ } else if r.code.BmPrefix != nil {
+ r.runtextpos = r.code.BmPrefix.Scan(r.runtext, r.runtextpos, 0, r.runtextend)
+
+ if r.runtextpos == -1 {
+ if r.code.RightToLeft {
+ r.runtextpos = 0
+ } else {
+ r.runtextpos = r.runtextend
+ }
+ return false
+ }
+
+ return true
+ } else if r.code.FcPrefix == nil {
+ return true
+ }
+
+ r.rightToLeft = r.code.RightToLeft
+ r.caseInsensitive = r.code.FcPrefix.CaseInsensitive
+
+ set := r.code.FcPrefix.PrefixSet
+ if set.IsSingleton() {
+ ch := set.SingletonChar()
+ for i := r.forwardchars(); i > 0; i-- {
+ if ch == r.forwardcharnext() {
+ r.backwardnext()
+ return true
+ }
+ }
+ } else {
+ for i := r.forwardchars(); i > 0; i-- {
+ n := r.forwardcharnext()
+ //fmt.Printf("%v in %v: %v\n", string(n), set.String(), set.CharIn(n))
+ if set.CharIn(n) {
+ r.backwardnext()
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+func (r *runner) initMatch() {
+ // Use a hashtable'ed Match object if the capture numbers are sparse
+
+ if r.runmatch == nil {
+ if r.re.caps != nil {
+ r.runmatch = newMatchSparse(r.re, r.re.caps, r.re.capsize, r.runtext, r.runtextstart)
+ } else {
+ r.runmatch = newMatch(r.re, r.re.capsize, r.runtext, r.runtextstart)
+ }
+ } else {
+ r.runmatch.reset(r.runtext, r.runtextstart)
+ }
+
+ // note we test runcrawl, because it is the last one to be allocated
+ // If there is an alloc failure in the middle of the three allocations,
+ // we may still return to reuse this instance, and we want to behave
+ // as if the allocations didn't occur. (we used to test _trackcount != 0)
+
+ if r.runcrawl != nil {
+ r.runtrackpos = len(r.runtrack)
+ r.runstackpos = len(r.runstack)
+ r.runcrawlpos = len(r.runcrawl)
+ return
+ }
+
+ r.initTrackCount()
+
+ tracksize := r.runtrackcount * 8
+ stacksize := r.runtrackcount * 8
+
+ if tracksize < 32 {
+ tracksize = 32
+ }
+ if stacksize < 16 {
+ stacksize = 16
+ }
+
+ r.runtrack = make([]int, tracksize)
+ r.runtrackpos = tracksize
+
+ r.runstack = make([]int, stacksize)
+ r.runstackpos = stacksize
+
+ r.runcrawl = make([]int, 32)
+ r.runcrawlpos = 32
+}
+
+func (r *runner) tidyMatch(quick bool) *Match {
+ if !quick {
+ match := r.runmatch
+
+ r.runmatch = nil
+
+ match.tidy(r.runtextpos)
+ return match
+ } else {
+ // send back our match -- it's not leaving the package, so it's safe to not clean it up
+ // this reduces allocs for frequent calls to the "IsMatch" bool-only functions
+ return r.runmatch
+ }
+}
+
+// capture captures a subexpression. Note that the
+// capnum used here has already been mapped to a non-sparse
+// index (by the code generator RegexWriter).
+func (r *runner) capture(capnum, start, end int) {
+ if end < start {
+ T := end
+ end = start
+ start = T
+ }
+
+ r.crawl(capnum)
+ r.runmatch.addMatch(capnum, start, end-start)
+}
+
+// transferCapture captures a subexpression. Note that the
+// capnum used here has already been mapped to a non-sparse
+// index (by the code generator RegexWriter).
+func (r *runner) transferCapture(capnum, uncapnum, start, end int) {
+ var start2, end2 int
+
+ // these are the two intervals that are cancelling each other
+
+ if end < start {
+ T := end
+ end = start
+ start = T
+ }
+
+ start2 = r.runmatch.matchIndex(uncapnum)
+ end2 = start2 + r.runmatch.matchLength(uncapnum)
+
+ // The new capture gets the innermost defined interval
+
+ if start >= end2 {
+ end = start
+ start = end2
+ } else if end <= start2 {
+ start = start2
+ } else {
+ if end > end2 {
+ end = end2
+ }
+ if start2 > start {
+ start = start2
+ }
+ }
+
+ r.crawl(uncapnum)
+ r.runmatch.balanceMatch(uncapnum)
+
+ if capnum != -1 {
+ r.crawl(capnum)
+ r.runmatch.addMatch(capnum, start, end-start)
+ }
+}
+
+// revert the last capture
+func (r *runner) uncapture() {
+ capnum := r.popcrawl()
+ r.runmatch.removeMatch(capnum)
+}
+
+//debug
+
+func (r *runner) dumpState() {
+ back := ""
+ if r.operator&syntax.Back != 0 {
+ back = " Back"
+ }
+ if r.operator&syntax.Back2 != 0 {
+ back += " Back2"
+ }
+ fmt.Printf("Text: %v\nTrack: %v\nStack: %v\n %s%s\n\n",
+ r.textposDescription(),
+ r.stackDescription(r.runtrack, r.runtrackpos),
+ r.stackDescription(r.runstack, r.runstackpos),
+ r.code.OpcodeDescription(r.codepos),
+ back)
+}
+
+func (r *runner) stackDescription(a []int, index int) string {
+ buf := &bytes.Buffer{}
+
+ fmt.Fprintf(buf, "%v/%v", len(a)-index, len(a))
+ if buf.Len() < 8 {
+ buf.WriteString(strings.Repeat(" ", 8-buf.Len()))
+ }
+
+ buf.WriteRune('(')
+ for i := index; i < len(a); i++ {
+ if i > index {
+ buf.WriteRune(' ')
+ }
+
+ buf.WriteString(strconv.Itoa(a[i]))
+ }
+
+ buf.WriteRune(')')
+
+ return buf.String()
+}
+
+func (r *runner) textposDescription() string {
+ buf := &bytes.Buffer{}
+
+ buf.WriteString(strconv.Itoa(r.runtextpos))
+
+ if buf.Len() < 8 {
+ buf.WriteString(strings.Repeat(" ", 8-buf.Len()))
+ }
+
+ if r.runtextpos > 0 {
+ buf.WriteString(syntax.CharDescription(r.runtext[r.runtextpos-1]))
+ } else {
+ buf.WriteRune('^')
+ }
+
+ buf.WriteRune('>')
+
+ for i := r.runtextpos; i < r.runtextend; i++ {
+ buf.WriteString(syntax.CharDescription(r.runtext[i]))
+ }
+ if buf.Len() >= 64 {
+ buf.Truncate(61)
+ buf.WriteString("...")
+ } else {
+ buf.WriteRune('$')
+ }
+
+ return buf.String()
+}
+
+// decide whether the pos
+// at the specified index is a boundary or not. It's just not worth
+// emitting inline code for this logic.
+func (r *runner) isBoundary(index, startpos, endpos int) bool {
+ return (index > startpos && syntax.IsWordChar(r.runtext[index-1])) !=
+ (index < endpos && syntax.IsWordChar(r.runtext[index]))
+}
+
+func (r *runner) isECMABoundary(index, startpos, endpos int) bool {
+ return (index > startpos && syntax.IsECMAWordChar(r.runtext[index-1])) !=
+ (index < endpos && syntax.IsECMAWordChar(r.runtext[index]))
+}
+
+func (r *runner) startTimeoutWatch() {
+ if r.ignoreTimeout {
+ return
+ }
+ r.deadline = makeDeadline(r.timeout)
+}
+
+func (r *runner) checkTimeout() error {
+ if r.ignoreTimeout || !r.deadline.reached() {
+ return nil
+ }
+
+ if r.re.Debug() {
+ //Debug.WriteLine("")
+ //Debug.WriteLine("RegEx match timeout occurred!")
+ //Debug.WriteLine("Specified timeout: " + TimeSpan.FromMilliseconds(_timeout).ToString())
+ //Debug.WriteLine("Timeout check frequency: " + TimeoutCheckFrequency)
+ //Debug.WriteLine("Search pattern: " + _runregex._pattern)
+ //Debug.WriteLine("Input: " + r.runtext)
+ //Debug.WriteLine("About to throw RegexMatchTimeoutException.")
+ }
+
+ return fmt.Errorf("match timeout after %v on input `%v`", r.timeout, string(r.runtext))
+}
+
+func (r *runner) initTrackCount() {
+ r.runtrackcount = r.code.TrackCount
+}
+
+// getRunner returns a run to use for matching re.
+// It uses the re's runner cache if possible, to avoid
+// unnecessary allocation.
+func (re *Regexp) getRunner() *runner {
+ re.muRun.Lock()
+ if n := len(re.runner); n > 0 {
+ z := re.runner[n-1]
+ re.runner = re.runner[:n-1]
+ re.muRun.Unlock()
+ return z
+ }
+ re.muRun.Unlock()
+ z := &runner{
+ re: re,
+ code: re.code,
+ }
+ return z
+}
+
+// putRunner returns a runner to the re's cache.
+// There is no attempt to limit the size of the cache, so it will
+// grow to the maximum number of simultaneous matches
+// run using re. (The cache empties when re gets garbage collected.)
+func (re *Regexp) putRunner(r *runner) {
+ re.muRun.Lock()
+ r.runtext = nil
+ if r.runmatch != nil {
+ r.runmatch.text = nil
+ }
+ re.runner = append(re.runner, r)
+ re.muRun.Unlock()
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/charclass.go b/vendor/github.com/dlclark/regexp2/syntax/charclass.go
new file mode 100644
index 0000000..6881a0e
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/charclass.go
@@ -0,0 +1,865 @@
+package syntax
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "sort"
+ "unicode"
+ "unicode/utf8"
+)
+
+// CharSet combines start-end rune ranges and unicode categories representing a set of characters
+type CharSet struct {
+ ranges []singleRange
+ categories []category
+ sub *CharSet //optional subtractor
+ negate bool
+ anything bool
+}
+
+type category struct {
+ negate bool
+ cat string
+}
+
+type singleRange struct {
+ first rune
+ last rune
+}
+
+const (
+ spaceCategoryText = " "
+ wordCategoryText = "W"
+)
+
+var (
+ ecmaSpace = []rune{0x0009, 0x000e, 0x0020, 0x0021, 0x00a0, 0x00a1, 0x1680, 0x1681, 0x2000, 0x200b, 0x2028, 0x202a, 0x202f, 0x2030, 0x205f, 0x2060, 0x3000, 0x3001, 0xfeff, 0xff00}
+ ecmaWord = []rune{0x0030, 0x003a, 0x0041, 0x005b, 0x005f, 0x0060, 0x0061, 0x007b}
+ ecmaDigit = []rune{0x0030, 0x003a}
+
+ re2Space = []rune{0x0009, 0x000b, 0x000c, 0x000e, 0x0020, 0x0021}
+)
+
+var (
+ AnyClass = getCharSetFromOldString([]rune{0}, false)
+ ECMAAnyClass = getCharSetFromOldString([]rune{0, 0x000a, 0x000b, 0x000d, 0x000e}, false)
+ NoneClass = getCharSetFromOldString(nil, false)
+ ECMAWordClass = getCharSetFromOldString(ecmaWord, false)
+ NotECMAWordClass = getCharSetFromOldString(ecmaWord, true)
+ ECMASpaceClass = getCharSetFromOldString(ecmaSpace, false)
+ NotECMASpaceClass = getCharSetFromOldString(ecmaSpace, true)
+ ECMADigitClass = getCharSetFromOldString(ecmaDigit, false)
+ NotECMADigitClass = getCharSetFromOldString(ecmaDigit, true)
+
+ WordClass = getCharSetFromCategoryString(false, false, wordCategoryText)
+ NotWordClass = getCharSetFromCategoryString(true, false, wordCategoryText)
+ SpaceClass = getCharSetFromCategoryString(false, false, spaceCategoryText)
+ NotSpaceClass = getCharSetFromCategoryString(true, false, spaceCategoryText)
+ DigitClass = getCharSetFromCategoryString(false, false, "Nd")
+ NotDigitClass = getCharSetFromCategoryString(false, true, "Nd")
+
+ RE2SpaceClass = getCharSetFromOldString(re2Space, false)
+ NotRE2SpaceClass = getCharSetFromOldString(re2Space, true)
+)
+
+var unicodeCategories = func() map[string]*unicode.RangeTable {
+ retVal := make(map[string]*unicode.RangeTable)
+ for k, v := range unicode.Scripts {
+ retVal[k] = v
+ }
+ for k, v := range unicode.Categories {
+ retVal[k] = v
+ }
+ for k, v := range unicode.Properties {
+ retVal[k] = v
+ }
+ return retVal
+}()
+
+func getCharSetFromCategoryString(negateSet bool, negateCat bool, cats ...string) func() *CharSet {
+ if negateCat && negateSet {
+ panic("BUG! You should only negate the set OR the category in a constant setup, but not both")
+ }
+
+ c := CharSet{negate: negateSet}
+
+ c.categories = make([]category, len(cats))
+ for i, cat := range cats {
+ c.categories[i] = category{cat: cat, negate: negateCat}
+ }
+ return func() *CharSet {
+ //make a copy each time
+ local := c
+ //return that address
+ return &local
+ }
+}
+
+func getCharSetFromOldString(setText []rune, negate bool) func() *CharSet {
+ c := CharSet{}
+ if len(setText) > 0 {
+ fillFirst := false
+ l := len(setText)
+ if negate {
+ if setText[0] == 0 {
+ setText = setText[1:]
+ } else {
+ l++
+ fillFirst = true
+ }
+ }
+
+ if l%2 == 0 {
+ c.ranges = make([]singleRange, l/2)
+ } else {
+ c.ranges = make([]singleRange, l/2+1)
+ }
+
+ first := true
+ if fillFirst {
+ c.ranges[0] = singleRange{first: 0}
+ first = false
+ }
+
+ i := 0
+ for _, r := range setText {
+ if first {
+ // lower bound in a new range
+ c.ranges[i] = singleRange{first: r}
+ first = false
+ } else {
+ c.ranges[i].last = r - 1
+ i++
+ first = true
+ }
+ }
+ if !first {
+ c.ranges[i].last = utf8.MaxRune
+ }
+ }
+
+ return func() *CharSet {
+ local := c
+ return &local
+ }
+}
+
+// Copy makes a deep copy to prevent accidental mutation of a set
+func (c CharSet) Copy() CharSet {
+ ret := CharSet{
+ anything: c.anything,
+ negate: c.negate,
+ }
+
+ ret.ranges = append(ret.ranges, c.ranges...)
+ ret.categories = append(ret.categories, c.categories...)
+
+ if c.sub != nil {
+ sub := c.sub.Copy()
+ ret.sub = &sub
+ }
+
+ return ret
+}
+
+// gets a human-readable description for a set string
+func (c CharSet) String() string {
+ buf := &bytes.Buffer{}
+ buf.WriteRune('[')
+
+ if c.IsNegated() {
+ buf.WriteRune('^')
+ }
+
+ for _, r := range c.ranges {
+
+ buf.WriteString(CharDescription(r.first))
+ if r.first != r.last {
+ if r.last-r.first != 1 {
+ //groups that are 1 char apart skip the dash
+ buf.WriteRune('-')
+ }
+ buf.WriteString(CharDescription(r.last))
+ }
+ }
+
+ for _, c := range c.categories {
+ buf.WriteString(c.String())
+ }
+
+ if c.sub != nil {
+ buf.WriteRune('-')
+ buf.WriteString(c.sub.String())
+ }
+
+ buf.WriteRune(']')
+
+ return buf.String()
+}
+
+// mapHashFill converts a charset into a buffer for use in maps
+func (c CharSet) mapHashFill(buf *bytes.Buffer) {
+ if c.negate {
+ buf.WriteByte(0)
+ } else {
+ buf.WriteByte(1)
+ }
+
+ binary.Write(buf, binary.LittleEndian, len(c.ranges))
+ binary.Write(buf, binary.LittleEndian, len(c.categories))
+ for _, r := range c.ranges {
+ buf.WriteRune(r.first)
+ buf.WriteRune(r.last)
+ }
+ for _, ct := range c.categories {
+ buf.WriteString(ct.cat)
+ if ct.negate {
+ buf.WriteByte(1)
+ } else {
+ buf.WriteByte(0)
+ }
+ }
+
+ if c.sub != nil {
+ c.sub.mapHashFill(buf)
+ }
+}
+
+// CharIn returns true if the rune is in our character set (either ranges or categories).
+// It handles negations and subtracted sub-charsets.
+func (c CharSet) CharIn(ch rune) bool {
+ val := false
+ // in s && !s.subtracted
+
+ //check ranges
+ for _, r := range c.ranges {
+ if ch < r.first {
+ continue
+ }
+ if ch <= r.last {
+ val = true
+ break
+ }
+ }
+
+ //check categories if we haven't already found a range
+ if !val && len(c.categories) > 0 {
+ for _, ct := range c.categories {
+ // special categories...then unicode
+ if ct.cat == spaceCategoryText {
+ if unicode.IsSpace(ch) {
+ // we found a space so we're done
+ // negate means this is a "bad" thing
+ val = !ct.negate
+ break
+ } else if ct.negate {
+ val = true
+ break
+ }
+ } else if ct.cat == wordCategoryText {
+ if IsWordChar(ch) {
+ val = !ct.negate
+ break
+ } else if ct.negate {
+ val = true
+ break
+ }
+ } else if unicode.Is(unicodeCategories[ct.cat], ch) {
+ // if we're in this unicode category then we're done
+ // if negate=true on this category then we "failed" our test
+ // otherwise we're good that we found it
+ val = !ct.negate
+ break
+ } else if ct.negate {
+ val = true
+ break
+ }
+ }
+ }
+
+ // negate the whole char set
+ if c.negate {
+ val = !val
+ }
+
+ // get subtracted recurse
+ if val && c.sub != nil {
+ val = !c.sub.CharIn(ch)
+ }
+
+ //log.Printf("Char '%v' in %v == %v", string(ch), c.String(), val)
+ return val
+}
+
+func (c category) String() string {
+ switch c.cat {
+ case spaceCategoryText:
+ if c.negate {
+ return "\\S"
+ }
+ return "\\s"
+ case wordCategoryText:
+ if c.negate {
+ return "\\W"
+ }
+ return "\\w"
+ }
+ if _, ok := unicodeCategories[c.cat]; ok {
+
+ if c.negate {
+ return "\\P{" + c.cat + "}"
+ }
+ return "\\p{" + c.cat + "}"
+ }
+ return "Unknown category: " + c.cat
+}
+
+// CharDescription Produces a human-readable description for a single character.
+func CharDescription(ch rune) string {
+ /*if ch == '\\' {
+ return "\\\\"
+ }
+
+ if ch > ' ' && ch <= '~' {
+ return string(ch)
+ } else if ch == '\n' {
+ return "\\n"
+ } else if ch == ' ' {
+ return "\\ "
+ }*/
+
+ b := &bytes.Buffer{}
+ escape(b, ch, false) //fmt.Sprintf("%U", ch)
+ return b.String()
+}
+
+// According to UTS#18 Unicode Regular Expressions (http://www.unicode.org/reports/tr18/)
+// RL 1.4 Simple Word Boundaries The class of includes all Alphabetic
+// values from the Unicode character database, from UnicodeData.txt [UData], plus the U+200C
+// ZERO WIDTH NON-JOINER and U+200D ZERO WIDTH JOINER.
+func IsWordChar(r rune) bool {
+ //"L", "Mn", "Nd", "Pc"
+ return unicode.In(r,
+ unicode.Categories["L"], unicode.Categories["Mn"],
+ unicode.Categories["Nd"], unicode.Categories["Pc"]) || r == '\u200D' || r == '\u200C'
+ //return 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' || '0' <= r && r <= '9' || r == '_'
+}
+
+func IsECMAWordChar(r rune) bool {
+ return unicode.In(r,
+ unicode.Categories["L"], unicode.Categories["Mn"],
+ unicode.Categories["Nd"], unicode.Categories["Pc"])
+
+ //return 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' || '0' <= r && r <= '9' || r == '_'
+}
+
+// SingletonChar will return the char from the first range without validation.
+// It assumes you have checked for IsSingleton or IsSingletonInverse and will panic given bad input
+func (c CharSet) SingletonChar() rune {
+ return c.ranges[0].first
+}
+
+func (c CharSet) IsSingleton() bool {
+ return !c.negate && //negated is multiple chars
+ len(c.categories) == 0 && len(c.ranges) == 1 && // multiple ranges and unicode classes represent multiple chars
+ c.sub == nil && // subtraction means we've got multiple chars
+ c.ranges[0].first == c.ranges[0].last // first and last equal means we're just 1 char
+}
+
+func (c CharSet) IsSingletonInverse() bool {
+ return c.negate && //same as above, but requires negated
+ len(c.categories) == 0 && len(c.ranges) == 1 && // multiple ranges and unicode classes represent multiple chars
+ c.sub == nil && // subtraction means we've got multiple chars
+ c.ranges[0].first == c.ranges[0].last // first and last equal means we're just 1 char
+}
+
+func (c CharSet) IsMergeable() bool {
+ return !c.IsNegated() && !c.HasSubtraction()
+}
+
+func (c CharSet) IsNegated() bool {
+ return c.negate
+}
+
+func (c CharSet) HasSubtraction() bool {
+ return c.sub != nil
+}
+
+func (c CharSet) IsEmpty() bool {
+ return len(c.ranges) == 0 && len(c.categories) == 0 && c.sub == nil
+}
+
+func (c *CharSet) addDigit(ecma, negate bool, pattern string) {
+ if ecma {
+ if negate {
+ c.addRanges(NotECMADigitClass().ranges)
+ } else {
+ c.addRanges(ECMADigitClass().ranges)
+ }
+ } else {
+ c.addCategories(category{cat: "Nd", negate: negate})
+ }
+}
+
+func (c *CharSet) addChar(ch rune) {
+ c.addRange(ch, ch)
+}
+
+func (c *CharSet) addSpace(ecma, re2, negate bool) {
+ if ecma {
+ if negate {
+ c.addRanges(NotECMASpaceClass().ranges)
+ } else {
+ c.addRanges(ECMASpaceClass().ranges)
+ }
+ } else if re2 {
+ if negate {
+ c.addRanges(NotRE2SpaceClass().ranges)
+ } else {
+ c.addRanges(RE2SpaceClass().ranges)
+ }
+ } else {
+ c.addCategories(category{cat: spaceCategoryText, negate: negate})
+ }
+}
+
+func (c *CharSet) addWord(ecma, negate bool) {
+ if ecma {
+ if negate {
+ c.addRanges(NotECMAWordClass().ranges)
+ } else {
+ c.addRanges(ECMAWordClass().ranges)
+ }
+ } else {
+ c.addCategories(category{cat: wordCategoryText, negate: negate})
+ }
+}
+
+// Add set ranges and categories into ours -- no deduping or anything
+func (c *CharSet) addSet(set CharSet) {
+ if c.anything {
+ return
+ }
+ if set.anything {
+ c.makeAnything()
+ return
+ }
+ // just append here to prevent double-canon
+ c.ranges = append(c.ranges, set.ranges...)
+ c.addCategories(set.categories...)
+ c.canonicalize()
+}
+
+func (c *CharSet) makeAnything() {
+ c.anything = true
+ c.categories = []category{}
+ c.ranges = AnyClass().ranges
+}
+
+func (c *CharSet) addCategories(cats ...category) {
+ // don't add dupes and remove positive+negative
+ if c.anything {
+ // if we've had a previous positive+negative group then
+ // just return, we're as broad as we can get
+ return
+ }
+
+ for _, ct := range cats {
+ found := false
+ for _, ct2 := range c.categories {
+ if ct.cat == ct2.cat {
+ if ct.negate != ct2.negate {
+ // oposite negations...this mean we just
+ // take us as anything and move on
+ c.makeAnything()
+ return
+ }
+ found = true
+ break
+ }
+ }
+
+ if !found {
+ c.categories = append(c.categories, ct)
+ }
+ }
+}
+
+// Merges new ranges to our own
+func (c *CharSet) addRanges(ranges []singleRange) {
+ if c.anything {
+ return
+ }
+ c.ranges = append(c.ranges, ranges...)
+ c.canonicalize()
+}
+
+// Merges everything but the new ranges into our own
+func (c *CharSet) addNegativeRanges(ranges []singleRange) {
+ if c.anything {
+ return
+ }
+
+ var hi rune
+
+ // convert incoming ranges into opposites, assume they are in order
+ for _, r := range ranges {
+ if hi < r.first {
+ c.ranges = append(c.ranges, singleRange{hi, r.first - 1})
+ }
+ hi = r.last + 1
+ }
+
+ if hi < utf8.MaxRune {
+ c.ranges = append(c.ranges, singleRange{hi, utf8.MaxRune})
+ }
+
+ c.canonicalize()
+}
+
+func isValidUnicodeCat(catName string) bool {
+ _, ok := unicodeCategories[catName]
+ return ok
+}
+
+func (c *CharSet) addCategory(categoryName string, negate, caseInsensitive bool, pattern string) {
+ if !isValidUnicodeCat(categoryName) {
+ // unknown unicode category, script, or property "blah"
+ panic(fmt.Errorf("Unknown unicode category, script, or property '%v'", categoryName))
+
+ }
+
+ if caseInsensitive && (categoryName == "Ll" || categoryName == "Lu" || categoryName == "Lt") {
+ // when RegexOptions.IgnoreCase is specified then {Ll} {Lu} and {Lt} cases should all match
+ c.addCategories(
+ category{cat: "Ll", negate: negate},
+ category{cat: "Lu", negate: negate},
+ category{cat: "Lt", negate: negate})
+ }
+ c.addCategories(category{cat: categoryName, negate: negate})
+}
+
+func (c *CharSet) addSubtraction(sub *CharSet) {
+ c.sub = sub
+}
+
+func (c *CharSet) addRange(chMin, chMax rune) {
+ c.ranges = append(c.ranges, singleRange{first: chMin, last: chMax})
+ c.canonicalize()
+}
+
+func (c *CharSet) addNamedASCII(name string, negate bool) bool {
+ var rs []singleRange
+
+ switch name {
+ case "alnum":
+ rs = []singleRange{singleRange{'0', '9'}, singleRange{'A', 'Z'}, singleRange{'a', 'z'}}
+ case "alpha":
+ rs = []singleRange{singleRange{'A', 'Z'}, singleRange{'a', 'z'}}
+ case "ascii":
+ rs = []singleRange{singleRange{0, 0x7f}}
+ case "blank":
+ rs = []singleRange{singleRange{'\t', '\t'}, singleRange{' ', ' '}}
+ case "cntrl":
+ rs = []singleRange{singleRange{0, 0x1f}, singleRange{0x7f, 0x7f}}
+ case "digit":
+ c.addDigit(false, negate, "")
+ case "graph":
+ rs = []singleRange{singleRange{'!', '~'}}
+ case "lower":
+ rs = []singleRange{singleRange{'a', 'z'}}
+ case "print":
+ rs = []singleRange{singleRange{' ', '~'}}
+ case "punct": //[!-/:-@[-`{-~]
+ rs = []singleRange{singleRange{'!', '/'}, singleRange{':', '@'}, singleRange{'[', '`'}, singleRange{'{', '~'}}
+ case "space":
+ c.addSpace(true, false, negate)
+ case "upper":
+ rs = []singleRange{singleRange{'A', 'Z'}}
+ case "word":
+ c.addWord(true, negate)
+ case "xdigit":
+ rs = []singleRange{singleRange{'0', '9'}, singleRange{'A', 'F'}, singleRange{'a', 'f'}}
+ default:
+ return false
+ }
+
+ if len(rs) > 0 {
+ if negate {
+ c.addNegativeRanges(rs)
+ } else {
+ c.addRanges(rs)
+ }
+ }
+
+ return true
+}
+
+type singleRangeSorter []singleRange
+
+func (p singleRangeSorter) Len() int { return len(p) }
+func (p singleRangeSorter) Less(i, j int) bool { return p[i].first < p[j].first }
+func (p singleRangeSorter) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+
+// Logic to reduce a character class to a unique, sorted form.
+func (c *CharSet) canonicalize() {
+ var i, j int
+ var last rune
+
+ //
+ // Find and eliminate overlapping or abutting ranges
+ //
+
+ if len(c.ranges) > 1 {
+ sort.Sort(singleRangeSorter(c.ranges))
+
+ done := false
+
+ for i, j = 1, 0; ; i++ {
+ for last = c.ranges[j].last; ; i++ {
+ if i == len(c.ranges) || last == utf8.MaxRune {
+ done = true
+ break
+ }
+
+ CurrentRange := c.ranges[i]
+ if CurrentRange.first > last+1 {
+ break
+ }
+
+ if last < CurrentRange.last {
+ last = CurrentRange.last
+ }
+ }
+
+ c.ranges[j] = singleRange{first: c.ranges[j].first, last: last}
+
+ j++
+
+ if done {
+ break
+ }
+
+ if j < i {
+ c.ranges[j] = c.ranges[i]
+ }
+ }
+
+ c.ranges = append(c.ranges[:j], c.ranges[len(c.ranges):]...)
+ }
+}
+
+// Adds to the class any lowercase versions of characters already
+// in the class. Used for case-insensitivity.
+func (c *CharSet) addLowercase() {
+ if c.anything {
+ return
+ }
+ toAdd := []singleRange{}
+ for i := 0; i < len(c.ranges); i++ {
+ r := c.ranges[i]
+ if r.first == r.last {
+ lower := unicode.ToLower(r.first)
+ c.ranges[i] = singleRange{first: lower, last: lower}
+ } else {
+ toAdd = append(toAdd, r)
+ }
+ }
+
+ for _, r := range toAdd {
+ c.addLowercaseRange(r.first, r.last)
+ }
+ c.canonicalize()
+}
+
+/**************************************************************************
+ Let U be the set of Unicode character values and let L be the lowercase
+ function, mapping from U to U. To perform case insensitive matching of
+ character sets, we need to be able to map an interval I in U, say
+
+ I = [chMin, chMax] = { ch : chMin <= ch <= chMax }
+
+ to a set A such that A contains L(I) and A is contained in the union of
+ I and L(I).
+
+ The table below partitions U into intervals on which L is non-decreasing.
+ Thus, for any interval J = [a, b] contained in one of these intervals,
+ L(J) is contained in [L(a), L(b)].
+
+ It is also true that for any such J, [L(a), L(b)] is contained in the
+ union of J and L(J). This does not follow from L being non-decreasing on
+ these intervals. It follows from the nature of the L on each interval.
+ On each interval, L has one of the following forms:
+
+ (1) L(ch) = constant (LowercaseSet)
+ (2) L(ch) = ch + offset (LowercaseAdd)
+ (3) L(ch) = ch | 1 (LowercaseBor)
+ (4) L(ch) = ch + (ch & 1) (LowercaseBad)
+
+ It is easy to verify that for any of these forms [L(a), L(b)] is
+ contained in the union of [a, b] and L([a, b]).
+***************************************************************************/
+
+const (
+ LowercaseSet = 0 // Set to arg.
+ LowercaseAdd = 1 // Add arg.
+ LowercaseBor = 2 // Bitwise or with 1.
+ LowercaseBad = 3 // Bitwise and with 1 and add original.
+)
+
+type lcMap struct {
+ chMin, chMax rune
+ op, data int32
+}
+
+var lcTable = []lcMap{
+ lcMap{'\u0041', '\u005A', LowercaseAdd, 32},
+ lcMap{'\u00C0', '\u00DE', LowercaseAdd, 32},
+ lcMap{'\u0100', '\u012E', LowercaseBor, 0},
+ lcMap{'\u0130', '\u0130', LowercaseSet, 0x0069},
+ lcMap{'\u0132', '\u0136', LowercaseBor, 0},
+ lcMap{'\u0139', '\u0147', LowercaseBad, 0},
+ lcMap{'\u014A', '\u0176', LowercaseBor, 0},
+ lcMap{'\u0178', '\u0178', LowercaseSet, 0x00FF},
+ lcMap{'\u0179', '\u017D', LowercaseBad, 0},
+ lcMap{'\u0181', '\u0181', LowercaseSet, 0x0253},
+ lcMap{'\u0182', '\u0184', LowercaseBor, 0},
+ lcMap{'\u0186', '\u0186', LowercaseSet, 0x0254},
+ lcMap{'\u0187', '\u0187', LowercaseSet, 0x0188},
+ lcMap{'\u0189', '\u018A', LowercaseAdd, 205},
+ lcMap{'\u018B', '\u018B', LowercaseSet, 0x018C},
+ lcMap{'\u018E', '\u018E', LowercaseSet, 0x01DD},
+ lcMap{'\u018F', '\u018F', LowercaseSet, 0x0259},
+ lcMap{'\u0190', '\u0190', LowercaseSet, 0x025B},
+ lcMap{'\u0191', '\u0191', LowercaseSet, 0x0192},
+ lcMap{'\u0193', '\u0193', LowercaseSet, 0x0260},
+ lcMap{'\u0194', '\u0194', LowercaseSet, 0x0263},
+ lcMap{'\u0196', '\u0196', LowercaseSet, 0x0269},
+ lcMap{'\u0197', '\u0197', LowercaseSet, 0x0268},
+ lcMap{'\u0198', '\u0198', LowercaseSet, 0x0199},
+ lcMap{'\u019C', '\u019C', LowercaseSet, 0x026F},
+ lcMap{'\u019D', '\u019D', LowercaseSet, 0x0272},
+ lcMap{'\u019F', '\u019F', LowercaseSet, 0x0275},
+ lcMap{'\u01A0', '\u01A4', LowercaseBor, 0},
+ lcMap{'\u01A7', '\u01A7', LowercaseSet, 0x01A8},
+ lcMap{'\u01A9', '\u01A9', LowercaseSet, 0x0283},
+ lcMap{'\u01AC', '\u01AC', LowercaseSet, 0x01AD},
+ lcMap{'\u01AE', '\u01AE', LowercaseSet, 0x0288},
+ lcMap{'\u01AF', '\u01AF', LowercaseSet, 0x01B0},
+ lcMap{'\u01B1', '\u01B2', LowercaseAdd, 217},
+ lcMap{'\u01B3', '\u01B5', LowercaseBad, 0},
+ lcMap{'\u01B7', '\u01B7', LowercaseSet, 0x0292},
+ lcMap{'\u01B8', '\u01B8', LowercaseSet, 0x01B9},
+ lcMap{'\u01BC', '\u01BC', LowercaseSet, 0x01BD},
+ lcMap{'\u01C4', '\u01C5', LowercaseSet, 0x01C6},
+ lcMap{'\u01C7', '\u01C8', LowercaseSet, 0x01C9},
+ lcMap{'\u01CA', '\u01CB', LowercaseSet, 0x01CC},
+ lcMap{'\u01CD', '\u01DB', LowercaseBad, 0},
+ lcMap{'\u01DE', '\u01EE', LowercaseBor, 0},
+ lcMap{'\u01F1', '\u01F2', LowercaseSet, 0x01F3},
+ lcMap{'\u01F4', '\u01F4', LowercaseSet, 0x01F5},
+ lcMap{'\u01FA', '\u0216', LowercaseBor, 0},
+ lcMap{'\u0386', '\u0386', LowercaseSet, 0x03AC},
+ lcMap{'\u0388', '\u038A', LowercaseAdd, 37},
+ lcMap{'\u038C', '\u038C', LowercaseSet, 0x03CC},
+ lcMap{'\u038E', '\u038F', LowercaseAdd, 63},
+ lcMap{'\u0391', '\u03AB', LowercaseAdd, 32},
+ lcMap{'\u03E2', '\u03EE', LowercaseBor, 0},
+ lcMap{'\u0401', '\u040F', LowercaseAdd, 80},
+ lcMap{'\u0410', '\u042F', LowercaseAdd, 32},
+ lcMap{'\u0460', '\u0480', LowercaseBor, 0},
+ lcMap{'\u0490', '\u04BE', LowercaseBor, 0},
+ lcMap{'\u04C1', '\u04C3', LowercaseBad, 0},
+ lcMap{'\u04C7', '\u04C7', LowercaseSet, 0x04C8},
+ lcMap{'\u04CB', '\u04CB', LowercaseSet, 0x04CC},
+ lcMap{'\u04D0', '\u04EA', LowercaseBor, 0},
+ lcMap{'\u04EE', '\u04F4', LowercaseBor, 0},
+ lcMap{'\u04F8', '\u04F8', LowercaseSet, 0x04F9},
+ lcMap{'\u0531', '\u0556', LowercaseAdd, 48},
+ lcMap{'\u10A0', '\u10C5', LowercaseAdd, 48},
+ lcMap{'\u1E00', '\u1EF8', LowercaseBor, 0},
+ lcMap{'\u1F08', '\u1F0F', LowercaseAdd, -8},
+ lcMap{'\u1F18', '\u1F1F', LowercaseAdd, -8},
+ lcMap{'\u1F28', '\u1F2F', LowercaseAdd, -8},
+ lcMap{'\u1F38', '\u1F3F', LowercaseAdd, -8},
+ lcMap{'\u1F48', '\u1F4D', LowercaseAdd, -8},
+ lcMap{'\u1F59', '\u1F59', LowercaseSet, 0x1F51},
+ lcMap{'\u1F5B', '\u1F5B', LowercaseSet, 0x1F53},
+ lcMap{'\u1F5D', '\u1F5D', LowercaseSet, 0x1F55},
+ lcMap{'\u1F5F', '\u1F5F', LowercaseSet, 0x1F57},
+ lcMap{'\u1F68', '\u1F6F', LowercaseAdd, -8},
+ lcMap{'\u1F88', '\u1F8F', LowercaseAdd, -8},
+ lcMap{'\u1F98', '\u1F9F', LowercaseAdd, -8},
+ lcMap{'\u1FA8', '\u1FAF', LowercaseAdd, -8},
+ lcMap{'\u1FB8', '\u1FB9', LowercaseAdd, -8},
+ lcMap{'\u1FBA', '\u1FBB', LowercaseAdd, -74},
+ lcMap{'\u1FBC', '\u1FBC', LowercaseSet, 0x1FB3},
+ lcMap{'\u1FC8', '\u1FCB', LowercaseAdd, -86},
+ lcMap{'\u1FCC', '\u1FCC', LowercaseSet, 0x1FC3},
+ lcMap{'\u1FD8', '\u1FD9', LowercaseAdd, -8},
+ lcMap{'\u1FDA', '\u1FDB', LowercaseAdd, -100},
+ lcMap{'\u1FE8', '\u1FE9', LowercaseAdd, -8},
+ lcMap{'\u1FEA', '\u1FEB', LowercaseAdd, -112},
+ lcMap{'\u1FEC', '\u1FEC', LowercaseSet, 0x1FE5},
+ lcMap{'\u1FF8', '\u1FF9', LowercaseAdd, -128},
+ lcMap{'\u1FFA', '\u1FFB', LowercaseAdd, -126},
+ lcMap{'\u1FFC', '\u1FFC', LowercaseSet, 0x1FF3},
+ lcMap{'\u2160', '\u216F', LowercaseAdd, 16},
+ lcMap{'\u24B6', '\u24D0', LowercaseAdd, 26},
+ lcMap{'\uFF21', '\uFF3A', LowercaseAdd, 32},
+}
+
+func (c *CharSet) addLowercaseRange(chMin, chMax rune) {
+ var i, iMax, iMid int
+ var chMinT, chMaxT rune
+ var lc lcMap
+
+ for i, iMax = 0, len(lcTable); i < iMax; {
+ iMid = (i + iMax) / 2
+ if lcTable[iMid].chMax < chMin {
+ i = iMid + 1
+ } else {
+ iMax = iMid
+ }
+ }
+
+ for ; i < len(lcTable); i++ {
+ lc = lcTable[i]
+ if lc.chMin > chMax {
+ return
+ }
+ chMinT = lc.chMin
+ if chMinT < chMin {
+ chMinT = chMin
+ }
+
+ chMaxT = lc.chMax
+ if chMaxT > chMax {
+ chMaxT = chMax
+ }
+
+ switch lc.op {
+ case LowercaseSet:
+ chMinT = rune(lc.data)
+ chMaxT = rune(lc.data)
+ break
+ case LowercaseAdd:
+ chMinT += lc.data
+ chMaxT += lc.data
+ break
+ case LowercaseBor:
+ chMinT |= 1
+ chMaxT |= 1
+ break
+ case LowercaseBad:
+ chMinT += (chMinT & 1)
+ chMaxT += (chMaxT & 1)
+ break
+ }
+
+ if chMinT < chMin || chMaxT > chMax {
+ c.addRange(chMinT, chMaxT)
+ }
+ }
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/code.go b/vendor/github.com/dlclark/regexp2/syntax/code.go
new file mode 100644
index 0000000..686e822
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/code.go
@@ -0,0 +1,274 @@
+package syntax
+
+import (
+ "bytes"
+ "fmt"
+ "math"
+)
+
+// similar to prog.go in the go regex package...also with comment 'may not belong in this package'
+
+// File provides operator constants for use by the Builder and the Machine.
+
+// Implementation notes:
+//
+// Regexps are built into RegexCodes, which contain an operation array,
+// a string table, and some constants.
+//
+// Each operation is one of the codes below, followed by the integer
+// operands specified for each op.
+//
+// Strings and sets are indices into a string table.
+
+type InstOp int
+
+const (
+ // lef/back operands description
+
+ Onerep InstOp = 0 // lef,back char,min,max a {n}
+ Notonerep = 1 // lef,back char,min,max .{n}
+ Setrep = 2 // lef,back set,min,max [\d]{n}
+
+ Oneloop = 3 // lef,back char,min,max a {,n}
+ Notoneloop = 4 // lef,back char,min,max .{,n}
+ Setloop = 5 // lef,back set,min,max [\d]{,n}
+
+ Onelazy = 6 // lef,back char,min,max a {,n}?
+ Notonelazy = 7 // lef,back char,min,max .{,n}?
+ Setlazy = 8 // lef,back set,min,max [\d]{,n}?
+
+ One = 9 // lef char a
+ Notone = 10 // lef char [^a]
+ Set = 11 // lef set [a-z\s] \w \s \d
+
+ Multi = 12 // lef string abcd
+ Ref = 13 // lef group \#
+
+ Bol = 14 // ^
+ Eol = 15 // $
+ Boundary = 16 // \b
+ Nonboundary = 17 // \B
+ Beginning = 18 // \A
+ Start = 19 // \G
+ EndZ = 20 // \Z
+ End = 21 // \Z
+
+ Nothing = 22 // Reject!
+
+ // Primitive control structures
+
+ Lazybranch = 23 // back jump straight first
+ Branchmark = 24 // back jump branch first for loop
+ Lazybranchmark = 25 // back jump straight first for loop
+ Nullcount = 26 // back val set counter, null mark
+ Setcount = 27 // back val set counter, make mark
+ Branchcount = 28 // back jump,limit branch++ if zero<=c impl group slots
+ Capsize int // number of impl group slots
+ FcPrefix *Prefix // the set of candidate first characters (may be null)
+ BmPrefix *BmPrefix // the fixed prefix string as a Boyer-Moore machine (may be null)
+ Anchors AnchorLoc // the set of zero-length start anchors (RegexFCD.Bol, etc)
+ RightToLeft bool // true if right to left
+}
+
+func opcodeBacktracks(op InstOp) bool {
+ op &= Mask
+
+ switch op {
+ case Oneloop, Notoneloop, Setloop, Onelazy, Notonelazy, Setlazy, Lazybranch, Branchmark, Lazybranchmark,
+ Nullcount, Setcount, Branchcount, Lazybranchcount, Setmark, Capturemark, Getmark, Setjump, Backjump,
+ Forejump, Goto:
+ return true
+
+ default:
+ return false
+ }
+}
+
+func opcodeSize(op InstOp) int {
+ op &= Mask
+
+ switch op {
+ case Nothing, Bol, Eol, Boundary, Nonboundary, ECMABoundary, NonECMABoundary, Beginning, Start, EndZ,
+ End, Nullmark, Setmark, Getmark, Setjump, Backjump, Forejump, Stop:
+ return 1
+
+ case One, Notone, Multi, Ref, Testref, Goto, Nullcount, Setcount, Lazybranch, Branchmark, Lazybranchmark,
+ Prune, Set:
+ return 2
+
+ case Capturemark, Branchcount, Lazybranchcount, Onerep, Notonerep, Oneloop, Notoneloop, Onelazy, Notonelazy,
+ Setlazy, Setrep, Setloop:
+ return 3
+
+ default:
+ panic(fmt.Errorf("Unexpected op code: %v", op))
+ }
+}
+
+var codeStr = []string{
+ "Onerep", "Notonerep", "Setrep",
+ "Oneloop", "Notoneloop", "Setloop",
+ "Onelazy", "Notonelazy", "Setlazy",
+ "One", "Notone", "Set",
+ "Multi", "Ref",
+ "Bol", "Eol", "Boundary", "Nonboundary", "Beginning", "Start", "EndZ", "End",
+ "Nothing",
+ "Lazybranch", "Branchmark", "Lazybranchmark",
+ "Nullcount", "Setcount", "Branchcount", "Lazybranchcount",
+ "Nullmark", "Setmark", "Capturemark", "Getmark",
+ "Setjump", "Backjump", "Forejump", "Testref", "Goto",
+ "Prune", "Stop",
+ "ECMABoundary", "NonECMABoundary",
+}
+
+func operatorDescription(op InstOp) string {
+ desc := codeStr[op&Mask]
+ if (op & Ci) != 0 {
+ desc += "-Ci"
+ }
+ if (op & Rtl) != 0 {
+ desc += "-Rtl"
+ }
+ if (op & Back) != 0 {
+ desc += "-Back"
+ }
+ if (op & Back2) != 0 {
+ desc += "-Back2"
+ }
+
+ return desc
+}
+
+// OpcodeDescription is a humman readable string of the specific offset
+func (c *Code) OpcodeDescription(offset int) string {
+ buf := &bytes.Buffer{}
+
+ op := InstOp(c.Codes[offset])
+ fmt.Fprintf(buf, "%06d ", offset)
+
+ if opcodeBacktracks(op & Mask) {
+ buf.WriteString("*")
+ } else {
+ buf.WriteString(" ")
+ }
+ buf.WriteString(operatorDescription(op))
+ buf.WriteString("(")
+ op &= Mask
+
+ switch op {
+ case One, Notone, Onerep, Notonerep, Oneloop, Notoneloop, Onelazy, Notonelazy:
+ buf.WriteString("Ch = ")
+ buf.WriteString(CharDescription(rune(c.Codes[offset+1])))
+
+ case Set, Setrep, Setloop, Setlazy:
+ buf.WriteString("Set = ")
+ buf.WriteString(c.Sets[c.Codes[offset+1]].String())
+
+ case Multi:
+ fmt.Fprintf(buf, "String = %s", string(c.Strings[c.Codes[offset+1]]))
+
+ case Ref, Testref:
+ fmt.Fprintf(buf, "Index = %d", c.Codes[offset+1])
+
+ case Capturemark:
+ fmt.Fprintf(buf, "Index = %d", c.Codes[offset+1])
+ if c.Codes[offset+2] != -1 {
+ fmt.Fprintf(buf, ", Unindex = %d", c.Codes[offset+2])
+ }
+
+ case Nullcount, Setcount:
+ fmt.Fprintf(buf, "Value = %d", c.Codes[offset+1])
+
+ case Goto, Lazybranch, Branchmark, Lazybranchmark, Branchcount, Lazybranchcount:
+ fmt.Fprintf(buf, "Addr = %d", c.Codes[offset+1])
+ }
+
+ switch op {
+ case Onerep, Notonerep, Oneloop, Notoneloop, Onelazy, Notonelazy, Setrep, Setloop, Setlazy:
+ buf.WriteString(", Rep = ")
+ if c.Codes[offset+2] == math.MaxInt32 {
+ buf.WriteString("inf")
+ } else {
+ fmt.Fprintf(buf, "%d", c.Codes[offset+2])
+ }
+
+ case Branchcount, Lazybranchcount:
+ buf.WriteString(", Limit = ")
+ if c.Codes[offset+2] == math.MaxInt32 {
+ buf.WriteString("inf")
+ } else {
+ fmt.Fprintf(buf, "%d", c.Codes[offset+2])
+ }
+
+ }
+
+ buf.WriteString(")")
+
+ return buf.String()
+}
+
+func (c *Code) Dump() string {
+ buf := &bytes.Buffer{}
+
+ if c.RightToLeft {
+ fmt.Fprintln(buf, "Direction: right-to-left")
+ } else {
+ fmt.Fprintln(buf, "Direction: left-to-right")
+ }
+ if c.FcPrefix == nil {
+ fmt.Fprintln(buf, "Firstchars: n/a")
+ } else {
+ fmt.Fprintf(buf, "Firstchars: %v\n", c.FcPrefix.PrefixSet.String())
+ }
+
+ if c.BmPrefix == nil {
+ fmt.Fprintln(buf, "Prefix: n/a")
+ } else {
+ fmt.Fprintf(buf, "Prefix: %v\n", Escape(c.BmPrefix.String()))
+ }
+
+ fmt.Fprintf(buf, "Anchors: %v\n", c.Anchors)
+ fmt.Fprintln(buf)
+
+ if c.BmPrefix != nil {
+ fmt.Fprintln(buf, "BoyerMoore:")
+ fmt.Fprintln(buf, c.BmPrefix.Dump(" "))
+ }
+ for i := 0; i < len(c.Codes); i += opcodeSize(InstOp(c.Codes[i])) {
+ fmt.Fprintln(buf, c.OpcodeDescription(i))
+ }
+
+ return buf.String()
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/escape.go b/vendor/github.com/dlclark/regexp2/syntax/escape.go
new file mode 100644
index 0000000..609df10
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/escape.go
@@ -0,0 +1,94 @@
+package syntax
+
+import (
+ "bytes"
+ "strconv"
+ "strings"
+ "unicode"
+)
+
+func Escape(input string) string {
+ b := &bytes.Buffer{}
+ for _, r := range input {
+ escape(b, r, false)
+ }
+ return b.String()
+}
+
+const meta = `\.+*?()|[]{}^$# `
+
+func escape(b *bytes.Buffer, r rune, force bool) {
+ if unicode.IsPrint(r) {
+ if strings.IndexRune(meta, r) >= 0 || force {
+ b.WriteRune('\\')
+ }
+ b.WriteRune(r)
+ return
+ }
+
+ switch r {
+ case '\a':
+ b.WriteString(`\a`)
+ case '\f':
+ b.WriteString(`\f`)
+ case '\n':
+ b.WriteString(`\n`)
+ case '\r':
+ b.WriteString(`\r`)
+ case '\t':
+ b.WriteString(`\t`)
+ case '\v':
+ b.WriteString(`\v`)
+ default:
+ if r < 0x100 {
+ b.WriteString(`\x`)
+ s := strconv.FormatInt(int64(r), 16)
+ if len(s) == 1 {
+ b.WriteRune('0')
+ }
+ b.WriteString(s)
+ break
+ }
+ b.WriteString(`\u`)
+ b.WriteString(strconv.FormatInt(int64(r), 16))
+ }
+}
+
+func Unescape(input string) (string, error) {
+ idx := strings.IndexRune(input, '\\')
+ // no slashes means no unescape needed
+ if idx == -1 {
+ return input, nil
+ }
+
+ buf := bytes.NewBufferString(input[:idx])
+ // get the runes for the rest of the string -- we're going full parser scan on this
+
+ p := parser{}
+ p.setPattern(input[idx+1:])
+ for {
+ if p.rightMost() {
+ return "", p.getErr(ErrIllegalEndEscape)
+ }
+ r, err := p.scanCharEscape()
+ if err != nil {
+ return "", err
+ }
+ buf.WriteRune(r)
+ // are we done?
+ if p.rightMost() {
+ return buf.String(), nil
+ }
+
+ r = p.moveRightGetChar()
+ for r != '\\' {
+ buf.WriteRune(r)
+ if p.rightMost() {
+ // we're done, no more slashes
+ return buf.String(), nil
+ }
+ // keep scanning until we get another slash
+ r = p.moveRightGetChar()
+ }
+ }
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/fuzz.go b/vendor/github.com/dlclark/regexp2/syntax/fuzz.go
new file mode 100644
index 0000000..ee86386
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/fuzz.go
@@ -0,0 +1,20 @@
+// +build gofuzz
+
+package syntax
+
+// Fuzz is the input point for go-fuzz
+func Fuzz(data []byte) int {
+ sdata := string(data)
+ tree, err := Parse(sdata, RegexOptions(0))
+ if err != nil {
+ return 0
+ }
+
+ // translate it to code
+ _, err = Write(tree)
+ if err != nil {
+ panic(err)
+ }
+
+ return 1
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/parser.go b/vendor/github.com/dlclark/regexp2/syntax/parser.go
new file mode 100644
index 0000000..4ff0aaa
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/parser.go
@@ -0,0 +1,2262 @@
+package syntax
+
+import (
+ "fmt"
+ "math"
+ "os"
+ "sort"
+ "strconv"
+ "unicode"
+)
+
+type RegexOptions int32
+
+const (
+ IgnoreCase RegexOptions = 0x0001 // "i"
+ Multiline = 0x0002 // "m"
+ ExplicitCapture = 0x0004 // "n"
+ Compiled = 0x0008 // "c"
+ Singleline = 0x0010 // "s"
+ IgnorePatternWhitespace = 0x0020 // "x"
+ RightToLeft = 0x0040 // "r"
+ Debug = 0x0080 // "d"
+ ECMAScript = 0x0100 // "e"
+ RE2 = 0x0200 // RE2 compat mode
+ Unicode = 0x0400 // "u"
+)
+
+func optionFromCode(ch rune) RegexOptions {
+ // case-insensitive
+ switch ch {
+ case 'i', 'I':
+ return IgnoreCase
+ case 'r', 'R':
+ return RightToLeft
+ case 'm', 'M':
+ return Multiline
+ case 'n', 'N':
+ return ExplicitCapture
+ case 's', 'S':
+ return Singleline
+ case 'x', 'X':
+ return IgnorePatternWhitespace
+ case 'd', 'D':
+ return Debug
+ case 'e', 'E':
+ return ECMAScript
+ case 'u', 'U':
+ return Unicode
+ default:
+ return 0
+ }
+}
+
+// An Error describes a failure to parse a regular expression
+// and gives the offending expression.
+type Error struct {
+ Code ErrorCode
+ Expr string
+ Args []interface{}
+}
+
+func (e *Error) Error() string {
+ if len(e.Args) == 0 {
+ return "error parsing regexp: " + e.Code.String() + " in `" + e.Expr + "`"
+ }
+ return "error parsing regexp: " + fmt.Sprintf(e.Code.String(), e.Args...) + " in `" + e.Expr + "`"
+}
+
+// An ErrorCode describes a failure to parse a regular expression.
+type ErrorCode string
+
+const (
+ // internal issue
+ ErrInternalError ErrorCode = "regexp/syntax: internal error"
+ // Parser errors
+ ErrUnterminatedComment = "unterminated comment"
+ ErrInvalidCharRange = "invalid character class range"
+ ErrInvalidRepeatSize = "invalid repeat count"
+ ErrInvalidUTF8 = "invalid UTF-8"
+ ErrCaptureGroupOutOfRange = "capture group number out of range"
+ ErrUnexpectedParen = "unexpected )"
+ ErrMissingParen = "missing closing )"
+ ErrMissingBrace = "missing closing }"
+ ErrInvalidRepeatOp = "invalid nested repetition operator"
+ ErrMissingRepeatArgument = "missing argument to repetition operator"
+ ErrConditionalExpression = "illegal conditional (?(...)) expression"
+ ErrTooManyAlternates = "too many | in (?()|)"
+ ErrUnrecognizedGrouping = "unrecognized grouping construct: (%v"
+ ErrInvalidGroupName = "invalid group name: group names must begin with a word character and have a matching terminator"
+ ErrCapNumNotZero = "capture number cannot be zero"
+ ErrUndefinedBackRef = "reference to undefined group number %v"
+ ErrUndefinedNameRef = "reference to undefined group name %v"
+ ErrAlternationCantCapture = "alternation conditions do not capture and cannot be named"
+ ErrAlternationCantHaveComment = "alternation conditions cannot be comments"
+ ErrMalformedReference = "(?(%v) ) malformed"
+ ErrUndefinedReference = "(?(%v) ) reference to undefined group"
+ ErrIllegalEndEscape = "illegal \\ at end of pattern"
+ ErrMalformedSlashP = "malformed \\p{X} character escape"
+ ErrIncompleteSlashP = "incomplete \\p{X} character escape"
+ ErrUnknownSlashP = "unknown unicode category, script, or property '%v'"
+ ErrUnrecognizedEscape = "unrecognized escape sequence \\%v"
+ ErrMissingControl = "missing control character"
+ ErrUnrecognizedControl = "unrecognized control character"
+ ErrTooFewHex = "insufficient hexadecimal digits"
+ ErrInvalidHex = "hex values may not be larger than 0x10FFFF"
+ ErrMalformedNameRef = "malformed \\k<...> named back reference"
+ ErrBadClassInCharRange = "cannot include class \\%v in character range"
+ ErrUnterminatedBracket = "unterminated [] set"
+ ErrSubtractionMustBeLast = "a subtraction must be the last element in a character class"
+ ErrReversedCharRange = "[%c-%c] range in reverse order"
+)
+
+func (e ErrorCode) String() string {
+ return string(e)
+}
+
+type parser struct {
+ stack *regexNode
+ group *regexNode
+ alternation *regexNode
+ concatenation *regexNode
+ unit *regexNode
+
+ patternRaw string
+ pattern []rune
+
+ currentPos int
+ specialCase *unicode.SpecialCase
+
+ autocap int
+ capcount int
+ captop int
+ capsize int
+
+ caps map[int]int
+ capnames map[string]int
+
+ capnumlist []int
+ capnamelist []string
+
+ options RegexOptions
+ optionsStack []RegexOptions
+ ignoreNextParen bool
+}
+
+const (
+ maxValueDiv10 int = math.MaxInt32 / 10
+ maxValueMod10 = math.MaxInt32 % 10
+)
+
+// Parse converts a regex string into a parse tree
+func Parse(re string, op RegexOptions) (*RegexTree, error) {
+ p := parser{
+ options: op,
+ caps: make(map[int]int),
+ }
+ p.setPattern(re)
+
+ if err := p.countCaptures(); err != nil {
+ return nil, err
+ }
+
+ p.reset(op)
+ root, err := p.scanRegex()
+
+ if err != nil {
+ return nil, err
+ }
+ tree := &RegexTree{
+ root: root,
+ caps: p.caps,
+ capnumlist: p.capnumlist,
+ captop: p.captop,
+ Capnames: p.capnames,
+ Caplist: p.capnamelist,
+ options: op,
+ }
+
+ if tree.options&Debug > 0 {
+ os.Stdout.WriteString(tree.Dump())
+ }
+
+ return tree, nil
+}
+
+func (p *parser) setPattern(pattern string) {
+ p.patternRaw = pattern
+ p.pattern = make([]rune, 0, len(pattern))
+
+ //populate our rune array to handle utf8 encoding
+ for _, r := range pattern {
+ p.pattern = append(p.pattern, r)
+ }
+}
+func (p *parser) getErr(code ErrorCode, args ...interface{}) error {
+ return &Error{Code: code, Expr: p.patternRaw, Args: args}
+}
+
+func (p *parser) noteCaptureSlot(i, pos int) {
+ if _, ok := p.caps[i]; !ok {
+ // the rhs of the hashtable isn't used in the parser
+ p.caps[i] = pos
+ p.capcount++
+
+ if p.captop <= i {
+ if i == math.MaxInt32 {
+ p.captop = i
+ } else {
+ p.captop = i + 1
+ }
+ }
+ }
+}
+
+func (p *parser) noteCaptureName(name string, pos int) {
+ if p.capnames == nil {
+ p.capnames = make(map[string]int)
+ }
+
+ if _, ok := p.capnames[name]; !ok {
+ p.capnames[name] = pos
+ p.capnamelist = append(p.capnamelist, name)
+ }
+}
+
+func (p *parser) assignNameSlots() {
+ if p.capnames != nil {
+ for _, name := range p.capnamelist {
+ for p.isCaptureSlot(p.autocap) {
+ p.autocap++
+ }
+ pos := p.capnames[name]
+ p.capnames[name] = p.autocap
+ p.noteCaptureSlot(p.autocap, pos)
+
+ p.autocap++
+ }
+ }
+
+ // if the caps array has at least one gap, construct the list of used slots
+ if p.capcount < p.captop {
+ p.capnumlist = make([]int, p.capcount)
+ i := 0
+
+ for k := range p.caps {
+ p.capnumlist[i] = k
+ i++
+ }
+
+ sort.Ints(p.capnumlist)
+ }
+
+ // merge capsnumlist into capnamelist
+ if p.capnames != nil || p.capnumlist != nil {
+ var oldcapnamelist []string
+ var next int
+ var k int
+
+ if p.capnames == nil {
+ oldcapnamelist = nil
+ p.capnames = make(map[string]int)
+ p.capnamelist = []string{}
+ next = -1
+ } else {
+ oldcapnamelist = p.capnamelist
+ p.capnamelist = []string{}
+ next = p.capnames[oldcapnamelist[0]]
+ }
+
+ for i := 0; i < p.capcount; i++ {
+ j := i
+ if p.capnumlist != nil {
+ j = p.capnumlist[i]
+ }
+
+ if next == j {
+ p.capnamelist = append(p.capnamelist, oldcapnamelist[k])
+ k++
+
+ if k == len(oldcapnamelist) {
+ next = -1
+ } else {
+ next = p.capnames[oldcapnamelist[k]]
+ }
+
+ } else {
+ //feature: culture?
+ str := strconv.Itoa(j)
+ p.capnamelist = append(p.capnamelist, str)
+ p.capnames[str] = j
+ }
+ }
+ }
+}
+
+func (p *parser) consumeAutocap() int {
+ r := p.autocap
+ p.autocap++
+ return r
+}
+
+// CountCaptures is a prescanner for deducing the slots used for
+// captures by doing a partial tokenization of the pattern.
+func (p *parser) countCaptures() error {
+ var ch rune
+
+ p.noteCaptureSlot(0, 0)
+
+ p.autocap = 1
+
+ for p.charsRight() > 0 {
+ pos := p.textpos()
+ ch = p.moveRightGetChar()
+ switch ch {
+ case '\\':
+ if p.charsRight() > 0 {
+ p.scanBackslash(true)
+ }
+
+ case '#':
+ if p.useOptionX() {
+ p.moveLeft()
+ p.scanBlank()
+ }
+
+ case '[':
+ p.scanCharSet(false, true)
+
+ case ')':
+ if !p.emptyOptionsStack() {
+ p.popOptions()
+ }
+
+ case '(':
+ if p.charsRight() >= 2 && p.rightChar(1) == '#' && p.rightChar(0) == '?' {
+ p.moveLeft()
+ p.scanBlank()
+ } else {
+ p.pushOptions()
+ if p.charsRight() > 0 && p.rightChar(0) == '?' {
+ // we have (?...
+ p.moveRight(1)
+
+ if p.charsRight() > 1 && (p.rightChar(0) == '<' || p.rightChar(0) == '\'') {
+ // named group: (?<... or (?'...
+
+ p.moveRight(1)
+ ch = p.rightChar(0)
+
+ if ch != '0' && IsWordChar(ch) {
+ if ch >= '1' && ch <= '9' {
+ dec, err := p.scanDecimal()
+ if err != nil {
+ return err
+ }
+ p.noteCaptureSlot(dec, pos)
+ } else {
+ p.noteCaptureName(p.scanCapname(), pos)
+ }
+ }
+ } else if p.useRE2() && p.charsRight() > 2 && (p.rightChar(0) == 'P' && p.rightChar(1) == '<') {
+ // RE2-compat (?P<)
+ p.moveRight(2)
+ ch = p.rightChar(0)
+ if IsWordChar(ch) {
+ p.noteCaptureName(p.scanCapname(), pos)
+ }
+
+ } else {
+ // (?...
+
+ // get the options if it's an option construct (?cimsx-cimsx...)
+ p.scanOptions()
+
+ if p.charsRight() > 0 {
+ if p.rightChar(0) == ')' {
+ // (?cimsx-cimsx)
+ p.moveRight(1)
+ p.popKeepOptions()
+ } else if p.rightChar(0) == '(' {
+ // alternation construct: (?(foo)yes|no)
+ // ignore the next paren so we don't capture the condition
+ p.ignoreNextParen = true
+
+ // break from here so we don't reset ignoreNextParen
+ continue
+ }
+ }
+ }
+ } else {
+ if !p.useOptionN() && !p.ignoreNextParen {
+ p.noteCaptureSlot(p.consumeAutocap(), pos)
+ }
+ }
+ }
+
+ p.ignoreNextParen = false
+
+ }
+ }
+
+ p.assignNameSlots()
+ return nil
+}
+
+func (p *parser) reset(topopts RegexOptions) {
+ p.currentPos = 0
+ p.autocap = 1
+ p.ignoreNextParen = false
+
+ if len(p.optionsStack) > 0 {
+ p.optionsStack = p.optionsStack[:0]
+ }
+
+ p.options = topopts
+ p.stack = nil
+}
+
+func (p *parser) scanRegex() (*regexNode, error) {
+ ch := '@' // nonspecial ch, means at beginning
+ isQuant := false
+
+ p.startGroup(newRegexNodeMN(ntCapture, p.options, 0, -1))
+
+ for p.charsRight() > 0 {
+ wasPrevQuantifier := isQuant
+ isQuant = false
+
+ if err := p.scanBlank(); err != nil {
+ return nil, err
+ }
+
+ startpos := p.textpos()
+
+ // move past all of the normal characters. We'll stop when we hit some kind of control character,
+ // or if IgnorePatternWhiteSpace is on, we'll stop when we see some whitespace.
+ if p.useOptionX() {
+ for p.charsRight() > 0 {
+ ch = p.rightChar(0)
+ //UGLY: clean up, this is ugly
+ if !(!isStopperX(ch) || (ch == '{' && !p.isTrueQuantifier())) {
+ break
+ }
+ p.moveRight(1)
+ }
+ } else {
+ for p.charsRight() > 0 {
+ ch = p.rightChar(0)
+ if !(!isSpecial(ch) || ch == '{' && !p.isTrueQuantifier()) {
+ break
+ }
+ p.moveRight(1)
+ }
+ }
+
+ endpos := p.textpos()
+
+ p.scanBlank()
+
+ if p.charsRight() == 0 {
+ ch = '!' // nonspecial, means at end
+ } else if ch = p.rightChar(0); isSpecial(ch) {
+ isQuant = isQuantifier(ch)
+ p.moveRight(1)
+ } else {
+ ch = ' ' // nonspecial, means at ordinary char
+ }
+
+ if startpos < endpos {
+ cchUnquantified := endpos - startpos
+ if isQuant {
+ cchUnquantified--
+ }
+ wasPrevQuantifier = false
+
+ if cchUnquantified > 0 {
+ p.addToConcatenate(startpos, cchUnquantified, false)
+ }
+
+ if isQuant {
+ p.addUnitOne(p.charAt(endpos - 1))
+ }
+ }
+
+ switch ch {
+ case '!':
+ goto BreakOuterScan
+
+ case ' ':
+ goto ContinueOuterScan
+
+ case '[':
+ cc, err := p.scanCharSet(p.useOptionI(), false)
+ if err != nil {
+ return nil, err
+ }
+ p.addUnitSet(cc)
+
+ case '(':
+ p.pushOptions()
+
+ if grouper, err := p.scanGroupOpen(); err != nil {
+ return nil, err
+ } else if grouper == nil {
+ p.popKeepOptions()
+ } else {
+ p.pushGroup()
+ p.startGroup(grouper)
+ }
+
+ continue
+
+ case '|':
+ p.addAlternate()
+ goto ContinueOuterScan
+
+ case ')':
+ if p.emptyStack() {
+ return nil, p.getErr(ErrUnexpectedParen)
+ }
+
+ if err := p.addGroup(); err != nil {
+ return nil, err
+ }
+ if err := p.popGroup(); err != nil {
+ return nil, err
+ }
+ p.popOptions()
+
+ if p.unit == nil {
+ goto ContinueOuterScan
+ }
+
+ case '\\':
+ n, err := p.scanBackslash(false)
+ if err != nil {
+ return nil, err
+ }
+ p.addUnitNode(n)
+
+ case '^':
+ if p.useOptionM() {
+ p.addUnitType(ntBol)
+ } else {
+ p.addUnitType(ntBeginning)
+ }
+
+ case '$':
+ if p.useOptionM() {
+ p.addUnitType(ntEol)
+ } else {
+ p.addUnitType(ntEndZ)
+ }
+
+ case '.':
+ if p.useOptionS() {
+ p.addUnitSet(AnyClass())
+ } else if p.useOptionE() {
+ p.addUnitSet(ECMAAnyClass())
+ } else {
+ p.addUnitNotone('\n')
+ }
+
+ case '{', '*', '+', '?':
+ if p.unit == nil {
+ if wasPrevQuantifier {
+ return nil, p.getErr(ErrInvalidRepeatOp)
+ } else {
+ return nil, p.getErr(ErrMissingRepeatArgument)
+ }
+ }
+ p.moveLeft()
+
+ default:
+ return nil, p.getErr(ErrInternalError)
+ }
+
+ if err := p.scanBlank(); err != nil {
+ return nil, err
+ }
+
+ if p.charsRight() > 0 {
+ isQuant = p.isTrueQuantifier()
+ }
+ if p.charsRight() == 0 || !isQuant {
+ //maintain odd C# assignment order -- not sure if required, could clean up?
+ p.addConcatenate()
+ goto ContinueOuterScan
+ }
+
+ ch = p.moveRightGetChar()
+
+ // Handle quantifiers
+ for p.unit != nil {
+ var min, max int
+ var lazy bool
+
+ switch ch {
+ case '*':
+ min = 0
+ max = math.MaxInt32
+
+ case '?':
+ min = 0
+ max = 1
+
+ case '+':
+ min = 1
+ max = math.MaxInt32
+
+ case '{':
+ {
+ var err error
+ startpos = p.textpos()
+ if min, err = p.scanDecimal(); err != nil {
+ return nil, err
+ }
+ max = min
+ if startpos < p.textpos() {
+ if p.charsRight() > 0 && p.rightChar(0) == ',' {
+ p.moveRight(1)
+ if p.charsRight() == 0 || p.rightChar(0) == '}' {
+ max = math.MaxInt32
+ } else {
+ if max, err = p.scanDecimal(); err != nil {
+ return nil, err
+ }
+ }
+ }
+ }
+
+ if startpos == p.textpos() || p.charsRight() == 0 || p.moveRightGetChar() != '}' {
+ p.addConcatenate()
+ p.textto(startpos - 1)
+ goto ContinueOuterScan
+ }
+ }
+
+ default:
+ return nil, p.getErr(ErrInternalError)
+ }
+
+ if err := p.scanBlank(); err != nil {
+ return nil, err
+ }
+
+ if p.charsRight() == 0 || p.rightChar(0) != '?' {
+ lazy = false
+ } else {
+ p.moveRight(1)
+ lazy = true
+ }
+
+ if min > max {
+ return nil, p.getErr(ErrInvalidRepeatSize)
+ }
+
+ p.addConcatenate3(lazy, min, max)
+ }
+
+ ContinueOuterScan:
+ }
+
+BreakOuterScan:
+ ;
+
+ if !p.emptyStack() {
+ return nil, p.getErr(ErrMissingParen)
+ }
+
+ if err := p.addGroup(); err != nil {
+ return nil, err
+ }
+
+ return p.unit, nil
+
+}
+
+/*
+ * Simple parsing for replacement patterns
+ */
+func (p *parser) scanReplacement() (*regexNode, error) {
+ var c, startpos int
+
+ p.concatenation = newRegexNode(ntConcatenate, p.options)
+
+ for {
+ c = p.charsRight()
+ if c == 0 {
+ break
+ }
+
+ startpos = p.textpos()
+
+ for c > 0 && p.rightChar(0) != '$' {
+ p.moveRight(1)
+ c--
+ }
+
+ p.addToConcatenate(startpos, p.textpos()-startpos, true)
+
+ if c > 0 {
+ if p.moveRightGetChar() == '$' {
+ n, err := p.scanDollar()
+ if err != nil {
+ return nil, err
+ }
+ p.addUnitNode(n)
+ }
+ p.addConcatenate()
+ }
+ }
+
+ return p.concatenation, nil
+}
+
+/*
+ * Scans $ patterns recognized within replacement patterns
+ */
+func (p *parser) scanDollar() (*regexNode, error) {
+ if p.charsRight() == 0 {
+ return newRegexNodeCh(ntOne, p.options, '$'), nil
+ }
+
+ ch := p.rightChar(0)
+ angled := false
+ backpos := p.textpos()
+ lastEndPos := backpos
+
+ // Note angle
+
+ if ch == '{' && p.charsRight() > 1 {
+ angled = true
+ p.moveRight(1)
+ ch = p.rightChar(0)
+ }
+
+ // Try to parse backreference: \1 or \{1} or \{cap}
+
+ if ch >= '0' && ch <= '9' {
+ if !angled && p.useOptionE() {
+ capnum := -1
+ newcapnum := int(ch - '0')
+ p.moveRight(1)
+ if p.isCaptureSlot(newcapnum) {
+ capnum = newcapnum
+ lastEndPos = p.textpos()
+ }
+
+ for p.charsRight() > 0 {
+ ch = p.rightChar(0)
+ if ch < '0' || ch > '9' {
+ break
+ }
+ digit := int(ch - '0')
+ if newcapnum > maxValueDiv10 || (newcapnum == maxValueDiv10 && digit > maxValueMod10) {
+ return nil, p.getErr(ErrCaptureGroupOutOfRange)
+ }
+
+ newcapnum = newcapnum*10 + digit
+
+ p.moveRight(1)
+ if p.isCaptureSlot(newcapnum) {
+ capnum = newcapnum
+ lastEndPos = p.textpos()
+ }
+ }
+ p.textto(lastEndPos)
+ if capnum >= 0 {
+ return newRegexNodeM(ntRef, p.options, capnum), nil
+ }
+ } else {
+ capnum, err := p.scanDecimal()
+ if err != nil {
+ return nil, err
+ }
+ if !angled || p.charsRight() > 0 && p.moveRightGetChar() == '}' {
+ if p.isCaptureSlot(capnum) {
+ return newRegexNodeM(ntRef, p.options, capnum), nil
+ }
+ }
+ }
+ } else if angled && IsWordChar(ch) {
+ capname := p.scanCapname()
+
+ if p.charsRight() > 0 && p.moveRightGetChar() == '}' {
+ if p.isCaptureName(capname) {
+ return newRegexNodeM(ntRef, p.options, p.captureSlotFromName(capname)), nil
+ }
+ }
+ } else if !angled {
+ capnum := 1
+
+ switch ch {
+ case '$':
+ p.moveRight(1)
+ return newRegexNodeCh(ntOne, p.options, '$'), nil
+ case '&':
+ capnum = 0
+ case '`':
+ capnum = replaceLeftPortion
+ case '\'':
+ capnum = replaceRightPortion
+ case '+':
+ capnum = replaceLastGroup
+ case '_':
+ capnum = replaceWholeString
+ }
+
+ if capnum != 1 {
+ p.moveRight(1)
+ return newRegexNodeM(ntRef, p.options, capnum), nil
+ }
+ }
+
+ // unrecognized $: literalize
+
+ p.textto(backpos)
+ return newRegexNodeCh(ntOne, p.options, '$'), nil
+}
+
+// scanGroupOpen scans chars following a '(' (not counting the '('), and returns
+// a RegexNode for the type of group scanned, or nil if the group
+// simply changed options (?cimsx-cimsx) or was a comment (#...).
+func (p *parser) scanGroupOpen() (*regexNode, error) {
+ var ch rune
+ var nt nodeType
+ var err error
+ close := '>'
+ start := p.textpos()
+
+ // just return a RegexNode if we have:
+ // 1. "(" followed by nothing
+ // 2. "(x" where x != ?
+ // 3. "(?)"
+ if p.charsRight() == 0 || p.rightChar(0) != '?' || (p.rightChar(0) == '?' && (p.charsRight() > 1 && p.rightChar(1) == ')')) {
+ if p.useOptionN() || p.ignoreNextParen {
+ p.ignoreNextParen = false
+ return newRegexNode(ntGroup, p.options), nil
+ }
+ return newRegexNodeMN(ntCapture, p.options, p.consumeAutocap(), -1), nil
+ }
+
+ p.moveRight(1)
+
+ for {
+ if p.charsRight() == 0 {
+ break
+ }
+
+ switch ch = p.moveRightGetChar(); ch {
+ case ':':
+ nt = ntGroup
+
+ case '=':
+ p.options &= ^RightToLeft
+ nt = ntRequire
+
+ case '!':
+ p.options &= ^RightToLeft
+ nt = ntPrevent
+
+ case '>':
+ nt = ntGreedy
+
+ case '\'':
+ close = '\''
+ fallthrough
+
+ case '<':
+ if p.charsRight() == 0 {
+ goto BreakRecognize
+ }
+
+ switch ch = p.moveRightGetChar(); ch {
+ case '=':
+ if close == '\'' {
+ goto BreakRecognize
+ }
+
+ p.options |= RightToLeft
+ nt = ntRequire
+
+ case '!':
+ if close == '\'' {
+ goto BreakRecognize
+ }
+
+ p.options |= RightToLeft
+ nt = ntPrevent
+
+ default:
+ p.moveLeft()
+ capnum := -1
+ uncapnum := -1
+ proceed := false
+
+ // grab part before -
+
+ if ch >= '0' && ch <= '9' {
+ if capnum, err = p.scanDecimal(); err != nil {
+ return nil, err
+ }
+
+ if !p.isCaptureSlot(capnum) {
+ capnum = -1
+ }
+
+ // check if we have bogus characters after the number
+ if p.charsRight() > 0 && !(p.rightChar(0) == close || p.rightChar(0) == '-') {
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+ if capnum == 0 {
+ return nil, p.getErr(ErrCapNumNotZero)
+ }
+ } else if IsWordChar(ch) {
+ capname := p.scanCapname()
+
+ if p.isCaptureName(capname) {
+ capnum = p.captureSlotFromName(capname)
+ }
+
+ // check if we have bogus character after the name
+ if p.charsRight() > 0 && !(p.rightChar(0) == close || p.rightChar(0) == '-') {
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+ } else if ch == '-' {
+ proceed = true
+ } else {
+ // bad group name - starts with something other than a word character and isn't a number
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+
+ // grab part after - if any
+
+ if (capnum != -1 || proceed == true) && p.charsRight() > 0 && p.rightChar(0) == '-' {
+ p.moveRight(1)
+
+ //no more chars left, no closing char, etc
+ if p.charsRight() == 0 {
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+
+ ch = p.rightChar(0)
+ if ch >= '0' && ch <= '9' {
+ if uncapnum, err = p.scanDecimal(); err != nil {
+ return nil, err
+ }
+
+ if !p.isCaptureSlot(uncapnum) {
+ return nil, p.getErr(ErrUndefinedBackRef, uncapnum)
+ }
+
+ // check if we have bogus characters after the number
+ if p.charsRight() > 0 && p.rightChar(0) != close {
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+ } else if IsWordChar(ch) {
+ uncapname := p.scanCapname()
+
+ if !p.isCaptureName(uncapname) {
+ return nil, p.getErr(ErrUndefinedNameRef, uncapname)
+ }
+ uncapnum = p.captureSlotFromName(uncapname)
+
+ // check if we have bogus character after the name
+ if p.charsRight() > 0 && p.rightChar(0) != close {
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+ } else {
+ // bad group name - starts with something other than a word character and isn't a number
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+ }
+
+ // actually make the node
+
+ if (capnum != -1 || uncapnum != -1) && p.charsRight() > 0 && p.moveRightGetChar() == close {
+ return newRegexNodeMN(ntCapture, p.options, capnum, uncapnum), nil
+ }
+ goto BreakRecognize
+ }
+
+ case '(':
+ // alternation construct (?(...) | )
+
+ parenPos := p.textpos()
+ if p.charsRight() > 0 {
+ ch = p.rightChar(0)
+
+ // check if the alternation condition is a backref
+ if ch >= '0' && ch <= '9' {
+ var capnum int
+ if capnum, err = p.scanDecimal(); err != nil {
+ return nil, err
+ }
+ if p.charsRight() > 0 && p.moveRightGetChar() == ')' {
+ if p.isCaptureSlot(capnum) {
+ return newRegexNodeM(ntTestref, p.options, capnum), nil
+ }
+ return nil, p.getErr(ErrUndefinedReference, capnum)
+ }
+
+ return nil, p.getErr(ErrMalformedReference, capnum)
+
+ } else if IsWordChar(ch) {
+ capname := p.scanCapname()
+
+ if p.isCaptureName(capname) && p.charsRight() > 0 && p.moveRightGetChar() == ')' {
+ return newRegexNodeM(ntTestref, p.options, p.captureSlotFromName(capname)), nil
+ }
+ }
+ }
+ // not a backref
+ nt = ntTestgroup
+ p.textto(parenPos - 1) // jump to the start of the parentheses
+ p.ignoreNextParen = true // but make sure we don't try to capture the insides
+
+ charsRight := p.charsRight()
+ if charsRight >= 3 && p.rightChar(1) == '?' {
+ rightchar2 := p.rightChar(2)
+ // disallow comments in the condition
+ if rightchar2 == '#' {
+ return nil, p.getErr(ErrAlternationCantHaveComment)
+ }
+
+ // disallow named capture group (?<..>..) in the condition
+ if rightchar2 == '\'' {
+ return nil, p.getErr(ErrAlternationCantCapture)
+ }
+
+ if charsRight >= 4 && (rightchar2 == '<' && p.rightChar(3) != '!' && p.rightChar(3) != '=') {
+ return nil, p.getErr(ErrAlternationCantCapture)
+ }
+ }
+
+ case 'P':
+ if p.useRE2() {
+ // support for P syntax
+ if p.charsRight() < 3 {
+ goto BreakRecognize
+ }
+
+ ch = p.moveRightGetChar()
+ if ch != '<' {
+ goto BreakRecognize
+ }
+
+ ch = p.moveRightGetChar()
+ p.moveLeft()
+
+ if IsWordChar(ch) {
+ capnum := -1
+ capname := p.scanCapname()
+
+ if p.isCaptureName(capname) {
+ capnum = p.captureSlotFromName(capname)
+ }
+
+ // check if we have bogus character after the name
+ if p.charsRight() > 0 && p.rightChar(0) != '>' {
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+
+ // actually make the node
+
+ if capnum != -1 && p.charsRight() > 0 && p.moveRightGetChar() == '>' {
+ return newRegexNodeMN(ntCapture, p.options, capnum, -1), nil
+ }
+ goto BreakRecognize
+
+ } else {
+ // bad group name - starts with something other than a word character and isn't a number
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+ }
+ // if we're not using RE2 compat mode then
+ // we just behave like normal
+ fallthrough
+
+ default:
+ p.moveLeft()
+
+ nt = ntGroup
+ // disallow options in the children of a testgroup node
+ if p.group.t != ntTestgroup {
+ p.scanOptions()
+ }
+ if p.charsRight() == 0 {
+ goto BreakRecognize
+ }
+
+ if ch = p.moveRightGetChar(); ch == ')' {
+ return nil, nil
+ }
+
+ if ch != ':' {
+ goto BreakRecognize
+ }
+
+ }
+
+ return newRegexNode(nt, p.options), nil
+ }
+
+BreakRecognize:
+
+ // break Recognize comes here
+
+ return nil, p.getErr(ErrUnrecognizedGrouping, string(p.pattern[start:p.textpos()]))
+}
+
+// scans backslash specials and basics
+func (p *parser) scanBackslash(scanOnly bool) (*regexNode, error) {
+
+ if p.charsRight() == 0 {
+ return nil, p.getErr(ErrIllegalEndEscape)
+ }
+
+ switch ch := p.rightChar(0); ch {
+ case 'b', 'B', 'A', 'G', 'Z', 'z':
+ p.moveRight(1)
+ return newRegexNode(p.typeFromCode(ch), p.options), nil
+
+ case 'w':
+ p.moveRight(1)
+ if p.useOptionE() || p.useRE2() {
+ return newRegexNodeSet(ntSet, p.options, ECMAWordClass()), nil
+ }
+ return newRegexNodeSet(ntSet, p.options, WordClass()), nil
+
+ case 'W':
+ p.moveRight(1)
+ if p.useOptionE() || p.useRE2() {
+ return newRegexNodeSet(ntSet, p.options, NotECMAWordClass()), nil
+ }
+ return newRegexNodeSet(ntSet, p.options, NotWordClass()), nil
+
+ case 's':
+ p.moveRight(1)
+ if p.useOptionE() {
+ return newRegexNodeSet(ntSet, p.options, ECMASpaceClass()), nil
+ } else if p.useRE2() {
+ return newRegexNodeSet(ntSet, p.options, RE2SpaceClass()), nil
+ }
+ return newRegexNodeSet(ntSet, p.options, SpaceClass()), nil
+
+ case 'S':
+ p.moveRight(1)
+ if p.useOptionE() {
+ return newRegexNodeSet(ntSet, p.options, NotECMASpaceClass()), nil
+ } else if p.useRE2() {
+ return newRegexNodeSet(ntSet, p.options, NotRE2SpaceClass()), nil
+ }
+ return newRegexNodeSet(ntSet, p.options, NotSpaceClass()), nil
+
+ case 'd':
+ p.moveRight(1)
+ if p.useOptionE() || p.useRE2() {
+ return newRegexNodeSet(ntSet, p.options, ECMADigitClass()), nil
+ }
+ return newRegexNodeSet(ntSet, p.options, DigitClass()), nil
+
+ case 'D':
+ p.moveRight(1)
+ if p.useOptionE() || p.useRE2() {
+ return newRegexNodeSet(ntSet, p.options, NotECMADigitClass()), nil
+ }
+ return newRegexNodeSet(ntSet, p.options, NotDigitClass()), nil
+
+ case 'p', 'P':
+ p.moveRight(1)
+ prop, err := p.parseProperty()
+ if err != nil {
+ return nil, err
+ }
+ cc := &CharSet{}
+ cc.addCategory(prop, (ch != 'p'), p.useOptionI(), p.patternRaw)
+ if p.useOptionI() {
+ cc.addLowercase()
+ }
+
+ return newRegexNodeSet(ntSet, p.options, cc), nil
+
+ default:
+ return p.scanBasicBackslash(scanOnly)
+ }
+}
+
+// Scans \-style backreferences and character escapes
+func (p *parser) scanBasicBackslash(scanOnly bool) (*regexNode, error) {
+ if p.charsRight() == 0 {
+ return nil, p.getErr(ErrIllegalEndEscape)
+ }
+ angled := false
+ k := false
+ close := '\x00'
+
+ backpos := p.textpos()
+ ch := p.rightChar(0)
+
+ // Allow \k instead of \, which is now deprecated.
+
+ // According to ECMAScript specification, \k is only parsed as a named group reference if
+ // there is at least one group name in the regexp.
+ // See https://www.ecma-international.org/ecma-262/#sec-isvalidregularexpressionliteral, step 7.
+ // Note, during the first (scanOnly) run we may not have all group names scanned, but that's ok.
+ if ch == 'k' && (!p.useOptionE() || len(p.capnames) > 0) {
+ if p.charsRight() >= 2 {
+ p.moveRight(1)
+ ch = p.moveRightGetChar()
+
+ if ch == '<' || (!p.useOptionE() && ch == '\'') { // No support for \k'name' in ECMAScript
+ angled = true
+ if ch == '\'' {
+ close = '\''
+ } else {
+ close = '>'
+ }
+ }
+ }
+
+ if !angled || p.charsRight() <= 0 {
+ return nil, p.getErr(ErrMalformedNameRef)
+ }
+
+ ch = p.rightChar(0)
+ k = true
+
+ } else if !p.useOptionE() && (ch == '<' || ch == '\'') && p.charsRight() > 1 { // Note angle without \g
+ angled = true
+ if ch == '\'' {
+ close = '\''
+ } else {
+ close = '>'
+ }
+
+ p.moveRight(1)
+ ch = p.rightChar(0)
+ }
+
+ // Try to parse backreference: \<1> or \
+
+ if angled && ch >= '0' && ch <= '9' {
+ capnum, err := p.scanDecimal()
+ if err != nil {
+ return nil, err
+ }
+
+ if p.charsRight() > 0 && p.moveRightGetChar() == close {
+ if p.isCaptureSlot(capnum) {
+ return newRegexNodeM(ntRef, p.options, capnum), nil
+ }
+ return nil, p.getErr(ErrUndefinedBackRef, capnum)
+ }
+ } else if !angled && ch >= '1' && ch <= '9' { // Try to parse backreference or octal: \1
+ capnum, err := p.scanDecimal()
+ if err != nil {
+ return nil, err
+ }
+
+ if scanOnly {
+ return nil, nil
+ }
+
+ if p.isCaptureSlot(capnum) {
+ return newRegexNodeM(ntRef, p.options, capnum), nil
+ }
+ if capnum <= 9 && !p.useOptionE() {
+ return nil, p.getErr(ErrUndefinedBackRef, capnum)
+ }
+
+ } else if angled {
+ capname := p.scanCapname()
+
+ if capname != "" && p.charsRight() > 0 && p.moveRightGetChar() == close {
+
+ if scanOnly {
+ return nil, nil
+ }
+
+ if p.isCaptureName(capname) {
+ return newRegexNodeM(ntRef, p.options, p.captureSlotFromName(capname)), nil
+ }
+ return nil, p.getErr(ErrUndefinedNameRef, capname)
+ } else {
+ if k {
+ return nil, p.getErr(ErrMalformedNameRef)
+ }
+ }
+ }
+
+ // Not backreference: must be char code
+
+ p.textto(backpos)
+ ch, err := p.scanCharEscape()
+ if err != nil {
+ return nil, err
+ }
+
+ if scanOnly {
+ return nil, nil
+ }
+
+ if p.useOptionI() {
+ ch = unicode.ToLower(ch)
+ }
+
+ return newRegexNodeCh(ntOne, p.options, ch), nil
+}
+
+// Scans X for \p{X} or \P{X}
+func (p *parser) parseProperty() (string, error) {
+ // RE2 and PCRE supports \pX syntax (no {} and only 1 letter unicode cats supported)
+ // since this is purely additive syntax it's not behind a flag
+ if p.charsRight() >= 1 && p.rightChar(0) != '{' {
+ ch := string(p.moveRightGetChar())
+ // check if it's a valid cat
+ if !isValidUnicodeCat(ch) {
+ return "", p.getErr(ErrUnknownSlashP, ch)
+ }
+ return ch, nil
+ }
+
+ if p.charsRight() < 3 {
+ return "", p.getErr(ErrIncompleteSlashP)
+ }
+ ch := p.moveRightGetChar()
+ if ch != '{' {
+ return "", p.getErr(ErrMalformedSlashP)
+ }
+
+ startpos := p.textpos()
+ for p.charsRight() > 0 {
+ ch = p.moveRightGetChar()
+ if !(IsWordChar(ch) || ch == '-') {
+ p.moveLeft()
+ break
+ }
+ }
+ capname := string(p.pattern[startpos:p.textpos()])
+
+ if p.charsRight() == 0 || p.moveRightGetChar() != '}' {
+ return "", p.getErr(ErrIncompleteSlashP)
+ }
+
+ if !isValidUnicodeCat(capname) {
+ return "", p.getErr(ErrUnknownSlashP, capname)
+ }
+
+ return capname, nil
+}
+
+// Returns ReNode type for zero-length assertions with a \ code.
+func (p *parser) typeFromCode(ch rune) nodeType {
+ switch ch {
+ case 'b':
+ if p.useOptionE() {
+ return ntECMABoundary
+ }
+ return ntBoundary
+ case 'B':
+ if p.useOptionE() {
+ return ntNonECMABoundary
+ }
+ return ntNonboundary
+ case 'A':
+ return ntBeginning
+ case 'G':
+ return ntStart
+ case 'Z':
+ return ntEndZ
+ case 'z':
+ return ntEnd
+ default:
+ return ntNothing
+ }
+}
+
+// Scans whitespace or x-mode comments.
+func (p *parser) scanBlank() error {
+ if p.useOptionX() {
+ for {
+ for p.charsRight() > 0 && isSpace(p.rightChar(0)) {
+ p.moveRight(1)
+ }
+
+ if p.charsRight() == 0 {
+ break
+ }
+
+ if p.rightChar(0) == '#' {
+ for p.charsRight() > 0 && p.rightChar(0) != '\n' {
+ p.moveRight(1)
+ }
+ } else if p.charsRight() >= 3 && p.rightChar(2) == '#' &&
+ p.rightChar(1) == '?' && p.rightChar(0) == '(' {
+ for p.charsRight() > 0 && p.rightChar(0) != ')' {
+ p.moveRight(1)
+ }
+ if p.charsRight() == 0 {
+ return p.getErr(ErrUnterminatedComment)
+ }
+ p.moveRight(1)
+ } else {
+ break
+ }
+ }
+ } else {
+ for {
+ if p.charsRight() < 3 || p.rightChar(2) != '#' ||
+ p.rightChar(1) != '?' || p.rightChar(0) != '(' {
+ return nil
+ }
+
+ for p.charsRight() > 0 && p.rightChar(0) != ')' {
+ p.moveRight(1)
+ }
+ if p.charsRight() == 0 {
+ return p.getErr(ErrUnterminatedComment)
+ }
+ p.moveRight(1)
+ }
+ }
+ return nil
+}
+
+func (p *parser) scanCapname() string {
+ startpos := p.textpos()
+
+ for p.charsRight() > 0 {
+ if !IsWordChar(p.moveRightGetChar()) {
+ p.moveLeft()
+ break
+ }
+ }
+
+ return string(p.pattern[startpos:p.textpos()])
+}
+
+// Scans contents of [] (not including []'s), and converts to a set.
+func (p *parser) scanCharSet(caseInsensitive, scanOnly bool) (*CharSet, error) {
+ ch := '\x00'
+ chPrev := '\x00'
+ inRange := false
+ firstChar := true
+ closed := false
+
+ var cc *CharSet
+ if !scanOnly {
+ cc = &CharSet{}
+ }
+
+ if p.charsRight() > 0 && p.rightChar(0) == '^' {
+ p.moveRight(1)
+ if !scanOnly {
+ cc.negate = true
+ }
+ }
+
+ for ; p.charsRight() > 0; firstChar = false {
+ fTranslatedChar := false
+ ch = p.moveRightGetChar()
+ if ch == ']' {
+ if !firstChar {
+ closed = true
+ break
+ } else if p.useOptionE() {
+ if !scanOnly {
+ cc.addRanges(NoneClass().ranges)
+ }
+ closed = true
+ break
+ }
+
+ } else if ch == '\\' && p.charsRight() > 0 {
+ switch ch = p.moveRightGetChar(); ch {
+ case 'D', 'd':
+ if !scanOnly {
+ if inRange {
+ return nil, p.getErr(ErrBadClassInCharRange, ch)
+ }
+ cc.addDigit(p.useOptionE() || p.useRE2(), ch == 'D', p.patternRaw)
+ }
+ continue
+
+ case 'S', 's':
+ if !scanOnly {
+ if inRange {
+ return nil, p.getErr(ErrBadClassInCharRange, ch)
+ }
+ cc.addSpace(p.useOptionE(), p.useRE2(), ch == 'S')
+ }
+ continue
+
+ case 'W', 'w':
+ if !scanOnly {
+ if inRange {
+ return nil, p.getErr(ErrBadClassInCharRange, ch)
+ }
+
+ cc.addWord(p.useOptionE() || p.useRE2(), ch == 'W')
+ }
+ continue
+
+ case 'p', 'P':
+ if !scanOnly {
+ if inRange {
+ return nil, p.getErr(ErrBadClassInCharRange, ch)
+ }
+ prop, err := p.parseProperty()
+ if err != nil {
+ return nil, err
+ }
+ cc.addCategory(prop, (ch != 'p'), caseInsensitive, p.patternRaw)
+ } else {
+ p.parseProperty()
+ }
+
+ continue
+
+ case '-':
+ if !scanOnly {
+ cc.addRange(ch, ch)
+ }
+ continue
+
+ default:
+ p.moveLeft()
+ var err error
+ ch, err = p.scanCharEscape() // non-literal character
+ if err != nil {
+ return nil, err
+ }
+ fTranslatedChar = true
+ break // this break will only break out of the switch
+ }
+ } else if ch == '[' {
+ // This is code for Posix style properties - [:Ll:] or [:IsTibetan:].
+ // It currently doesn't do anything other than skip the whole thing!
+ if p.charsRight() > 0 && p.rightChar(0) == ':' && !inRange {
+ savePos := p.textpos()
+
+ p.moveRight(1)
+ negate := false
+ if p.charsRight() > 1 && p.rightChar(0) == '^' {
+ negate = true
+ p.moveRight(1)
+ }
+
+ nm := p.scanCapname() // snag the name
+ if !scanOnly && p.useRE2() {
+ // look up the name since these are valid for RE2
+ // add the group based on the name
+ if ok := cc.addNamedASCII(nm, negate); !ok {
+ return nil, p.getErr(ErrInvalidCharRange)
+ }
+ }
+ if p.charsRight() < 2 || p.moveRightGetChar() != ':' || p.moveRightGetChar() != ']' {
+ p.textto(savePos)
+ } else if p.useRE2() {
+ // move on
+ continue
+ }
+ }
+ }
+
+ if inRange {
+ inRange = false
+ if !scanOnly {
+ if ch == '[' && !fTranslatedChar && !firstChar {
+ // We thought we were in a range, but we're actually starting a subtraction.
+ // In that case, we'll add chPrev to our char class, skip the opening [, and
+ // scan the new character class recursively.
+ cc.addChar(chPrev)
+ sub, err := p.scanCharSet(caseInsensitive, false)
+ if err != nil {
+ return nil, err
+ }
+ cc.addSubtraction(sub)
+
+ if p.charsRight() > 0 && p.rightChar(0) != ']' {
+ return nil, p.getErr(ErrSubtractionMustBeLast)
+ }
+ } else {
+ // a regular range, like a-z
+ if chPrev > ch {
+ return nil, p.getErr(ErrReversedCharRange, chPrev, ch)
+ }
+ cc.addRange(chPrev, ch)
+ }
+ }
+ } else if p.charsRight() >= 2 && p.rightChar(0) == '-' && p.rightChar(1) != ']' {
+ // this could be the start of a range
+ chPrev = ch
+ inRange = true
+ p.moveRight(1)
+ } else if p.charsRight() >= 1 && ch == '-' && !fTranslatedChar && p.rightChar(0) == '[' && !firstChar {
+ // we aren't in a range, and now there is a subtraction. Usually this happens
+ // only when a subtraction follows a range, like [a-z-[b]]
+ if !scanOnly {
+ p.moveRight(1)
+ sub, err := p.scanCharSet(caseInsensitive, false)
+ if err != nil {
+ return nil, err
+ }
+ cc.addSubtraction(sub)
+
+ if p.charsRight() > 0 && p.rightChar(0) != ']' {
+ return nil, p.getErr(ErrSubtractionMustBeLast)
+ }
+ } else {
+ p.moveRight(1)
+ p.scanCharSet(caseInsensitive, true)
+ }
+ } else {
+ if !scanOnly {
+ cc.addRange(ch, ch)
+ }
+ }
+ }
+
+ if !closed {
+ return nil, p.getErr(ErrUnterminatedBracket)
+ }
+
+ if !scanOnly && caseInsensitive {
+ cc.addLowercase()
+ }
+
+ return cc, nil
+}
+
+// Scans any number of decimal digits (pegs value at 2^31-1 if too large)
+func (p *parser) scanDecimal() (int, error) {
+ i := 0
+ var d int
+
+ for p.charsRight() > 0 {
+ d = int(p.rightChar(0) - '0')
+ if d < 0 || d > 9 {
+ break
+ }
+ p.moveRight(1)
+
+ if i > maxValueDiv10 || (i == maxValueDiv10 && d > maxValueMod10) {
+ return 0, p.getErr(ErrCaptureGroupOutOfRange)
+ }
+
+ i *= 10
+ i += d
+ }
+
+ return int(i), nil
+}
+
+// Returns true for options allowed only at the top level
+func isOnlyTopOption(option RegexOptions) bool {
+ return option == RightToLeft || option == ECMAScript || option == RE2
+}
+
+// Scans cimsx-cimsx option string, stops at the first unrecognized char.
+func (p *parser) scanOptions() {
+
+ for off := false; p.charsRight() > 0; p.moveRight(1) {
+ ch := p.rightChar(0)
+
+ if ch == '-' {
+ off = true
+ } else if ch == '+' {
+ off = false
+ } else {
+ option := optionFromCode(ch)
+ if option == 0 || isOnlyTopOption(option) {
+ return
+ }
+
+ if off {
+ p.options &= ^option
+ } else {
+ p.options |= option
+ }
+ }
+ }
+}
+
+// Scans \ code for escape codes that map to single unicode chars.
+func (p *parser) scanCharEscape() (r rune, err error) {
+
+ ch := p.moveRightGetChar()
+
+ if ch >= '0' && ch <= '7' {
+ p.moveLeft()
+ return p.scanOctal(), nil
+ }
+
+ pos := p.textpos()
+
+ switch ch {
+ case 'x':
+ // support for \x{HEX} syntax from Perl and PCRE
+ if p.charsRight() > 0 && p.rightChar(0) == '{' {
+ if p.useOptionE() {
+ return ch, nil
+ }
+ p.moveRight(1)
+ return p.scanHexUntilBrace()
+ } else {
+ r, err = p.scanHex(2)
+ }
+ case 'u':
+ // ECMAscript suppot \u{HEX} only if `u` is also set
+ if p.useOptionE() && p.useOptionU() && p.charsRight() > 0 && p.rightChar(0) == '{' {
+ p.moveRight(1)
+ return p.scanHexUntilBrace()
+ } else {
+ r, err = p.scanHex(4)
+ }
+ case 'a':
+ return '\u0007', nil
+ case 'b':
+ return '\b', nil
+ case 'e':
+ return '\u001B', nil
+ case 'f':
+ return '\f', nil
+ case 'n':
+ return '\n', nil
+ case 'r':
+ return '\r', nil
+ case 't':
+ return '\t', nil
+ case 'v':
+ return '\u000B', nil
+ case 'c':
+ r, err = p.scanControl()
+ default:
+ if !p.useOptionE() && !p.useRE2() && IsWordChar(ch) {
+ return 0, p.getErr(ErrUnrecognizedEscape, string(ch))
+ }
+ return ch, nil
+ }
+ if err != nil && p.useOptionE() {
+ p.textto(pos)
+ return ch, nil
+ }
+ return
+}
+
+// Grabs and converts an ascii control character
+func (p *parser) scanControl() (rune, error) {
+ if p.charsRight() <= 0 {
+ return 0, p.getErr(ErrMissingControl)
+ }
+
+ ch := p.moveRightGetChar()
+
+ // \ca interpreted as \cA
+
+ if ch >= 'a' && ch <= 'z' {
+ ch = (ch - ('a' - 'A'))
+ }
+ ch = (ch - '@')
+ if ch >= 0 && ch < ' ' {
+ return ch, nil
+ }
+
+ return 0, p.getErr(ErrUnrecognizedControl)
+
+}
+
+// Scan hex digits until we hit a closing brace.
+// Non-hex digits, hex value too large for UTF-8, or running out of chars are errors
+func (p *parser) scanHexUntilBrace() (rune, error) {
+ // PCRE spec reads like unlimited hex digits are allowed, but unicode has a limit
+ // so we can enforce that
+ i := 0
+ hasContent := false
+
+ for p.charsRight() > 0 {
+ ch := p.moveRightGetChar()
+ if ch == '}' {
+ // hit our close brace, we're done here
+ // prevent \x{}
+ if !hasContent {
+ return 0, p.getErr(ErrTooFewHex)
+ }
+ return rune(i), nil
+ }
+ hasContent = true
+ // no brace needs to be hex digit
+ d := hexDigit(ch)
+ if d < 0 {
+ return 0, p.getErr(ErrMissingBrace)
+ }
+
+ i *= 0x10
+ i += d
+
+ if i > unicode.MaxRune {
+ return 0, p.getErr(ErrInvalidHex)
+ }
+ }
+
+ // we only make it here if we run out of digits without finding the brace
+ return 0, p.getErr(ErrMissingBrace)
+}
+
+// Scans exactly c hex digits (c=2 for \xFF, c=4 for \uFFFF)
+func (p *parser) scanHex(c int) (rune, error) {
+
+ i := 0
+
+ if p.charsRight() >= c {
+ for c > 0 {
+ d := hexDigit(p.moveRightGetChar())
+ if d < 0 {
+ break
+ }
+ i *= 0x10
+ i += d
+ c--
+ }
+ }
+
+ if c > 0 {
+ return 0, p.getErr(ErrTooFewHex)
+ }
+
+ return rune(i), nil
+}
+
+// Returns n <= 0xF for a hex digit.
+func hexDigit(ch rune) int {
+
+ if d := uint(ch - '0'); d <= 9 {
+ return int(d)
+ }
+
+ if d := uint(ch - 'a'); d <= 5 {
+ return int(d + 0xa)
+ }
+
+ if d := uint(ch - 'A'); d <= 5 {
+ return int(d + 0xa)
+ }
+
+ return -1
+}
+
+// Scans up to three octal digits (stops before exceeding 0377).
+func (p *parser) scanOctal() rune {
+ // Consume octal chars only up to 3 digits and value 0377
+
+ c := 3
+
+ if c > p.charsRight() {
+ c = p.charsRight()
+ }
+
+ //we know the first char is good because the caller had to check
+ i := 0
+ d := int(p.rightChar(0) - '0')
+ for c > 0 && d <= 7 && d >= 0 {
+ if i >= 0x20 && p.useOptionE() {
+ break
+ }
+ i *= 8
+ i += d
+ c--
+
+ p.moveRight(1)
+ if !p.rightMost() {
+ d = int(p.rightChar(0) - '0')
+ }
+ }
+
+ // Octal codes only go up to 255. Any larger and the behavior that Perl follows
+ // is simply to truncate the high bits.
+ i &= 0xFF
+
+ return rune(i)
+}
+
+// Returns the current parsing position.
+func (p *parser) textpos() int {
+ return p.currentPos
+}
+
+// Zaps to a specific parsing position.
+func (p *parser) textto(pos int) {
+ p.currentPos = pos
+}
+
+// Returns the char at the right of the current parsing position and advances to the right.
+func (p *parser) moveRightGetChar() rune {
+ ch := p.pattern[p.currentPos]
+ p.currentPos++
+ return ch
+}
+
+// Moves the current position to the right.
+func (p *parser) moveRight(i int) {
+ // default would be 1
+ p.currentPos += i
+}
+
+// Moves the current parsing position one to the left.
+func (p *parser) moveLeft() {
+ p.currentPos--
+}
+
+// Returns the char left of the current parsing position.
+func (p *parser) charAt(i int) rune {
+ return p.pattern[i]
+}
+
+// Returns the char i chars right of the current parsing position.
+func (p *parser) rightChar(i int) rune {
+ // default would be 0
+ return p.pattern[p.currentPos+i]
+}
+
+// Number of characters to the right of the current parsing position.
+func (p *parser) charsRight() int {
+ return len(p.pattern) - p.currentPos
+}
+
+func (p *parser) rightMost() bool {
+ return p.currentPos == len(p.pattern)
+}
+
+// Looks up the slot number for a given name
+func (p *parser) captureSlotFromName(capname string) int {
+ return p.capnames[capname]
+}
+
+// True if the capture slot was noted
+func (p *parser) isCaptureSlot(i int) bool {
+ if p.caps != nil {
+ _, ok := p.caps[i]
+ return ok
+ }
+
+ return (i >= 0 && i < p.capsize)
+}
+
+// Looks up the slot number for a given name
+func (p *parser) isCaptureName(capname string) bool {
+ if p.capnames == nil {
+ return false
+ }
+
+ _, ok := p.capnames[capname]
+ return ok
+}
+
+// option shortcuts
+
+// True if N option disabling '(' autocapture is on.
+func (p *parser) useOptionN() bool {
+ return (p.options & ExplicitCapture) != 0
+}
+
+// True if I option enabling case-insensitivity is on.
+func (p *parser) useOptionI() bool {
+ return (p.options & IgnoreCase) != 0
+}
+
+// True if M option altering meaning of $ and ^ is on.
+func (p *parser) useOptionM() bool {
+ return (p.options & Multiline) != 0
+}
+
+// True if S option altering meaning of . is on.
+func (p *parser) useOptionS() bool {
+ return (p.options & Singleline) != 0
+}
+
+// True if X option enabling whitespace/comment mode is on.
+func (p *parser) useOptionX() bool {
+ return (p.options & IgnorePatternWhitespace) != 0
+}
+
+// True if E option enabling ECMAScript behavior on.
+func (p *parser) useOptionE() bool {
+ return (p.options & ECMAScript) != 0
+}
+
+// true to use RE2 compatibility parsing behavior.
+func (p *parser) useRE2() bool {
+ return (p.options & RE2) != 0
+}
+
+// True if U option enabling ECMAScript's Unicode behavior on.
+func (p *parser) useOptionU() bool {
+ return (p.options & Unicode) != 0
+}
+
+// True if options stack is empty.
+func (p *parser) emptyOptionsStack() bool {
+ return len(p.optionsStack) == 0
+}
+
+// Finish the current quantifiable (when a quantifier is not found or is not possible)
+func (p *parser) addConcatenate() {
+ // The first (| inside a Testgroup group goes directly to the group
+ p.concatenation.addChild(p.unit)
+ p.unit = nil
+}
+
+// Finish the current quantifiable (when a quantifier is found)
+func (p *parser) addConcatenate3(lazy bool, min, max int) {
+ p.concatenation.addChild(p.unit.makeQuantifier(lazy, min, max))
+ p.unit = nil
+}
+
+// Sets the current unit to a single char node
+func (p *parser) addUnitOne(ch rune) {
+ if p.useOptionI() {
+ ch = unicode.ToLower(ch)
+ }
+
+ p.unit = newRegexNodeCh(ntOne, p.options, ch)
+}
+
+// Sets the current unit to a single inverse-char node
+func (p *parser) addUnitNotone(ch rune) {
+ if p.useOptionI() {
+ ch = unicode.ToLower(ch)
+ }
+
+ p.unit = newRegexNodeCh(ntNotone, p.options, ch)
+}
+
+// Sets the current unit to a single set node
+func (p *parser) addUnitSet(set *CharSet) {
+ p.unit = newRegexNodeSet(ntSet, p.options, set)
+}
+
+// Sets the current unit to a subtree
+func (p *parser) addUnitNode(node *regexNode) {
+ p.unit = node
+}
+
+// Sets the current unit to an assertion of the specified type
+func (p *parser) addUnitType(t nodeType) {
+ p.unit = newRegexNode(t, p.options)
+}
+
+// Finish the current group (in response to a ')' or end)
+func (p *parser) addGroup() error {
+ if p.group.t == ntTestgroup || p.group.t == ntTestref {
+ p.group.addChild(p.concatenation.reverseLeft())
+ if (p.group.t == ntTestref && len(p.group.children) > 2) || len(p.group.children) > 3 {
+ return p.getErr(ErrTooManyAlternates)
+ }
+ } else {
+ p.alternation.addChild(p.concatenation.reverseLeft())
+ p.group.addChild(p.alternation)
+ }
+
+ p.unit = p.group
+ return nil
+}
+
+// Pops the option stack, but keeps the current options unchanged.
+func (p *parser) popKeepOptions() {
+ lastIdx := len(p.optionsStack) - 1
+ p.optionsStack = p.optionsStack[:lastIdx]
+}
+
+// Recalls options from the stack.
+func (p *parser) popOptions() {
+ lastIdx := len(p.optionsStack) - 1
+ // get the last item on the stack and then remove it by reslicing
+ p.options = p.optionsStack[lastIdx]
+ p.optionsStack = p.optionsStack[:lastIdx]
+}
+
+// Saves options on a stack.
+func (p *parser) pushOptions() {
+ p.optionsStack = append(p.optionsStack, p.options)
+}
+
+// Add a string to the last concatenate.
+func (p *parser) addToConcatenate(pos, cch int, isReplacement bool) {
+ var node *regexNode
+
+ if cch == 0 {
+ return
+ }
+
+ if cch > 1 {
+ str := make([]rune, cch)
+ copy(str, p.pattern[pos:pos+cch])
+
+ if p.useOptionI() && !isReplacement {
+ // We do the ToLower character by character for consistency. With surrogate chars, doing
+ // a ToLower on the entire string could actually change the surrogate pair. This is more correct
+ // linguistically, but since Regex doesn't support surrogates, it's more important to be
+ // consistent.
+ for i := 0; i < len(str); i++ {
+ str[i] = unicode.ToLower(str[i])
+ }
+ }
+
+ node = newRegexNodeStr(ntMulti, p.options, str)
+ } else {
+ ch := p.charAt(pos)
+
+ if p.useOptionI() && !isReplacement {
+ ch = unicode.ToLower(ch)
+ }
+
+ node = newRegexNodeCh(ntOne, p.options, ch)
+ }
+
+ p.concatenation.addChild(node)
+}
+
+// Push the parser state (in response to an open paren)
+func (p *parser) pushGroup() {
+ p.group.next = p.stack
+ p.alternation.next = p.group
+ p.concatenation.next = p.alternation
+ p.stack = p.concatenation
+}
+
+// Remember the pushed state (in response to a ')')
+func (p *parser) popGroup() error {
+ p.concatenation = p.stack
+ p.alternation = p.concatenation.next
+ p.group = p.alternation.next
+ p.stack = p.group.next
+
+ // The first () inside a Testgroup group goes directly to the group
+ if p.group.t == ntTestgroup && len(p.group.children) == 0 {
+ if p.unit == nil {
+ return p.getErr(ErrConditionalExpression)
+ }
+
+ p.group.addChild(p.unit)
+ p.unit = nil
+ }
+ return nil
+}
+
+// True if the group stack is empty.
+func (p *parser) emptyStack() bool {
+ return p.stack == nil
+}
+
+// Start a new round for the parser state (in response to an open paren or string start)
+func (p *parser) startGroup(openGroup *regexNode) {
+ p.group = openGroup
+ p.alternation = newRegexNode(ntAlternate, p.options)
+ p.concatenation = newRegexNode(ntConcatenate, p.options)
+}
+
+// Finish the current concatenation (in response to a |)
+func (p *parser) addAlternate() {
+ // The | parts inside a Testgroup group go directly to the group
+
+ if p.group.t == ntTestgroup || p.group.t == ntTestref {
+ p.group.addChild(p.concatenation.reverseLeft())
+ } else {
+ p.alternation.addChild(p.concatenation.reverseLeft())
+ }
+
+ p.concatenation = newRegexNode(ntConcatenate, p.options)
+}
+
+// For categorizing ascii characters.
+
+const (
+ Q byte = 5 // quantifier
+ S = 4 // ordinary stopper
+ Z = 3 // ScanBlank stopper
+ X = 2 // whitespace
+ E = 1 // should be escaped
+)
+
+var _category = []byte{
+ //01 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, X, X, X, X, X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
+ X, 0, 0, Z, S, 0, 0, 0, S, S, Q, Q, 0, 0, S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Q,
+ //@A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, S, S, 0, S, 0,
+ //'a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Q, S, 0, 0, 0,
+}
+
+func isSpace(ch rune) bool {
+ return (ch <= ' ' && _category[ch] == X)
+}
+
+// Returns true for those characters that terminate a string of ordinary chars.
+func isSpecial(ch rune) bool {
+ return (ch <= '|' && _category[ch] >= S)
+}
+
+// Returns true for those characters that terminate a string of ordinary chars.
+func isStopperX(ch rune) bool {
+ return (ch <= '|' && _category[ch] >= X)
+}
+
+// Returns true for those characters that begin a quantifier.
+func isQuantifier(ch rune) bool {
+ return (ch <= '{' && _category[ch] >= Q)
+}
+
+func (p *parser) isTrueQuantifier() bool {
+ nChars := p.charsRight()
+ if nChars == 0 {
+ return false
+ }
+
+ startpos := p.textpos()
+ ch := p.charAt(startpos)
+ if ch != '{' {
+ return ch <= '{' && _category[ch] >= Q
+ }
+
+ //UGLY: this is ugly -- the original code was ugly too
+ pos := startpos
+ for {
+ nChars--
+ if nChars <= 0 {
+ break
+ }
+ pos++
+ ch = p.charAt(pos)
+ if ch < '0' || ch > '9' {
+ break
+ }
+ }
+
+ if nChars == 0 || pos-startpos == 1 {
+ return false
+ }
+ if ch == '}' {
+ return true
+ }
+ if ch != ',' {
+ return false
+ }
+ for {
+ nChars--
+ if nChars <= 0 {
+ break
+ }
+ pos++
+ ch = p.charAt(pos)
+ if ch < '0' || ch > '9' {
+ break
+ }
+ }
+
+ return nChars > 0 && ch == '}'
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/prefix.go b/vendor/github.com/dlclark/regexp2/syntax/prefix.go
new file mode 100644
index 0000000..f671688
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/prefix.go
@@ -0,0 +1,896 @@
+package syntax
+
+import (
+ "bytes"
+ "fmt"
+ "strconv"
+ "unicode"
+ "unicode/utf8"
+)
+
+type Prefix struct {
+ PrefixStr []rune
+ PrefixSet CharSet
+ CaseInsensitive bool
+}
+
+// It takes a RegexTree and computes the set of chars that can start it.
+func getFirstCharsPrefix(tree *RegexTree) *Prefix {
+ s := regexFcd{
+ fcStack: make([]regexFc, 32),
+ intStack: make([]int, 32),
+ }
+ fc := s.regexFCFromRegexTree(tree)
+
+ if fc == nil || fc.nullable || fc.cc.IsEmpty() {
+ return nil
+ }
+ fcSet := fc.getFirstChars()
+ return &Prefix{PrefixSet: fcSet, CaseInsensitive: fc.caseInsensitive}
+}
+
+type regexFcd struct {
+ intStack []int
+ intDepth int
+ fcStack []regexFc
+ fcDepth int
+ skipAllChildren bool // don't process any more children at the current level
+ skipchild bool // don't process the current child.
+ failed bool
+}
+
+/*
+ * The main FC computation. It does a shortcutted depth-first walk
+ * through the tree and calls CalculateFC to emits code before
+ * and after each child of an interior node, and at each leaf.
+ */
+func (s *regexFcd) regexFCFromRegexTree(tree *RegexTree) *regexFc {
+ curNode := tree.root
+ curChild := 0
+
+ for {
+ if len(curNode.children) == 0 {
+ // This is a leaf node
+ s.calculateFC(curNode.t, curNode, 0)
+ } else if curChild < len(curNode.children) && !s.skipAllChildren {
+ // This is an interior node, and we have more children to analyze
+ s.calculateFC(curNode.t|beforeChild, curNode, curChild)
+
+ if !s.skipchild {
+ curNode = curNode.children[curChild]
+ // this stack is how we get a depth first walk of the tree.
+ s.pushInt(curChild)
+ curChild = 0
+ } else {
+ curChild++
+ s.skipchild = false
+ }
+ continue
+ }
+
+ // This is an interior node where we've finished analyzing all the children, or
+ // the end of a leaf node.
+ s.skipAllChildren = false
+
+ if s.intIsEmpty() {
+ break
+ }
+
+ curChild = s.popInt()
+ curNode = curNode.next
+
+ s.calculateFC(curNode.t|afterChild, curNode, curChild)
+ if s.failed {
+ return nil
+ }
+
+ curChild++
+ }
+
+ if s.fcIsEmpty() {
+ return nil
+ }
+
+ return s.popFC()
+}
+
+// To avoid recursion, we use a simple integer stack.
+// This is the push.
+func (s *regexFcd) pushInt(I int) {
+ if s.intDepth >= len(s.intStack) {
+ expanded := make([]int, s.intDepth*2)
+ copy(expanded, s.intStack)
+ s.intStack = expanded
+ }
+
+ s.intStack[s.intDepth] = I
+ s.intDepth++
+}
+
+// True if the stack is empty.
+func (s *regexFcd) intIsEmpty() bool {
+ return s.intDepth == 0
+}
+
+// This is the pop.
+func (s *regexFcd) popInt() int {
+ s.intDepth--
+ return s.intStack[s.intDepth]
+}
+
+// We also use a stack of RegexFC objects.
+// This is the push.
+func (s *regexFcd) pushFC(fc regexFc) {
+ if s.fcDepth >= len(s.fcStack) {
+ expanded := make([]regexFc, s.fcDepth*2)
+ copy(expanded, s.fcStack)
+ s.fcStack = expanded
+ }
+
+ s.fcStack[s.fcDepth] = fc
+ s.fcDepth++
+}
+
+// True if the stack is empty.
+func (s *regexFcd) fcIsEmpty() bool {
+ return s.fcDepth == 0
+}
+
+// This is the pop.
+func (s *regexFcd) popFC() *regexFc {
+ s.fcDepth--
+ return &s.fcStack[s.fcDepth]
+}
+
+// This is the top.
+func (s *regexFcd) topFC() *regexFc {
+ return &s.fcStack[s.fcDepth-1]
+}
+
+// Called in Beforechild to prevent further processing of the current child
+func (s *regexFcd) skipChild() {
+ s.skipchild = true
+}
+
+// FC computation and shortcut cases for each node type
+func (s *regexFcd) calculateFC(nt nodeType, node *regexNode, CurIndex int) {
+ //fmt.Printf("NodeType: %v, CurIndex: %v, Desc: %v\n", nt, CurIndex, node.description())
+ ci := false
+ rtl := false
+
+ if nt <= ntRef {
+ if (node.options & IgnoreCase) != 0 {
+ ci = true
+ }
+ if (node.options & RightToLeft) != 0 {
+ rtl = true
+ }
+ }
+
+ switch nt {
+ case ntConcatenate | beforeChild, ntAlternate | beforeChild, ntTestref | beforeChild, ntLoop | beforeChild, ntLazyloop | beforeChild:
+ break
+
+ case ntTestgroup | beforeChild:
+ if CurIndex == 0 {
+ s.skipChild()
+ }
+ break
+
+ case ntEmpty:
+ s.pushFC(regexFc{nullable: true})
+ break
+
+ case ntConcatenate | afterChild:
+ if CurIndex != 0 {
+ child := s.popFC()
+ cumul := s.topFC()
+
+ s.failed = !cumul.addFC(*child, true)
+ }
+
+ fc := s.topFC()
+ if !fc.nullable {
+ s.skipAllChildren = true
+ }
+ break
+
+ case ntTestgroup | afterChild:
+ if CurIndex > 1 {
+ child := s.popFC()
+ cumul := s.topFC()
+
+ s.failed = !cumul.addFC(*child, false)
+ }
+ break
+
+ case ntAlternate | afterChild, ntTestref | afterChild:
+ if CurIndex != 0 {
+ child := s.popFC()
+ cumul := s.topFC()
+
+ s.failed = !cumul.addFC(*child, false)
+ }
+ break
+
+ case ntLoop | afterChild, ntLazyloop | afterChild:
+ if node.m == 0 {
+ fc := s.topFC()
+ fc.nullable = true
+ }
+ break
+
+ case ntGroup | beforeChild, ntGroup | afterChild, ntCapture | beforeChild, ntCapture | afterChild, ntGreedy | beforeChild, ntGreedy | afterChild:
+ break
+
+ case ntRequire | beforeChild, ntPrevent | beforeChild:
+ s.skipChild()
+ s.pushFC(regexFc{nullable: true})
+ break
+
+ case ntRequire | afterChild, ntPrevent | afterChild:
+ break
+
+ case ntOne, ntNotone:
+ s.pushFC(newRegexFc(node.ch, nt == ntNotone, false, ci))
+ break
+
+ case ntOneloop, ntOnelazy:
+ s.pushFC(newRegexFc(node.ch, false, node.m == 0, ci))
+ break
+
+ case ntNotoneloop, ntNotonelazy:
+ s.pushFC(newRegexFc(node.ch, true, node.m == 0, ci))
+ break
+
+ case ntMulti:
+ if len(node.str) == 0 {
+ s.pushFC(regexFc{nullable: true})
+ } else if !rtl {
+ s.pushFC(newRegexFc(node.str[0], false, false, ci))
+ } else {
+ s.pushFC(newRegexFc(node.str[len(node.str)-1], false, false, ci))
+ }
+ break
+
+ case ntSet:
+ s.pushFC(regexFc{cc: node.set.Copy(), nullable: false, caseInsensitive: ci})
+ break
+
+ case ntSetloop, ntSetlazy:
+ s.pushFC(regexFc{cc: node.set.Copy(), nullable: node.m == 0, caseInsensitive: ci})
+ break
+
+ case ntRef:
+ s.pushFC(regexFc{cc: *AnyClass(), nullable: true, caseInsensitive: false})
+ break
+
+ case ntNothing, ntBol, ntEol, ntBoundary, ntNonboundary, ntECMABoundary, ntNonECMABoundary, ntBeginning, ntStart, ntEndZ, ntEnd:
+ s.pushFC(regexFc{nullable: true})
+ break
+
+ default:
+ panic(fmt.Sprintf("unexpected op code: %v", nt))
+ }
+}
+
+type regexFc struct {
+ cc CharSet
+ nullable bool
+ caseInsensitive bool
+}
+
+func newRegexFc(ch rune, not, nullable, caseInsensitive bool) regexFc {
+ r := regexFc{
+ caseInsensitive: caseInsensitive,
+ nullable: nullable,
+ }
+ if not {
+ if ch > 0 {
+ r.cc.addRange('\x00', ch-1)
+ }
+ if ch < 0xFFFF {
+ r.cc.addRange(ch+1, utf8.MaxRune)
+ }
+ } else {
+ r.cc.addRange(ch, ch)
+ }
+ return r
+}
+
+func (r *regexFc) getFirstChars() CharSet {
+ if r.caseInsensitive {
+ r.cc.addLowercase()
+ }
+
+ return r.cc
+}
+
+func (r *regexFc) addFC(fc regexFc, concatenate bool) bool {
+ if !r.cc.IsMergeable() || !fc.cc.IsMergeable() {
+ return false
+ }
+
+ if concatenate {
+ if !r.nullable {
+ return true
+ }
+
+ if !fc.nullable {
+ r.nullable = false
+ }
+ } else {
+ if fc.nullable {
+ r.nullable = true
+ }
+ }
+
+ r.caseInsensitive = r.caseInsensitive || fc.caseInsensitive
+ r.cc.addSet(fc.cc)
+
+ return true
+}
+
+// This is a related computation: it takes a RegexTree and computes the
+// leading substring if it sees one. It's quite trivial and gives up easily.
+func getPrefix(tree *RegexTree) *Prefix {
+ var concatNode *regexNode
+ nextChild := 0
+
+ curNode := tree.root
+
+ for {
+ switch curNode.t {
+ case ntConcatenate:
+ if len(curNode.children) > 0 {
+ concatNode = curNode
+ nextChild = 0
+ }
+
+ case ntGreedy, ntCapture:
+ curNode = curNode.children[0]
+ concatNode = nil
+ continue
+
+ case ntOneloop, ntOnelazy:
+ if curNode.m > 0 {
+ return &Prefix{
+ PrefixStr: repeat(curNode.ch, curNode.m),
+ CaseInsensitive: (curNode.options & IgnoreCase) != 0,
+ }
+ }
+ return nil
+
+ case ntOne:
+ return &Prefix{
+ PrefixStr: []rune{curNode.ch},
+ CaseInsensitive: (curNode.options & IgnoreCase) != 0,
+ }
+
+ case ntMulti:
+ return &Prefix{
+ PrefixStr: curNode.str,
+ CaseInsensitive: (curNode.options & IgnoreCase) != 0,
+ }
+
+ case ntBol, ntEol, ntBoundary, ntECMABoundary, ntBeginning, ntStart,
+ ntEndZ, ntEnd, ntEmpty, ntRequire, ntPrevent:
+
+ default:
+ return nil
+ }
+
+ if concatNode == nil || nextChild >= len(concatNode.children) {
+ return nil
+ }
+
+ curNode = concatNode.children[nextChild]
+ nextChild++
+ }
+}
+
+// repeat the rune r, c times... up to the max of MaxPrefixSize
+func repeat(r rune, c int) []rune {
+ if c > MaxPrefixSize {
+ c = MaxPrefixSize
+ }
+
+ ret := make([]rune, c)
+
+ // binary growth using copy for speed
+ ret[0] = r
+ bp := 1
+ for bp < len(ret) {
+ copy(ret[bp:], ret[:bp])
+ bp *= 2
+ }
+
+ return ret
+}
+
+// BmPrefix precomputes the Boyer-Moore
+// tables for fast string scanning. These tables allow
+// you to scan for the first occurrence of a string within
+// a large body of text without examining every character.
+// The performance of the heuristic depends on the actual
+// string and the text being searched, but usually, the longer
+// the string that is being searched for, the fewer characters
+// need to be examined.
+type BmPrefix struct {
+ positive []int
+ negativeASCII []int
+ negativeUnicode [][]int
+ pattern []rune
+ lowASCII rune
+ highASCII rune
+ rightToLeft bool
+ caseInsensitive bool
+}
+
+func newBmPrefix(pattern []rune, caseInsensitive, rightToLeft bool) *BmPrefix {
+
+ b := &BmPrefix{
+ rightToLeft: rightToLeft,
+ caseInsensitive: caseInsensitive,
+ pattern: pattern,
+ }
+
+ if caseInsensitive {
+ for i := 0; i < len(b.pattern); i++ {
+ // We do the ToLower character by character for consistency. With surrogate chars, doing
+ // a ToLower on the entire string could actually change the surrogate pair. This is more correct
+ // linguistically, but since Regex doesn't support surrogates, it's more important to be
+ // consistent.
+
+ b.pattern[i] = unicode.ToLower(b.pattern[i])
+ }
+ }
+
+ var beforefirst, last, bump int
+ var scan, match int
+
+ if !rightToLeft {
+ beforefirst = -1
+ last = len(b.pattern) - 1
+ bump = 1
+ } else {
+ beforefirst = len(b.pattern)
+ last = 0
+ bump = -1
+ }
+
+ // PART I - the good-suffix shift table
+ //
+ // compute the positive requirement:
+ // if char "i" is the first one from the right that doesn't match,
+ // then we know the matcher can advance by _positive[i].
+ //
+ // This algorithm is a simplified variant of the standard
+ // Boyer-Moore good suffix calculation.
+
+ b.positive = make([]int, len(b.pattern))
+
+ examine := last
+ ch := b.pattern[examine]
+ b.positive[examine] = bump
+ examine -= bump
+
+Outerloop:
+ for {
+ // find an internal char (examine) that matches the tail
+
+ for {
+ if examine == beforefirst {
+ break Outerloop
+ }
+ if b.pattern[examine] == ch {
+ break
+ }
+ examine -= bump
+ }
+
+ match = last
+ scan = examine
+
+ // find the length of the match
+ for {
+ if scan == beforefirst || b.pattern[match] != b.pattern[scan] {
+ // at the end of the match, note the difference in _positive
+ // this is not the length of the match, but the distance from the internal match
+ // to the tail suffix.
+ if b.positive[match] == 0 {
+ b.positive[match] = match - scan
+ }
+
+ // System.Diagnostics.Debug.WriteLine("Set positive[" + match + "] to " + (match - scan));
+
+ break
+ }
+
+ scan -= bump
+ match -= bump
+ }
+
+ examine -= bump
+ }
+
+ match = last - bump
+
+ // scan for the chars for which there are no shifts that yield a different candidate
+
+ // The inside of the if statement used to say
+ // "_positive[match] = last - beforefirst;"
+ // This is slightly less aggressive in how much we skip, but at worst it
+ // should mean a little more work rather than skipping a potential match.
+ for match != beforefirst {
+ if b.positive[match] == 0 {
+ b.positive[match] = bump
+ }
+
+ match -= bump
+ }
+
+ // PART II - the bad-character shift table
+ //
+ // compute the negative requirement:
+ // if char "ch" is the reject character when testing position "i",
+ // we can slide up by _negative[ch];
+ // (_negative[ch] = str.Length - 1 - str.LastIndexOf(ch))
+ //
+ // the lookup table is divided into ASCII and Unicode portions;
+ // only those parts of the Unicode 16-bit code set that actually
+ // appear in the string are in the table. (Maximum size with
+ // Unicode is 65K; ASCII only case is 512 bytes.)
+
+ b.negativeASCII = make([]int, 128)
+
+ for i := 0; i < len(b.negativeASCII); i++ {
+ b.negativeASCII[i] = last - beforefirst
+ }
+
+ b.lowASCII = 127
+ b.highASCII = 0
+
+ for examine = last; examine != beforefirst; examine -= bump {
+ ch = b.pattern[examine]
+
+ switch {
+ case ch < 128:
+ if b.lowASCII > ch {
+ b.lowASCII = ch
+ }
+
+ if b.highASCII < ch {
+ b.highASCII = ch
+ }
+
+ if b.negativeASCII[ch] == last-beforefirst {
+ b.negativeASCII[ch] = last - examine
+ }
+ case ch <= 0xffff:
+ i, j := ch>>8, ch&0xFF
+
+ if b.negativeUnicode == nil {
+ b.negativeUnicode = make([][]int, 256)
+ }
+
+ if b.negativeUnicode[i] == nil {
+ newarray := make([]int, 256)
+
+ for k := 0; k < len(newarray); k++ {
+ newarray[k] = last - beforefirst
+ }
+
+ if i == 0 {
+ copy(newarray, b.negativeASCII)
+ //TODO: this line needed?
+ b.negativeASCII = newarray
+ }
+
+ b.negativeUnicode[i] = newarray
+ }
+
+ if b.negativeUnicode[i][j] == last-beforefirst {
+ b.negativeUnicode[i][j] = last - examine
+ }
+ default:
+ // we can't do the filter because this algo doesn't support
+ // unicode chars >0xffff
+ return nil
+ }
+ }
+
+ return b
+}
+
+func (b *BmPrefix) String() string {
+ return string(b.pattern)
+}
+
+// Dump returns the contents of the filter as a human readable string
+func (b *BmPrefix) Dump(indent string) string {
+ buf := &bytes.Buffer{}
+
+ fmt.Fprintf(buf, "%sBM Pattern: %s\n%sPositive: ", indent, string(b.pattern), indent)
+ for i := 0; i < len(b.positive); i++ {
+ buf.WriteString(strconv.Itoa(b.positive[i]))
+ buf.WriteRune(' ')
+ }
+ buf.WriteRune('\n')
+
+ if b.negativeASCII != nil {
+ buf.WriteString(indent)
+ buf.WriteString("Negative table\n")
+ for i := 0; i < len(b.negativeASCII); i++ {
+ if b.negativeASCII[i] != len(b.pattern) {
+ fmt.Fprintf(buf, "%s %s %s\n", indent, Escape(string(rune(i))), strconv.Itoa(b.negativeASCII[i]))
+ }
+ }
+ }
+
+ return buf.String()
+}
+
+// Scan uses the Boyer-Moore algorithm to find the first occurrence
+// of the specified string within text, beginning at index, and
+// constrained within beglimit and endlimit.
+//
+// The direction and case-sensitivity of the match is determined
+// by the arguments to the RegexBoyerMoore constructor.
+func (b *BmPrefix) Scan(text []rune, index, beglimit, endlimit int) int {
+ var (
+ defadv, test, test2 int
+ match, startmatch, endmatch int
+ bump, advance int
+ chTest rune
+ unicodeLookup []int
+ )
+
+ if !b.rightToLeft {
+ defadv = len(b.pattern)
+ startmatch = len(b.pattern) - 1
+ endmatch = 0
+ test = index + defadv - 1
+ bump = 1
+ } else {
+ defadv = -len(b.pattern)
+ startmatch = 0
+ endmatch = -defadv - 1
+ test = index + defadv
+ bump = -1
+ }
+
+ chMatch := b.pattern[startmatch]
+
+ for {
+ if test >= endlimit || test < beglimit {
+ return -1
+ }
+
+ chTest = text[test]
+
+ if b.caseInsensitive {
+ chTest = unicode.ToLower(chTest)
+ }
+
+ if chTest != chMatch {
+ if chTest < 128 {
+ advance = b.negativeASCII[chTest]
+ } else if chTest < 0xffff && len(b.negativeUnicode) > 0 {
+ unicodeLookup = b.negativeUnicode[chTest>>8]
+ if len(unicodeLookup) > 0 {
+ advance = unicodeLookup[chTest&0xFF]
+ } else {
+ advance = defadv
+ }
+ } else {
+ advance = defadv
+ }
+
+ test += advance
+ } else { // if (chTest == chMatch)
+ test2 = test
+ match = startmatch
+
+ for {
+ if match == endmatch {
+ if b.rightToLeft {
+ return test2 + 1
+ } else {
+ return test2
+ }
+ }
+
+ match -= bump
+ test2 -= bump
+
+ chTest = text[test2]
+
+ if b.caseInsensitive {
+ chTest = unicode.ToLower(chTest)
+ }
+
+ if chTest != b.pattern[match] {
+ advance = b.positive[match]
+ if chTest < 128 {
+ test2 = (match - startmatch) + b.negativeASCII[chTest]
+ } else if chTest < 0xffff && len(b.negativeUnicode) > 0 {
+ unicodeLookup = b.negativeUnicode[chTest>>8]
+ if len(unicodeLookup) > 0 {
+ test2 = (match - startmatch) + unicodeLookup[chTest&0xFF]
+ } else {
+ test += advance
+ break
+ }
+ } else {
+ test += advance
+ break
+ }
+
+ if b.rightToLeft {
+ if test2 < advance {
+ advance = test2
+ }
+ } else if test2 > advance {
+ advance = test2
+ }
+
+ test += advance
+ break
+ }
+ }
+ }
+ }
+}
+
+// When a regex is anchored, we can do a quick IsMatch test instead of a Scan
+func (b *BmPrefix) IsMatch(text []rune, index, beglimit, endlimit int) bool {
+ if !b.rightToLeft {
+ if index < beglimit || endlimit-index < len(b.pattern) {
+ return false
+ }
+
+ return b.matchPattern(text, index)
+ } else {
+ if index > endlimit || index-beglimit < len(b.pattern) {
+ return false
+ }
+
+ return b.matchPattern(text, index-len(b.pattern))
+ }
+}
+
+func (b *BmPrefix) matchPattern(text []rune, index int) bool {
+ if len(text)-index < len(b.pattern) {
+ return false
+ }
+
+ if b.caseInsensitive {
+ for i := 0; i < len(b.pattern); i++ {
+ //Debug.Assert(textinfo.ToLower(_pattern[i]) == _pattern[i], "pattern should be converted to lower case in constructor!");
+ if unicode.ToLower(text[index+i]) != b.pattern[i] {
+ return false
+ }
+ }
+ return true
+ } else {
+ for i := 0; i < len(b.pattern); i++ {
+ if text[index+i] != b.pattern[i] {
+ return false
+ }
+ }
+ return true
+ }
+}
+
+type AnchorLoc int16
+
+// where the regex can be pegged
+const (
+ AnchorBeginning AnchorLoc = 0x0001
+ AnchorBol = 0x0002
+ AnchorStart = 0x0004
+ AnchorEol = 0x0008
+ AnchorEndZ = 0x0010
+ AnchorEnd = 0x0020
+ AnchorBoundary = 0x0040
+ AnchorECMABoundary = 0x0080
+)
+
+func getAnchors(tree *RegexTree) AnchorLoc {
+
+ var concatNode *regexNode
+ nextChild, result := 0, AnchorLoc(0)
+
+ curNode := tree.root
+
+ for {
+ switch curNode.t {
+ case ntConcatenate:
+ if len(curNode.children) > 0 {
+ concatNode = curNode
+ nextChild = 0
+ }
+
+ case ntGreedy, ntCapture:
+ curNode = curNode.children[0]
+ concatNode = nil
+ continue
+
+ case ntBol, ntEol, ntBoundary, ntECMABoundary, ntBeginning,
+ ntStart, ntEndZ, ntEnd:
+ return result | anchorFromType(curNode.t)
+
+ case ntEmpty, ntRequire, ntPrevent:
+
+ default:
+ return result
+ }
+
+ if concatNode == nil || nextChild >= len(concatNode.children) {
+ return result
+ }
+
+ curNode = concatNode.children[nextChild]
+ nextChild++
+ }
+}
+
+func anchorFromType(t nodeType) AnchorLoc {
+ switch t {
+ case ntBol:
+ return AnchorBol
+ case ntEol:
+ return AnchorEol
+ case ntBoundary:
+ return AnchorBoundary
+ case ntECMABoundary:
+ return AnchorECMABoundary
+ case ntBeginning:
+ return AnchorBeginning
+ case ntStart:
+ return AnchorStart
+ case ntEndZ:
+ return AnchorEndZ
+ case ntEnd:
+ return AnchorEnd
+ default:
+ return 0
+ }
+}
+
+// anchorDescription returns a human-readable description of the anchors
+func (anchors AnchorLoc) String() string {
+ buf := &bytes.Buffer{}
+
+ if 0 != (anchors & AnchorBeginning) {
+ buf.WriteString(", Beginning")
+ }
+ if 0 != (anchors & AnchorStart) {
+ buf.WriteString(", Start")
+ }
+ if 0 != (anchors & AnchorBol) {
+ buf.WriteString(", Bol")
+ }
+ if 0 != (anchors & AnchorBoundary) {
+ buf.WriteString(", Boundary")
+ }
+ if 0 != (anchors & AnchorECMABoundary) {
+ buf.WriteString(", ECMABoundary")
+ }
+ if 0 != (anchors & AnchorEol) {
+ buf.WriteString(", Eol")
+ }
+ if 0 != (anchors & AnchorEnd) {
+ buf.WriteString(", End")
+ }
+ if 0 != (anchors & AnchorEndZ) {
+ buf.WriteString(", EndZ")
+ }
+
+ // trim off comma
+ if buf.Len() >= 2 {
+ return buf.String()[2:]
+ }
+ return "None"
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/replacerdata.go b/vendor/github.com/dlclark/regexp2/syntax/replacerdata.go
new file mode 100644
index 0000000..bcf4d3f
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/replacerdata.go
@@ -0,0 +1,87 @@
+package syntax
+
+import (
+ "bytes"
+ "errors"
+)
+
+type ReplacerData struct {
+ Rep string
+ Strings []string
+ Rules []int
+}
+
+const (
+ replaceSpecials = 4
+ replaceLeftPortion = -1
+ replaceRightPortion = -2
+ replaceLastGroup = -3
+ replaceWholeString = -4
+)
+
+//ErrReplacementError is a general error during parsing the replacement text
+var ErrReplacementError = errors.New("Replacement pattern error.")
+
+// NewReplacerData will populate a reusable replacer data struct based on the given replacement string
+// and the capture group data from a regexp
+func NewReplacerData(rep string, caps map[int]int, capsize int, capnames map[string]int, op RegexOptions) (*ReplacerData, error) {
+ p := parser{
+ options: op,
+ caps: caps,
+ capsize: capsize,
+ capnames: capnames,
+ }
+ p.setPattern(rep)
+ concat, err := p.scanReplacement()
+ if err != nil {
+ return nil, err
+ }
+
+ if concat.t != ntConcatenate {
+ panic(ErrReplacementError)
+ }
+
+ sb := &bytes.Buffer{}
+ var (
+ strings []string
+ rules []int
+ )
+
+ for _, child := range concat.children {
+ switch child.t {
+ case ntMulti:
+ child.writeStrToBuf(sb)
+
+ case ntOne:
+ sb.WriteRune(child.ch)
+
+ case ntRef:
+ if sb.Len() > 0 {
+ rules = append(rules, len(strings))
+ strings = append(strings, sb.String())
+ sb.Reset()
+ }
+ slot := child.m
+
+ if len(caps) > 0 && slot >= 0 {
+ slot = caps[slot]
+ }
+
+ rules = append(rules, -replaceSpecials-1-slot)
+
+ default:
+ panic(ErrReplacementError)
+ }
+ }
+
+ if sb.Len() > 0 {
+ rules = append(rules, len(strings))
+ strings = append(strings, sb.String())
+ }
+
+ return &ReplacerData{
+ Rep: rep,
+ Strings: strings,
+ Rules: rules,
+ }, nil
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/tree.go b/vendor/github.com/dlclark/regexp2/syntax/tree.go
new file mode 100644
index 0000000..ea28829
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/tree.go
@@ -0,0 +1,654 @@
+package syntax
+
+import (
+ "bytes"
+ "fmt"
+ "math"
+ "strconv"
+)
+
+type RegexTree struct {
+ root *regexNode
+ caps map[int]int
+ capnumlist []int
+ captop int
+ Capnames map[string]int
+ Caplist []string
+ options RegexOptions
+}
+
+// It is built into a parsed tree for a regular expression.
+
+// Implementation notes:
+//
+// Since the node tree is a temporary data structure only used
+// during compilation of the regexp to integer codes, it's
+// designed for clarity and convenience rather than
+// space efficiency.
+//
+// RegexNodes are built into a tree, linked by the n.children list.
+// Each node also has a n.parent and n.ichild member indicating
+// its parent and which child # it is in its parent's list.
+//
+// RegexNodes come in as many types as there are constructs in
+// a regular expression, for example, "concatenate", "alternate",
+// "one", "rept", "group". There are also node types for basic
+// peephole optimizations, e.g., "onerep", "notsetrep", etc.
+//
+// Because perl 5 allows "lookback" groups that scan backwards,
+// each node also gets a "direction". Normally the value of
+// boolean n.backward = false.
+//
+// During parsing, top-level nodes are also stacked onto a parse
+// stack (a stack of trees). For this purpose we have a n.next
+// pointer. [Note that to save a few bytes, we could overload the
+// n.parent pointer instead.]
+//
+// On the parse stack, each tree has a "role" - basically, the
+// nonterminal in the grammar that the parser has currently
+// assigned to the tree. That code is stored in n.role.
+//
+// Finally, some of the different kinds of nodes have data.
+// Two integers (for the looping constructs) are stored in
+// n.operands, an an object (either a string or a set)
+// is stored in n.data
+type regexNode struct {
+ t nodeType
+ children []*regexNode
+ str []rune
+ set *CharSet
+ ch rune
+ m int
+ n int
+ options RegexOptions
+ next *regexNode
+}
+
+type nodeType int32
+
+const (
+ // The following are leaves, and correspond to primitive operations
+
+ ntOnerep nodeType = 0 // lef,back char,min,max a {n}
+ ntNotonerep = 1 // lef,back char,min,max .{n}
+ ntSetrep = 2 // lef,back set,min,max [\d]{n}
+ ntOneloop = 3 // lef,back char,min,max a {,n}
+ ntNotoneloop = 4 // lef,back char,min,max .{,n}
+ ntSetloop = 5 // lef,back set,min,max [\d]{,n}
+ ntOnelazy = 6 // lef,back char,min,max a {,n}?
+ ntNotonelazy = 7 // lef,back char,min,max .{,n}?
+ ntSetlazy = 8 // lef,back set,min,max [\d]{,n}?
+ ntOne = 9 // lef char a
+ ntNotone = 10 // lef char [^a]
+ ntSet = 11 // lef set [a-z\s] \w \s \d
+ ntMulti = 12 // lef string abcd
+ ntRef = 13 // lef group \#
+ ntBol = 14 // ^
+ ntEol = 15 // $
+ ntBoundary = 16 // \b
+ ntNonboundary = 17 // \B
+ ntBeginning = 18 // \A
+ ntStart = 19 // \G
+ ntEndZ = 20 // \Z
+ ntEnd = 21 // \Z
+
+ // Interior nodes do not correspond to primitive operations, but
+ // control structures compositing other operations
+
+ // Concat and alternate take n children, and can run forward or backwards
+
+ ntNothing = 22 // []
+ ntEmpty = 23 // ()
+ ntAlternate = 24 // a|b
+ ntConcatenate = 25 // ab
+ ntLoop = 26 // m,x * + ? {,}
+ ntLazyloop = 27 // m,x *? +? ?? {,}?
+ ntCapture = 28 // n ()
+ ntGroup = 29 // (?:)
+ ntRequire = 30 // (?=) (?<=)
+ ntPrevent = 31 // (?!) (?) (?<)
+ ntTestref = 33 // (?(n) | )
+ ntTestgroup = 34 // (?(...) | )
+
+ ntECMABoundary = 41 // \b
+ ntNonECMABoundary = 42 // \B
+)
+
+func newRegexNode(t nodeType, opt RegexOptions) *regexNode {
+ return ®exNode{
+ t: t,
+ options: opt,
+ }
+}
+
+func newRegexNodeCh(t nodeType, opt RegexOptions, ch rune) *regexNode {
+ return ®exNode{
+ t: t,
+ options: opt,
+ ch: ch,
+ }
+}
+
+func newRegexNodeStr(t nodeType, opt RegexOptions, str []rune) *regexNode {
+ return ®exNode{
+ t: t,
+ options: opt,
+ str: str,
+ }
+}
+
+func newRegexNodeSet(t nodeType, opt RegexOptions, set *CharSet) *regexNode {
+ return ®exNode{
+ t: t,
+ options: opt,
+ set: set,
+ }
+}
+
+func newRegexNodeM(t nodeType, opt RegexOptions, m int) *regexNode {
+ return ®exNode{
+ t: t,
+ options: opt,
+ m: m,
+ }
+}
+func newRegexNodeMN(t nodeType, opt RegexOptions, m, n int) *regexNode {
+ return ®exNode{
+ t: t,
+ options: opt,
+ m: m,
+ n: n,
+ }
+}
+
+func (n *regexNode) writeStrToBuf(buf *bytes.Buffer) {
+ for i := 0; i < len(n.str); i++ {
+ buf.WriteRune(n.str[i])
+ }
+}
+
+func (n *regexNode) addChild(child *regexNode) {
+ reduced := child.reduce()
+ n.children = append(n.children, reduced)
+ reduced.next = n
+}
+
+func (n *regexNode) insertChildren(afterIndex int, nodes []*regexNode) {
+ newChildren := make([]*regexNode, 0, len(n.children)+len(nodes))
+ n.children = append(append(append(newChildren, n.children[:afterIndex]...), nodes...), n.children[afterIndex:]...)
+}
+
+// removes children including the start but not the end index
+func (n *regexNode) removeChildren(startIndex, endIndex int) {
+ n.children = append(n.children[:startIndex], n.children[endIndex:]...)
+}
+
+// Pass type as OneLazy or OneLoop
+func (n *regexNode) makeRep(t nodeType, min, max int) {
+ n.t += (t - ntOne)
+ n.m = min
+ n.n = max
+}
+
+func (n *regexNode) reduce() *regexNode {
+ switch n.t {
+ case ntAlternate:
+ return n.reduceAlternation()
+
+ case ntConcatenate:
+ return n.reduceConcatenation()
+
+ case ntLoop, ntLazyloop:
+ return n.reduceRep()
+
+ case ntGroup:
+ return n.reduceGroup()
+
+ case ntSet, ntSetloop:
+ return n.reduceSet()
+
+ default:
+ return n
+ }
+}
+
+// Basic optimization. Single-letter alternations can be replaced
+// by faster set specifications, and nested alternations with no
+// intervening operators can be flattened:
+//
+// a|b|c|def|g|h -> [a-c]|def|[gh]
+// apple|(?:orange|pear)|grape -> apple|orange|pear|grape
+func (n *regexNode) reduceAlternation() *regexNode {
+ if len(n.children) == 0 {
+ return newRegexNode(ntNothing, n.options)
+ }
+
+ wasLastSet := false
+ lastNodeCannotMerge := false
+ var optionsLast RegexOptions
+ var i, j int
+
+ for i, j = 0, 0; i < len(n.children); i, j = i+1, j+1 {
+ at := n.children[i]
+
+ if j < i {
+ n.children[j] = at
+ }
+
+ for {
+ if at.t == ntAlternate {
+ for k := 0; k < len(at.children); k++ {
+ at.children[k].next = n
+ }
+ n.insertChildren(i+1, at.children)
+
+ j--
+ } else if at.t == ntSet || at.t == ntOne {
+ // Cannot merge sets if L or I options differ, or if either are negated.
+ optionsAt := at.options & (RightToLeft | IgnoreCase)
+
+ if at.t == ntSet {
+ if !wasLastSet || optionsLast != optionsAt || lastNodeCannotMerge || !at.set.IsMergeable() {
+ wasLastSet = true
+ lastNodeCannotMerge = !at.set.IsMergeable()
+ optionsLast = optionsAt
+ break
+ }
+ } else if !wasLastSet || optionsLast != optionsAt || lastNodeCannotMerge {
+ wasLastSet = true
+ lastNodeCannotMerge = false
+ optionsLast = optionsAt
+ break
+ }
+
+ // The last node was a Set or a One, we're a Set or One and our options are the same.
+ // Merge the two nodes.
+ j--
+ prev := n.children[j]
+
+ var prevCharClass *CharSet
+ if prev.t == ntOne {
+ prevCharClass = &CharSet{}
+ prevCharClass.addChar(prev.ch)
+ } else {
+ prevCharClass = prev.set
+ }
+
+ if at.t == ntOne {
+ prevCharClass.addChar(at.ch)
+ } else {
+ prevCharClass.addSet(*at.set)
+ }
+
+ prev.t = ntSet
+ prev.set = prevCharClass
+ } else if at.t == ntNothing {
+ j--
+ } else {
+ wasLastSet = false
+ lastNodeCannotMerge = false
+ }
+ break
+ }
+ }
+
+ if j < i {
+ n.removeChildren(j, i)
+ }
+
+ return n.stripEnation(ntNothing)
+}
+
+// Basic optimization. Adjacent strings can be concatenated.
+//
+// (?:abc)(?:def) -> abcdef
+func (n *regexNode) reduceConcatenation() *regexNode {
+ // Eliminate empties and concat adjacent strings/chars
+
+ var optionsLast RegexOptions
+ var optionsAt RegexOptions
+ var i, j int
+
+ if len(n.children) == 0 {
+ return newRegexNode(ntEmpty, n.options)
+ }
+
+ wasLastString := false
+
+ for i, j = 0, 0; i < len(n.children); i, j = i+1, j+1 {
+ var at, prev *regexNode
+
+ at = n.children[i]
+
+ if j < i {
+ n.children[j] = at
+ }
+
+ if at.t == ntConcatenate &&
+ ((at.options & RightToLeft) == (n.options & RightToLeft)) {
+ for k := 0; k < len(at.children); k++ {
+ at.children[k].next = n
+ }
+
+ //insert at.children at i+1 index in n.children
+ n.insertChildren(i+1, at.children)
+
+ j--
+ } else if at.t == ntMulti || at.t == ntOne {
+ // Cannot merge strings if L or I options differ
+ optionsAt = at.options & (RightToLeft | IgnoreCase)
+
+ if !wasLastString || optionsLast != optionsAt {
+ wasLastString = true
+ optionsLast = optionsAt
+ continue
+ }
+
+ j--
+ prev = n.children[j]
+
+ if prev.t == ntOne {
+ prev.t = ntMulti
+ prev.str = []rune{prev.ch}
+ }
+
+ if (optionsAt & RightToLeft) == 0 {
+ if at.t == ntOne {
+ prev.str = append(prev.str, at.ch)
+ } else {
+ prev.str = append(prev.str, at.str...)
+ }
+ } else {
+ if at.t == ntOne {
+ // insert at the front by expanding our slice, copying the data over, and then setting the value
+ prev.str = append(prev.str, 0)
+ copy(prev.str[1:], prev.str)
+ prev.str[0] = at.ch
+ } else {
+ //insert at the front...this one we'll make a new slice and copy both into it
+ merge := make([]rune, len(prev.str)+len(at.str))
+ copy(merge, at.str)
+ copy(merge[len(at.str):], prev.str)
+ prev.str = merge
+ }
+ }
+ } else if at.t == ntEmpty {
+ j--
+ } else {
+ wasLastString = false
+ }
+ }
+
+ if j < i {
+ // remove indices j through i from the children
+ n.removeChildren(j, i)
+ }
+
+ return n.stripEnation(ntEmpty)
+}
+
+// Nested repeaters just get multiplied with each other if they're not
+// too lumpy
+func (n *regexNode) reduceRep() *regexNode {
+
+ u := n
+ t := n.t
+ min := n.m
+ max := n.n
+
+ for {
+ if len(u.children) == 0 {
+ break
+ }
+
+ child := u.children[0]
+
+ // multiply reps of the same type only
+ if child.t != t {
+ childType := child.t
+
+ if !(childType >= ntOneloop && childType <= ntSetloop && t == ntLoop ||
+ childType >= ntOnelazy && childType <= ntSetlazy && t == ntLazyloop) {
+ break
+ }
+ }
+
+ // child can be too lumpy to blur, e.g., (a {100,105}) {3} or (a {2,})?
+ // [but things like (a {2,})+ are not too lumpy...]
+ if u.m == 0 && child.m > 1 || child.n < child.m*2 {
+ break
+ }
+
+ u = child
+ if u.m > 0 {
+ if (math.MaxInt32-1)/u.m < min {
+ u.m = math.MaxInt32
+ } else {
+ u.m = u.m * min
+ }
+ }
+ if u.n > 0 {
+ if (math.MaxInt32-1)/u.n < max {
+ u.n = math.MaxInt32
+ } else {
+ u.n = u.n * max
+ }
+ }
+ }
+
+ if math.MaxInt32 == min {
+ return newRegexNode(ntNothing, n.options)
+ }
+ return u
+
+}
+
+// Simple optimization. If a concatenation or alternation has only
+// one child strip out the intermediate node. If it has zero children,
+// turn it into an empty.
+func (n *regexNode) stripEnation(emptyType nodeType) *regexNode {
+ switch len(n.children) {
+ case 0:
+ return newRegexNode(emptyType, n.options)
+ case 1:
+ return n.children[0]
+ default:
+ return n
+ }
+}
+
+func (n *regexNode) reduceGroup() *regexNode {
+ u := n
+
+ for u.t == ntGroup {
+ u = u.children[0]
+ }
+
+ return u
+}
+
+// Simple optimization. If a set is a singleton, an inverse singleton,
+// or empty, it's transformed accordingly.
+func (n *regexNode) reduceSet() *regexNode {
+ // Extract empty-set, one and not-one case as special
+
+ if n.set == nil {
+ n.t = ntNothing
+ } else if n.set.IsSingleton() {
+ n.ch = n.set.SingletonChar()
+ n.set = nil
+ n.t += (ntOne - ntSet)
+ } else if n.set.IsSingletonInverse() {
+ n.ch = n.set.SingletonChar()
+ n.set = nil
+ n.t += (ntNotone - ntSet)
+ }
+
+ return n
+}
+
+func (n *regexNode) reverseLeft() *regexNode {
+ if n.options&RightToLeft != 0 && n.t == ntConcatenate && len(n.children) > 0 {
+ //reverse children order
+ for left, right := 0, len(n.children)-1; left < right; left, right = left+1, right-1 {
+ n.children[left], n.children[right] = n.children[right], n.children[left]
+ }
+ }
+
+ return n
+}
+
+func (n *regexNode) makeQuantifier(lazy bool, min, max int) *regexNode {
+ if min == 0 && max == 0 {
+ return newRegexNode(ntEmpty, n.options)
+ }
+
+ if min == 1 && max == 1 {
+ return n
+ }
+
+ switch n.t {
+ case ntOne, ntNotone, ntSet:
+ if lazy {
+ n.makeRep(Onelazy, min, max)
+ } else {
+ n.makeRep(Oneloop, min, max)
+ }
+ return n
+
+ default:
+ var t nodeType
+ if lazy {
+ t = ntLazyloop
+ } else {
+ t = ntLoop
+ }
+ result := newRegexNodeMN(t, n.options, min, max)
+ result.addChild(n)
+ return result
+ }
+}
+
+// debug functions
+
+var typeStr = []string{
+ "Onerep", "Notonerep", "Setrep",
+ "Oneloop", "Notoneloop", "Setloop",
+ "Onelazy", "Notonelazy", "Setlazy",
+ "One", "Notone", "Set",
+ "Multi", "Ref",
+ "Bol", "Eol", "Boundary", "Nonboundary",
+ "Beginning", "Start", "EndZ", "End",
+ "Nothing", "Empty",
+ "Alternate", "Concatenate",
+ "Loop", "Lazyloop",
+ "Capture", "Group", "Require", "Prevent", "Greedy",
+ "Testref", "Testgroup",
+ "Unknown", "Unknown", "Unknown",
+ "Unknown", "Unknown", "Unknown",
+ "ECMABoundary", "NonECMABoundary",
+}
+
+func (n *regexNode) description() string {
+ buf := &bytes.Buffer{}
+
+ buf.WriteString(typeStr[n.t])
+
+ if (n.options & ExplicitCapture) != 0 {
+ buf.WriteString("-C")
+ }
+ if (n.options & IgnoreCase) != 0 {
+ buf.WriteString("-I")
+ }
+ if (n.options & RightToLeft) != 0 {
+ buf.WriteString("-L")
+ }
+ if (n.options & Multiline) != 0 {
+ buf.WriteString("-M")
+ }
+ if (n.options & Singleline) != 0 {
+ buf.WriteString("-S")
+ }
+ if (n.options & IgnorePatternWhitespace) != 0 {
+ buf.WriteString("-X")
+ }
+ if (n.options & ECMAScript) != 0 {
+ buf.WriteString("-E")
+ }
+
+ switch n.t {
+ case ntOneloop, ntNotoneloop, ntOnelazy, ntNotonelazy, ntOne, ntNotone:
+ buf.WriteString("(Ch = " + CharDescription(n.ch) + ")")
+ break
+ case ntCapture:
+ buf.WriteString("(index = " + strconv.Itoa(n.m) + ", unindex = " + strconv.Itoa(n.n) + ")")
+ break
+ case ntRef, ntTestref:
+ buf.WriteString("(index = " + strconv.Itoa(n.m) + ")")
+ break
+ case ntMulti:
+ fmt.Fprintf(buf, "(String = %s)", string(n.str))
+ break
+ case ntSet, ntSetloop, ntSetlazy:
+ buf.WriteString("(Set = " + n.set.String() + ")")
+ break
+ }
+
+ switch n.t {
+ case ntOneloop, ntNotoneloop, ntOnelazy, ntNotonelazy, ntSetloop, ntSetlazy, ntLoop, ntLazyloop:
+ buf.WriteString("(Min = ")
+ buf.WriteString(strconv.Itoa(n.m))
+ buf.WriteString(", Max = ")
+ if n.n == math.MaxInt32 {
+ buf.WriteString("inf")
+ } else {
+ buf.WriteString(strconv.Itoa(n.n))
+ }
+ buf.WriteString(")")
+
+ break
+ }
+
+ return buf.String()
+}
+
+var padSpace = []byte(" ")
+
+func (t *RegexTree) Dump() string {
+ return t.root.dump()
+}
+
+func (n *regexNode) dump() string {
+ var stack []int
+ CurNode := n
+ CurChild := 0
+
+ buf := bytes.NewBufferString(CurNode.description())
+ buf.WriteRune('\n')
+
+ for {
+ if CurNode.children != nil && CurChild < len(CurNode.children) {
+ stack = append(stack, CurChild+1)
+ CurNode = CurNode.children[CurChild]
+ CurChild = 0
+
+ Depth := len(stack)
+ if Depth > 32 {
+ Depth = 32
+ }
+ buf.Write(padSpace[:Depth])
+ buf.WriteString(CurNode.description())
+ buf.WriteRune('\n')
+ } else {
+ if len(stack) == 0 {
+ break
+ }
+
+ CurChild = stack[len(stack)-1]
+ stack = stack[:len(stack)-1]
+ CurNode = CurNode.next
+ }
+ }
+ return buf.String()
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/writer.go b/vendor/github.com/dlclark/regexp2/syntax/writer.go
new file mode 100644
index 0000000..a5aa11c
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/writer.go
@@ -0,0 +1,500 @@
+package syntax
+
+import (
+ "bytes"
+ "fmt"
+ "math"
+ "os"
+)
+
+func Write(tree *RegexTree) (*Code, error) {
+ w := writer{
+ intStack: make([]int, 0, 32),
+ emitted: make([]int, 2),
+ stringhash: make(map[string]int),
+ sethash: make(map[string]int),
+ }
+
+ code, err := w.codeFromTree(tree)
+
+ if tree.options&Debug > 0 && code != nil {
+ os.Stdout.WriteString(code.Dump())
+ os.Stdout.WriteString("\n")
+ }
+
+ return code, err
+}
+
+type writer struct {
+ emitted []int
+
+ intStack []int
+ curpos int
+ stringhash map[string]int
+ stringtable [][]rune
+ sethash map[string]int
+ settable []*CharSet
+ counting bool
+ count int
+ trackcount int
+ caps map[int]int
+}
+
+const (
+ beforeChild nodeType = 64
+ afterChild = 128
+ //MaxPrefixSize is the largest number of runes we'll use for a BoyerMoyer prefix
+ MaxPrefixSize = 50
+)
+
+// The top level RegexCode generator. It does a depth-first walk
+// through the tree and calls EmitFragment to emits code before
+// and after each child of an interior node, and at each leaf.
+//
+// It runs two passes, first to count the size of the generated
+// code, and second to generate the code.
+//
+// We should time it against the alternative, which is
+// to just generate the code and grow the array as we go.
+func (w *writer) codeFromTree(tree *RegexTree) (*Code, error) {
+ var (
+ curNode *regexNode
+ curChild int
+ capsize int
+ )
+ // construct sparse capnum mapping if some numbers are unused
+
+ if tree.capnumlist == nil || tree.captop == len(tree.capnumlist) {
+ capsize = tree.captop
+ w.caps = nil
+ } else {
+ capsize = len(tree.capnumlist)
+ w.caps = tree.caps
+ for i := 0; i < len(tree.capnumlist); i++ {
+ w.caps[tree.capnumlist[i]] = i
+ }
+ }
+
+ w.counting = true
+
+ for {
+ if !w.counting {
+ w.emitted = make([]int, w.count)
+ }
+
+ curNode = tree.root
+ curChild = 0
+
+ w.emit1(Lazybranch, 0)
+
+ for {
+ if len(curNode.children) == 0 {
+ w.emitFragment(curNode.t, curNode, 0)
+ } else if curChild < len(curNode.children) {
+ w.emitFragment(curNode.t|beforeChild, curNode, curChild)
+
+ curNode = curNode.children[curChild]
+
+ w.pushInt(curChild)
+ curChild = 0
+ continue
+ }
+
+ if w.emptyStack() {
+ break
+ }
+
+ curChild = w.popInt()
+ curNode = curNode.next
+
+ w.emitFragment(curNode.t|afterChild, curNode, curChild)
+ curChild++
+ }
+
+ w.patchJump(0, w.curPos())
+ w.emit(Stop)
+
+ if !w.counting {
+ break
+ }
+
+ w.counting = false
+ }
+
+ fcPrefix := getFirstCharsPrefix(tree)
+ prefix := getPrefix(tree)
+ rtl := (tree.options & RightToLeft) != 0
+
+ var bmPrefix *BmPrefix
+ //TODO: benchmark string prefixes
+ if prefix != nil && len(prefix.PrefixStr) > 0 && MaxPrefixSize > 0 {
+ if len(prefix.PrefixStr) > MaxPrefixSize {
+ // limit prefix changes to 10k
+ prefix.PrefixStr = prefix.PrefixStr[:MaxPrefixSize]
+ }
+ bmPrefix = newBmPrefix(prefix.PrefixStr, prefix.CaseInsensitive, rtl)
+ } else {
+ bmPrefix = nil
+ }
+
+ return &Code{
+ Codes: w.emitted,
+ Strings: w.stringtable,
+ Sets: w.settable,
+ TrackCount: w.trackcount,
+ Caps: w.caps,
+ Capsize: capsize,
+ FcPrefix: fcPrefix,
+ BmPrefix: bmPrefix,
+ Anchors: getAnchors(tree),
+ RightToLeft: rtl,
+ }, nil
+}
+
+// The main RegexCode generator. It does a depth-first walk
+// through the tree and calls EmitFragment to emits code before
+// and after each child of an interior node, and at each leaf.
+func (w *writer) emitFragment(nodetype nodeType, node *regexNode, curIndex int) error {
+ bits := InstOp(0)
+
+ if nodetype <= ntRef {
+ if (node.options & RightToLeft) != 0 {
+ bits |= Rtl
+ }
+ if (node.options & IgnoreCase) != 0 {
+ bits |= Ci
+ }
+ }
+ ntBits := nodeType(bits)
+
+ switch nodetype {
+ case ntConcatenate | beforeChild, ntConcatenate | afterChild, ntEmpty:
+ break
+
+ case ntAlternate | beforeChild:
+ if curIndex < len(node.children)-1 {
+ w.pushInt(w.curPos())
+ w.emit1(Lazybranch, 0)
+ }
+
+ case ntAlternate | afterChild:
+ if curIndex < len(node.children)-1 {
+ lbPos := w.popInt()
+ w.pushInt(w.curPos())
+ w.emit1(Goto, 0)
+ w.patchJump(lbPos, w.curPos())
+ } else {
+ for i := 0; i < curIndex; i++ {
+ w.patchJump(w.popInt(), w.curPos())
+ }
+ }
+ break
+
+ case ntTestref | beforeChild:
+ if curIndex == 0 {
+ w.emit(Setjump)
+ w.pushInt(w.curPos())
+ w.emit1(Lazybranch, 0)
+ w.emit1(Testref, w.mapCapnum(node.m))
+ w.emit(Forejump)
+ }
+
+ case ntTestref | afterChild:
+ if curIndex == 0 {
+ branchpos := w.popInt()
+ w.pushInt(w.curPos())
+ w.emit1(Goto, 0)
+ w.patchJump(branchpos, w.curPos())
+ w.emit(Forejump)
+ if len(node.children) <= 1 {
+ w.patchJump(w.popInt(), w.curPos())
+ }
+ } else if curIndex == 1 {
+ w.patchJump(w.popInt(), w.curPos())
+ }
+
+ case ntTestgroup | beforeChild:
+ if curIndex == 0 {
+ w.emit(Setjump)
+ w.emit(Setmark)
+ w.pushInt(w.curPos())
+ w.emit1(Lazybranch, 0)
+ }
+
+ case ntTestgroup | afterChild:
+ if curIndex == 0 {
+ w.emit(Getmark)
+ w.emit(Forejump)
+ } else if curIndex == 1 {
+ Branchpos := w.popInt()
+ w.pushInt(w.curPos())
+ w.emit1(Goto, 0)
+ w.patchJump(Branchpos, w.curPos())
+ w.emit(Getmark)
+ w.emit(Forejump)
+ if len(node.children) <= 2 {
+ w.patchJump(w.popInt(), w.curPos())
+ }
+ } else if curIndex == 2 {
+ w.patchJump(w.popInt(), w.curPos())
+ }
+
+ case ntLoop | beforeChild, ntLazyloop | beforeChild:
+
+ if node.n < math.MaxInt32 || node.m > 1 {
+ if node.m == 0 {
+ w.emit1(Nullcount, 0)
+ } else {
+ w.emit1(Setcount, 1-node.m)
+ }
+ } else if node.m == 0 {
+ w.emit(Nullmark)
+ } else {
+ w.emit(Setmark)
+ }
+
+ if node.m == 0 {
+ w.pushInt(w.curPos())
+ w.emit1(Goto, 0)
+ }
+ w.pushInt(w.curPos())
+
+ case ntLoop | afterChild, ntLazyloop | afterChild:
+
+ startJumpPos := w.curPos()
+ lazy := (nodetype - (ntLoop | afterChild))
+
+ if node.n < math.MaxInt32 || node.m > 1 {
+ if node.n == math.MaxInt32 {
+ w.emit2(InstOp(Branchcount+lazy), w.popInt(), math.MaxInt32)
+ } else {
+ w.emit2(InstOp(Branchcount+lazy), w.popInt(), node.n-node.m)
+ }
+ } else {
+ w.emit1(InstOp(Branchmark+lazy), w.popInt())
+ }
+
+ if node.m == 0 {
+ w.patchJump(w.popInt(), startJumpPos)
+ }
+
+ case ntGroup | beforeChild, ntGroup | afterChild:
+
+ case ntCapture | beforeChild:
+ w.emit(Setmark)
+
+ case ntCapture | afterChild:
+ w.emit2(Capturemark, w.mapCapnum(node.m), w.mapCapnum(node.n))
+
+ case ntRequire | beforeChild:
+ // NOTE: the following line causes lookahead/lookbehind to be
+ // NON-BACKTRACKING. It can be commented out with (*)
+ w.emit(Setjump)
+
+ w.emit(Setmark)
+
+ case ntRequire | afterChild:
+ w.emit(Getmark)
+
+ // NOTE: the following line causes lookahead/lookbehind to be
+ // NON-BACKTRACKING. It can be commented out with (*)
+ w.emit(Forejump)
+
+ case ntPrevent | beforeChild:
+ w.emit(Setjump)
+ w.pushInt(w.curPos())
+ w.emit1(Lazybranch, 0)
+
+ case ntPrevent | afterChild:
+ w.emit(Backjump)
+ w.patchJump(w.popInt(), w.curPos())
+ w.emit(Forejump)
+
+ case ntGreedy | beforeChild:
+ w.emit(Setjump)
+
+ case ntGreedy | afterChild:
+ w.emit(Forejump)
+
+ case ntOne, ntNotone:
+ w.emit1(InstOp(node.t|ntBits), int(node.ch))
+
+ case ntNotoneloop, ntNotonelazy, ntOneloop, ntOnelazy:
+ if node.m > 0 {
+ if node.t == ntOneloop || node.t == ntOnelazy {
+ w.emit2(Onerep|bits, int(node.ch), node.m)
+ } else {
+ w.emit2(Notonerep|bits, int(node.ch), node.m)
+ }
+ }
+ if node.n > node.m {
+ if node.n == math.MaxInt32 {
+ w.emit2(InstOp(node.t|ntBits), int(node.ch), math.MaxInt32)
+ } else {
+ w.emit2(InstOp(node.t|ntBits), int(node.ch), node.n-node.m)
+ }
+ }
+
+ case ntSetloop, ntSetlazy:
+ if node.m > 0 {
+ w.emit2(Setrep|bits, w.setCode(node.set), node.m)
+ }
+ if node.n > node.m {
+ if node.n == math.MaxInt32 {
+ w.emit2(InstOp(node.t|ntBits), w.setCode(node.set), math.MaxInt32)
+ } else {
+ w.emit2(InstOp(node.t|ntBits), w.setCode(node.set), node.n-node.m)
+ }
+ }
+
+ case ntMulti:
+ w.emit1(InstOp(node.t|ntBits), w.stringCode(node.str))
+
+ case ntSet:
+ w.emit1(InstOp(node.t|ntBits), w.setCode(node.set))
+
+ case ntRef:
+ w.emit1(InstOp(node.t|ntBits), w.mapCapnum(node.m))
+
+ case ntNothing, ntBol, ntEol, ntBoundary, ntNonboundary, ntECMABoundary, ntNonECMABoundary, ntBeginning, ntStart, ntEndZ, ntEnd:
+ w.emit(InstOp(node.t))
+
+ default:
+ return fmt.Errorf("unexpected opcode in regular expression generation: %v", nodetype)
+ }
+
+ return nil
+}
+
+// To avoid recursion, we use a simple integer stack.
+// This is the push.
+func (w *writer) pushInt(i int) {
+ w.intStack = append(w.intStack, i)
+}
+
+// Returns true if the stack is empty.
+func (w *writer) emptyStack() bool {
+ return len(w.intStack) == 0
+}
+
+// This is the pop.
+func (w *writer) popInt() int {
+ //get our item
+ idx := len(w.intStack) - 1
+ i := w.intStack[idx]
+ //trim our slice
+ w.intStack = w.intStack[:idx]
+ return i
+}
+
+// Returns the current position in the emitted code.
+func (w *writer) curPos() int {
+ return w.curpos
+}
+
+// Fixes up a jump instruction at the specified offset
+// so that it jumps to the specified jumpDest.
+func (w *writer) patchJump(offset, jumpDest int) {
+ w.emitted[offset+1] = jumpDest
+}
+
+// Returns an index in the set table for a charset
+// uses a map to eliminate duplicates.
+func (w *writer) setCode(set *CharSet) int {
+ if w.counting {
+ return 0
+ }
+
+ buf := &bytes.Buffer{}
+
+ set.mapHashFill(buf)
+ hash := buf.String()
+ i, ok := w.sethash[hash]
+ if !ok {
+ i = len(w.sethash)
+ w.sethash[hash] = i
+ w.settable = append(w.settable, set)
+ }
+ return i
+}
+
+// Returns an index in the string table for a string.
+// uses a map to eliminate duplicates.
+func (w *writer) stringCode(str []rune) int {
+ if w.counting {
+ return 0
+ }
+
+ hash := string(str)
+ i, ok := w.stringhash[hash]
+ if !ok {
+ i = len(w.stringhash)
+ w.stringhash[hash] = i
+ w.stringtable = append(w.stringtable, str)
+ }
+
+ return i
+}
+
+// When generating code on a regex that uses a sparse set
+// of capture slots, we hash them to a dense set of indices
+// for an array of capture slots. Instead of doing the hash
+// at match time, it's done at compile time, here.
+func (w *writer) mapCapnum(capnum int) int {
+ if capnum == -1 {
+ return -1
+ }
+
+ if w.caps != nil {
+ return w.caps[capnum]
+ }
+
+ return capnum
+}
+
+// Emits a zero-argument operation. Note that the emit
+// functions all run in two modes: they can emit code, or
+// they can just count the size of the code.
+func (w *writer) emit(op InstOp) {
+ if w.counting {
+ w.count++
+ if opcodeBacktracks(op) {
+ w.trackcount++
+ }
+ return
+ }
+ w.emitted[w.curpos] = int(op)
+ w.curpos++
+}
+
+// Emits a one-argument operation.
+func (w *writer) emit1(op InstOp, opd1 int) {
+ if w.counting {
+ w.count += 2
+ if opcodeBacktracks(op) {
+ w.trackcount++
+ }
+ return
+ }
+ w.emitted[w.curpos] = int(op)
+ w.curpos++
+ w.emitted[w.curpos] = opd1
+ w.curpos++
+}
+
+// Emits a two-argument operation.
+func (w *writer) emit2(op InstOp, opd1, opd2 int) {
+ if w.counting {
+ w.count += 3
+ if opcodeBacktracks(op) {
+ w.trackcount++
+ }
+ return
+ }
+ w.emitted[w.curpos] = int(op)
+ w.curpos++
+ w.emitted[w.curpos] = opd1
+ w.curpos++
+ w.emitted[w.curpos] = opd2
+ w.curpos++
+}
diff --git a/vendor/github.com/dlclark/regexp2/testoutput1 b/vendor/github.com/dlclark/regexp2/testoutput1
new file mode 100644
index 0000000..fbf63fd
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/testoutput1
@@ -0,0 +1,7061 @@
+# This set of tests is for features that are compatible with all versions of
+# Perl >= 5.10, in non-UTF mode. It should run clean for the 8-bit, 16-bit, and
+# 32-bit PCRE libraries, and also using the perltest.pl script.
+
+#forbid_utf
+#newline_default lf any anycrlf
+#perltest
+
+/the quick brown fox/
+ the quick brown fox
+ 0: the quick brown fox
+ What do you know about the quick brown fox?
+ 0: the quick brown fox
+\= Expect no match
+ The quick brown FOX
+No match
+ What do you know about THE QUICK BROWN FOX?
+No match
+
+/The quick brown fox/i
+ the quick brown fox
+ 0: the quick brown fox
+ The quick brown FOX
+ 0: The quick brown FOX
+ What do you know about the quick brown fox?
+ 0: the quick brown fox
+ What do you know about THE QUICK BROWN FOX?
+ 0: THE QUICK BROWN FOX
+
+/abcd\t\n\r\f\a\e\071\x3b\$\\\?caxyz/
+ abcd\t\n\r\f\a\e9;\$\\?caxyz
+ 0: abcd\x09\x0a\x0d\x0c\x07\x1b9;$\?caxyz
+
+/a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz/
+ abxyzpqrrrabbxyyyypqAzz
+ 0: abxyzpqrrrabbxyyyypqAzz
+ abxyzpqrrrabbxyyyypqAzz
+ 0: abxyzpqrrrabbxyyyypqAzz
+ aabxyzpqrrrabbxyyyypqAzz
+ 0: aabxyzpqrrrabbxyyyypqAzz
+ aaabxyzpqrrrabbxyyyypqAzz
+ 0: aaabxyzpqrrrabbxyyyypqAzz
+ aaaabxyzpqrrrabbxyyyypqAzz
+ 0: aaaabxyzpqrrrabbxyyyypqAzz
+ abcxyzpqrrrabbxyyyypqAzz
+ 0: abcxyzpqrrrabbxyyyypqAzz
+ aabcxyzpqrrrabbxyyyypqAzz
+ 0: aabcxyzpqrrrabbxyyyypqAzz
+ aaabcxyzpqrrrabbxyyyypAzz
+ 0: aaabcxyzpqrrrabbxyyyypAzz
+ aaabcxyzpqrrrabbxyyyypqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqAzz
+ aaabcxyzpqrrrabbxyyyypqqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqqAzz
+ aaabcxyzpqrrrabbxyyyypqqqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqqqAzz
+ aaabcxyzpqrrrabbxyyyypqqqqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqqqqAzz
+ aaabcxyzpqrrrabbxyyyypqqqqqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqqqqqAzz
+ aaabcxyzpqrrrabbxyyyypqqqqqqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqqqqqqAzz
+ aaaabcxyzpqrrrabbxyyyypqAzz
+ 0: aaaabcxyzpqrrrabbxyyyypqAzz
+ abxyzzpqrrrabbxyyyypqAzz
+ 0: abxyzzpqrrrabbxyyyypqAzz
+ aabxyzzzpqrrrabbxyyyypqAzz
+ 0: aabxyzzzpqrrrabbxyyyypqAzz
+ aaabxyzzzzpqrrrabbxyyyypqAzz
+ 0: aaabxyzzzzpqrrrabbxyyyypqAzz
+ aaaabxyzzzzpqrrrabbxyyyypqAzz
+ 0: aaaabxyzzzzpqrrrabbxyyyypqAzz
+ abcxyzzpqrrrabbxyyyypqAzz
+ 0: abcxyzzpqrrrabbxyyyypqAzz
+ aabcxyzzzpqrrrabbxyyyypqAzz
+ 0: aabcxyzzzpqrrrabbxyyyypqAzz
+ aaabcxyzzzzpqrrrabbxyyyypqAzz
+ 0: aaabcxyzzzzpqrrrabbxyyyypqAzz
+ aaaabcxyzzzzpqrrrabbxyyyypqAzz
+ 0: aaaabcxyzzzzpqrrrabbxyyyypqAzz
+ aaaabcxyzzzzpqrrrabbbxyyyypqAzz
+ 0: aaaabcxyzzzzpqrrrabbbxyyyypqAzz
+ aaaabcxyzzzzpqrrrabbbxyyyyypqAzz
+ 0: aaaabcxyzzzzpqrrrabbbxyyyyypqAzz
+ aaabcxyzpqrrrabbxyyyypABzz
+ 0: aaabcxyzpqrrrabbxyyyypABzz
+ aaabcxyzpqrrrabbxyyyypABBzz
+ 0: aaabcxyzpqrrrabbxyyyypABBzz
+ >>>aaabxyzpqrrrabbxyyyypqAzz
+ 0: aaabxyzpqrrrabbxyyyypqAzz
+ >aaaabxyzpqrrrabbxyyyypqAzz
+ 0: aaaabxyzpqrrrabbxyyyypqAzz
+ >>>>abcxyzpqrrrabbxyyyypqAzz
+ 0: abcxyzpqrrrabbxyyyypqAzz
+\= Expect no match
+ abxyzpqrrabbxyyyypqAzz
+No match
+ abxyzpqrrrrabbxyyyypqAzz
+No match
+ abxyzpqrrrabxyyyypqAzz
+No match
+ aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz
+No match
+ aaaabcxyzzzzpqrrrabbbxyyypqAzz
+No match
+ aaabcxyzpqrrrabbxyyyypqqqqqqqAzz
+No match
+
+/^(abc){1,2}zz/
+ abczz
+ 0: abczz
+ 1: abc
+ abcabczz
+ 0: abcabczz
+ 1: abc
+\= Expect no match
+ zz
+No match
+ abcabcabczz
+No match
+ >>abczz
+No match
+
+/^(b+?|a){1,2}?c/
+ bc
+ 0: bc
+ 1: b
+ bbc
+ 0: bbc
+ 1: b
+ bbbc
+ 0: bbbc
+ 1: bb
+ bac
+ 0: bac
+ 1: a
+ bbac
+ 0: bbac
+ 1: a
+ aac
+ 0: aac
+ 1: a
+ abbbbbbbbbbbc
+ 0: abbbbbbbbbbbc
+ 1: bbbbbbbbbbb
+ bbbbbbbbbbbac
+ 0: bbbbbbbbbbbac
+ 1: a
+\= Expect no match
+ aaac
+No match
+ abbbbbbbbbbbac
+No match
+
+/^(b+|a){1,2}c/
+ bc
+ 0: bc
+ 1: b
+ bbc
+ 0: bbc
+ 1: bb
+ bbbc
+ 0: bbbc
+ 1: bbb
+ bac
+ 0: bac
+ 1: a
+ bbac
+ 0: bbac
+ 1: a
+ aac
+ 0: aac
+ 1: a
+ abbbbbbbbbbbc
+ 0: abbbbbbbbbbbc
+ 1: bbbbbbbbbbb
+ bbbbbbbbbbbac
+ 0: bbbbbbbbbbbac
+ 1: a
+\= Expect no match
+ aaac
+No match
+ abbbbbbbbbbbac
+No match
+
+/^(b+|a){1,2}?bc/
+ bbc
+ 0: bbc
+ 1: b
+
+/^(b*|ba){1,2}?bc/
+ babc
+ 0: babc
+ 1: ba
+ bbabc
+ 0: bbabc
+ 1: ba
+ bababc
+ 0: bababc
+ 1: ba
+\= Expect no match
+ bababbc
+No match
+ babababc
+No match
+
+/^(ba|b*){1,2}?bc/
+ babc
+ 0: babc
+ 1: ba
+ bbabc
+ 0: bbabc
+ 1: ba
+ bababc
+ 0: bababc
+ 1: ba
+\= Expect no match
+ bababbc
+No match
+ babababc
+No match
+
+#/^\ca\cA\c[;\c:/
+# \x01\x01\e;z
+# 0: \x01\x01\x1b;z
+
+/^[ab\]cde]/
+ athing
+ 0: a
+ bthing
+ 0: b
+ ]thing
+ 0: ]
+ cthing
+ 0: c
+ dthing
+ 0: d
+ ething
+ 0: e
+\= Expect no match
+ fthing
+No match
+ [thing
+No match
+ \\thing
+No match
+
+/^[]cde]/
+ ]thing
+ 0: ]
+ cthing
+ 0: c
+ dthing
+ 0: d
+ ething
+ 0: e
+\= Expect no match
+ athing
+No match
+ fthing
+No match
+
+/^[^ab\]cde]/
+ fthing
+ 0: f
+ [thing
+ 0: [
+ \\thing
+ 0: \
+\= Expect no match
+ athing
+No match
+ bthing
+No match
+ ]thing
+No match
+ cthing
+No match
+ dthing
+No match
+ ething
+No match
+
+/^[^]cde]/
+ athing
+ 0: a
+ fthing
+ 0: f
+\= Expect no match
+ ]thing
+No match
+ cthing
+No match
+ dthing
+No match
+ ething
+No match
+
+# DLC - I don't get this one
+#/^\/
+#
+# 0: \x81
+
+#updated to handle 16-bits utf8
+/^ÿ/
+ ÿ
+ 0: \xc3\xbf
+
+/^[0-9]+$/
+ 0
+ 0: 0
+ 1
+ 0: 1
+ 2
+ 0: 2
+ 3
+ 0: 3
+ 4
+ 0: 4
+ 5
+ 0: 5
+ 6
+ 0: 6
+ 7
+ 0: 7
+ 8
+ 0: 8
+ 9
+ 0: 9
+ 10
+ 0: 10
+ 100
+ 0: 100
+\= Expect no match
+ abc
+No match
+
+/^.*nter/
+ enter
+ 0: enter
+ inter
+ 0: inter
+ uponter
+ 0: uponter
+
+/^xxx[0-9]+$/
+ xxx0
+ 0: xxx0
+ xxx1234
+ 0: xxx1234
+\= Expect no match
+ xxx
+No match
+
+/^.+[0-9][0-9][0-9]$/
+ x123
+ 0: x123
+ x1234
+ 0: x1234
+ xx123
+ 0: xx123
+ 123456
+ 0: 123456
+\= Expect no match
+ 123
+No match
+
+/^.+?[0-9][0-9][0-9]$/
+ x123
+ 0: x123
+ x1234
+ 0: x1234
+ xx123
+ 0: xx123
+ 123456
+ 0: 123456
+\= Expect no match
+ 123
+No match
+
+/^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/
+ abc!pqr=apquxz.ixr.zzz.ac.uk
+ 0: abc!pqr=apquxz.ixr.zzz.ac.uk
+ 1: abc
+ 2: pqr
+\= Expect no match
+ !pqr=apquxz.ixr.zzz.ac.uk
+No match
+ abc!=apquxz.ixr.zzz.ac.uk
+No match
+ abc!pqr=apquxz:ixr.zzz.ac.uk
+No match
+ abc!pqr=apquxz.ixr.zzz.ac.ukk
+No match
+
+/:/
+ Well, we need a colon: somewhere
+ 0: :
+\= Expect no match
+ Fail without a colon
+No match
+
+/([\da-f:]+)$/i
+ 0abc
+ 0: 0abc
+ 1: 0abc
+ abc
+ 0: abc
+ 1: abc
+ fed
+ 0: fed
+ 1: fed
+ E
+ 0: E
+ 1: E
+ ::
+ 0: ::
+ 1: ::
+ 5f03:12C0::932e
+ 0: 5f03:12C0::932e
+ 1: 5f03:12C0::932e
+ fed def
+ 0: def
+ 1: def
+ Any old stuff
+ 0: ff
+ 1: ff
+\= Expect no match
+ 0zzz
+No match
+ gzzz
+No match
+ fed\x20
+No match
+ Any old rubbish
+No match
+
+/^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/
+ .1.2.3
+ 0: .1.2.3
+ 1: 1
+ 2: 2
+ 3: 3
+ A.12.123.0
+ 0: A.12.123.0
+ 1: 12
+ 2: 123
+ 3: 0
+\= Expect no match
+ .1.2.3333
+No match
+ 1.2.3
+No match
+ 1234.2.3
+No match
+
+/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/
+ 1 IN SOA non-sp1 non-sp2(
+ 0: 1 IN SOA non-sp1 non-sp2(
+ 1: 1
+ 2: non-sp1
+ 3: non-sp2
+ 1 IN SOA non-sp1 non-sp2 (
+ 0: 1 IN SOA non-sp1 non-sp2 (
+ 1: 1
+ 2: non-sp1
+ 3: non-sp2
+\= Expect no match
+ 1IN SOA non-sp1 non-sp2(
+No match
+
+/^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/
+ a.
+ 0: a.
+ Z.
+ 0: Z.
+ 2.
+ 0: 2.
+ ab-c.pq-r.
+ 0: ab-c.pq-r.
+ 1: .pq-r
+ sxk.zzz.ac.uk.
+ 0: sxk.zzz.ac.uk.
+ 1: .uk
+ x-.y-.
+ 0: x-.y-.
+ 1: .y-
+\= Expect no match
+ -abc.peq.
+No match
+
+/^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/
+ *.a
+ 0: *.a
+ *.b0-a
+ 0: *.b0-a
+ 1: 0-a
+ *.c3-b.c
+ 0: *.c3-b.c
+ 1: 3-b
+ 2: .c
+ *.c-a.b-c
+ 0: *.c-a.b-c
+ 1: -a
+ 2: .b-c
+ 3: -c
+\= Expect no match
+ *.0
+No match
+ *.a-
+No match
+ *.a-b.c-
+No match
+ *.c-a.0-c
+No match
+
+/^(?=ab(de))(abd)(e)/
+ abde
+ 0: abde
+ 1: de
+ 2: abd
+ 3: e
+
+/^(?!(ab)de|x)(abd)(f)/
+ abdf
+ 0: abdf
+ 1:
+ 2: abd
+ 3: f
+
+/^(?=(ab(cd)))(ab)/
+ abcd
+ 0: ab
+ 1: abcd
+ 2: cd
+ 3: ab
+
+/^[\da-f](\.[\da-f])*$/i
+ a.b.c.d
+ 0: a.b.c.d
+ 1: .d
+ A.B.C.D
+ 0: A.B.C.D
+ 1: .D
+ a.b.c.1.2.3.C
+ 0: a.b.c.1.2.3.C
+ 1: .C
+
+/^\".*\"\s*(;.*)?$/
+ \"1234\"
+ 0: "1234"
+ \"abcd\" ;
+ 0: "abcd" ;
+ 1: ;
+ \"\" ; rhubarb
+ 0: "" ; rhubarb
+ 1: ; rhubarb
+\= Expect no match
+ \"1234\" : things
+No match
+
+/^$/
+ \
+ 0:
+\= Expect no match
+ A non-empty line
+No match
+
+/ ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x
+ ab c
+ 0: ab c
+\= Expect no match
+ abc
+No match
+ ab cde
+No match
+
+/(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/
+ ab c
+ 0: ab c
+\= Expect no match
+ abc
+No match
+ ab cde
+No match
+
+/^ a\ b[c ]d $/x
+ a bcd
+ 0: a bcd
+ a b d
+ 0: a b d
+\= Expect no match
+ abcd
+No match
+ ab d
+No match
+
+/^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/
+ abcdefhijklm
+ 0: abcdefhijklm
+ 1: abc
+ 2: bc
+ 3: c
+ 4: def
+ 5: ef
+ 6: f
+ 7: hij
+ 8: ij
+ 9: j
+10: klm
+11: lm
+12: m
+
+/^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/
+ abcdefhijklm
+ 0: abcdefhijklm
+ 1: bc
+ 2: c
+ 3: ef
+ 4: f
+ 5: ij
+ 6: j
+ 7: lm
+ 8: m
+
+#/^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/
+# a+ Z0+\x08\n\x1d\x12
+# 0: a+ Z0+\x08\x0a\x1d\x12
+
+/^[.^$|()*+?{,}]+/
+ .^\$(*+)|{?,?}
+ 0: .^$(*+)|{?,?}
+
+/^a*\w/
+ z
+ 0: z
+ az
+ 0: az
+ aaaz
+ 0: aaaz
+ a
+ 0: a
+ aa
+ 0: aa
+ aaaa
+ 0: aaaa
+ a+
+ 0: a
+ aa+
+ 0: aa
+
+/^a*?\w/
+ z
+ 0: z
+ az
+ 0: a
+ aaaz
+ 0: a
+ a
+ 0: a
+ aa
+ 0: a
+ aaaa
+ 0: a
+ a+
+ 0: a
+ aa+
+ 0: a
+
+/^a+\w/
+ az
+ 0: az
+ aaaz
+ 0: aaaz
+ aa
+ 0: aa
+ aaaa
+ 0: aaaa
+ aa+
+ 0: aa
+
+/^a+?\w/
+ az
+ 0: az
+ aaaz
+ 0: aa
+ aa
+ 0: aa
+ aaaa
+ 0: aa
+ aa+
+ 0: aa
+
+/^\d{8}\w{2,}/
+ 1234567890
+ 0: 1234567890
+ 12345678ab
+ 0: 12345678ab
+ 12345678__
+ 0: 12345678__
+\= Expect no match
+ 1234567
+No match
+
+/^[aeiou\d]{4,5}$/
+ uoie
+ 0: uoie
+ 1234
+ 0: 1234
+ 12345
+ 0: 12345
+ aaaaa
+ 0: aaaaa
+\= Expect no match
+ 123456
+No match
+
+/^[aeiou\d]{4,5}?/
+ uoie
+ 0: uoie
+ 1234
+ 0: 1234
+ 12345
+ 0: 1234
+ aaaaa
+ 0: aaaa
+ 123456
+ 0: 1234
+
+/\A(abc|def)=(\1){2,3}\Z/
+ abc=abcabc
+ 0: abc=abcabc
+ 1: abc
+ 2: abc
+ def=defdefdef
+ 0: def=defdefdef
+ 1: def
+ 2: def
+\= Expect no match
+ abc=defdef
+No match
+
+/^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\11*(\3\4)\1(?#)2$/
+ abcdefghijkcda2
+ 0: abcdefghijkcda2
+ 1: a
+ 2: b
+ 3: c
+ 4: d
+ 5: e
+ 6: f
+ 7: g
+ 8: h
+ 9: i
+10: j
+11: k
+12: cd
+ abcdefghijkkkkcda2
+ 0: abcdefghijkkkkcda2
+ 1: a
+ 2: b
+ 3: c
+ 4: d
+ 5: e
+ 6: f
+ 7: g
+ 8: h
+ 9: i
+10: j
+11: k
+12: cd
+
+/(cat(a(ract|tonic)|erpillar)) \1()2(3)/
+ cataract cataract23
+ 0: cataract cataract23
+ 1: cataract
+ 2: aract
+ 3: ract
+ 4:
+ 5: 3
+ catatonic catatonic23
+ 0: catatonic catatonic23
+ 1: catatonic
+ 2: atonic
+ 3: tonic
+ 4:
+ 5: 3
+ caterpillar caterpillar23
+ 0: caterpillar caterpillar23
+ 1: caterpillar
+ 2: erpillar
+ 3:
+ 4:
+ 5: 3
+
+
+/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/
+ From abcd Mon Sep 01 12:33:02 1997
+ 0: From abcd Mon Sep 01 12:33
+ 1: abcd
+
+/^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/
+ From abcd Mon Sep 01 12:33:02 1997
+ 0: From abcd Mon Sep 01 12:33
+ 1: Sep
+ From abcd Mon Sep 1 12:33:02 1997
+ 0: From abcd Mon Sep 1 12:33
+ 1: Sep
+\= Expect no match
+ From abcd Sep 01 12:33:02 1997
+No match
+
+/^12.34/s
+ 12\n34
+ 0: 12\x0a34
+ 12\r34
+ 0: 12\x0d34
+
+/\w+(?=\t)/
+ the quick brown\t fox
+ 0: brown
+
+/foo(?!bar)(.*)/
+ foobar is foolish see?
+ 0: foolish see?
+ 1: lish see?
+
+/(?:(?!foo)...|^.{0,2})bar(.*)/
+ foobar crowbar etc
+ 0: rowbar etc
+ 1: etc
+ barrel
+ 0: barrel
+ 1: rel
+ 2barrel
+ 0: 2barrel
+ 1: rel
+ A barrel
+ 0: A barrel
+ 1: rel
+
+/^(\D*)(?=\d)(?!123)/
+ abc456
+ 0: abc
+ 1: abc
+\= Expect no match
+ abc123
+No match
+
+/^1234(?# test newlines
+ inside)/
+ 1234
+ 0: 1234
+
+/^1234 #comment in extended re
+ /x
+ 1234
+ 0: 1234
+
+/#rhubarb
+ abcd/x
+ abcd
+ 0: abcd
+
+/^abcd#rhubarb/x
+ abcd
+ 0: abcd
+
+/^(a)\1{2,3}(.)/
+ aaab
+ 0: aaab
+ 1: a
+ 2: b
+ aaaab
+ 0: aaaab
+ 1: a
+ 2: b
+ aaaaab
+ 0: aaaaa
+ 1: a
+ 2: a
+ aaaaaab
+ 0: aaaaa
+ 1: a
+ 2: a
+
+/(?!^)abc/
+ the abc
+ 0: abc
+\= Expect no match
+ abc
+No match
+
+/(?=^)abc/
+ abc
+ 0: abc
+\= Expect no match
+ the abc
+No match
+
+/^[ab]{1,3}(ab*|b)/
+ aabbbbb
+ 0: aabb
+ 1: b
+
+/^[ab]{1,3}?(ab*|b)/
+ aabbbbb
+ 0: aabbbbb
+ 1: abbbbb
+
+/^[ab]{1,3}?(ab*?|b)/
+ aabbbbb
+ 0: aa
+ 1: a
+
+/^[ab]{1,3}(ab*?|b)/
+ aabbbbb
+ 0: aabb
+ 1: b
+
+/ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # optional leading comment
+(?: (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # initial word
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) )* # further okay, if led by a period
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+# address
+| # or
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # one word, optionally followed by....
+(?:
+[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or...
+\(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) | # comments, or...
+
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+# quoted strings
+)*
+< (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # leading <
+(?: @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* , (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+)* # further okay, if led by comma
+: # closing colon
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* )? # optional route
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # initial word
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) )* # further okay, if led by a period
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+# address spec
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* > # trailing >
+# name and address
+) (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # optional trailing comment
+/x
+ Alan Other
+ 0: Alan Other
+
+ 0: user@dom.ain
+ user\@dom.ain
+ 0: user@dom.ain
+ \"A. Other\" (a comment)
+ 0: "A. Other" (a comment)
+ A. Other (a comment)
+ 0: Other (a comment)
+ \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay
+ 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay
+ A missing angle @,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+| # or
+" # "
+[^\\\x80-\xff\n\015"] * # normal
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )*
+" # "
+# Quoted string
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+\.
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+| # or
+" # "
+[^\\\x80-\xff\n\015"] * # normal
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )*
+" # "
+# Quoted string
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# additional words
+)*
+@
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+(?:
+\.
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+)*
+# address
+| # or
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+| # or
+" # "
+[^\\\x80-\xff\n\015"] * # normal
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )*
+" # "
+# Quoted string
+)
+# leading word
+[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces
+(?:
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+|
+" # "
+[^\\\x80-\xff\n\015"] * # normal
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )*
+" # "
+) # "special" comment or quoted string
+[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal"
+)*
+<
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# <
+(?:
+@
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+(?:
+\.
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+)*
+(?: ,
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+@
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+(?:
+\.
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+)*
+)* # additional domains
+:
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+)? # optional route
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+| # or
+" # "
+[^\\\x80-\xff\n\015"] * # normal
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )*
+" # "
+# Quoted string
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+\.
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+| # or
+" # "
+[^\\\x80-\xff\n\015"] * # normal
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )*
+" # "
+# Quoted string
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# additional words
+)*
+@
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+(?:
+\.
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+)*
+# address spec
+> # >
+# name and address
+)
+/x
+ Alan Other
+ 0: Alan Other
+
+ 0: user@dom.ain
+ user\@dom.ain
+ 0: user@dom.ain
+ \"A. Other\" (a comment)
+ 0: "A. Other"
+ A. Other (a comment)
+ 0: Other
+ \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay
+ 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay
+ A missing angle ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f
+
+/P[^*]TAIRE[^*]{1,6}?LL/
+ xxxxxxxxxxxPSTAIREISLLxxxxxxxxx
+ 0: PSTAIREISLL
+
+/P[^*]TAIRE[^*]{1,}?LL/
+ xxxxxxxxxxxPSTAIREISLLxxxxxxxxx
+ 0: PSTAIREISLL
+
+/(\.\d\d[1-9]?)\d+/
+ 1.230003938
+ 0: .230003938
+ 1: .23
+ 1.875000282
+ 0: .875000282
+ 1: .875
+ 1.235
+ 0: .235
+ 1: .23
+
+/(\.\d\d((?=0)|\d(?=\d)))/
+ 1.230003938
+ 0: .23
+ 1: .23
+ 2:
+ 1.875000282
+ 0: .875
+ 1: .875
+ 2: 5
+\= Expect no match
+ 1.235
+No match
+
+/\b(foo)\s+(\w+)/i
+ Food is on the foo table
+ 0: foo table
+ 1: foo
+ 2: table
+
+/foo(.*)bar/
+ The food is under the bar in the barn.
+ 0: food is under the bar in the bar
+ 1: d is under the bar in the
+
+/foo(.*?)bar/
+ The food is under the bar in the barn.
+ 0: food is under the bar
+ 1: d is under the
+
+/(.*)(\d*)/
+ I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers: 53147
+ 2:
+
+/(.*)(\d+)/
+ I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers: 5314
+ 2: 7
+
+/(.*?)(\d*)/
+ I have 2 numbers: 53147
+ 0:
+ 1:
+ 2:
+
+/(.*?)(\d+)/
+ I have 2 numbers: 53147
+ 0: I have 2
+ 1: I have
+ 2: 2
+
+/(.*)(\d+)$/
+ I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers: 5314
+ 2: 7
+
+/(.*?)(\d+)$/
+ I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers:
+ 2: 53147
+
+/(.*)\b(\d+)$/
+ I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers:
+ 2: 53147
+
+/(.*\D)(\d+)$/
+ I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers:
+ 2: 53147
+
+/^\D*(?!123)/
+ ABC123
+ 0: AB
+
+/^(\D*)(?=\d)(?!123)/
+ ABC445
+ 0: ABC
+ 1: ABC
+\= Expect no match
+ ABC123
+No match
+
+/^[W-]46]/
+ W46]789
+ 0: W46]
+ -46]789
+ 0: -46]
+\= Expect no match
+ Wall
+No match
+ Zebra
+No match
+ 42
+No match
+ [abcd]
+No match
+ ]abcd[
+No match
+
+/^[W-\]46]/
+ W46]789
+ 0: W
+ Wall
+ 0: W
+ Zebra
+ 0: Z
+ Xylophone
+ 0: X
+ 42
+ 0: 4
+ [abcd]
+ 0: [
+ ]abcd[
+ 0: ]
+ \\backslash
+ 0: \
+\= Expect no match
+ -46]789
+No match
+ well
+No match
+
+/\d\d\/\d\d\/\d\d\d\d/
+ 01/01/2000
+ 0: 01/01/2000
+
+/word (?:[a-zA-Z0-9]+ ){0,10}otherword/
+ word cat dog elephant mussel cow horse canary baboon snake shark otherword
+ 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword
+\= Expect no match
+ word cat dog elephant mussel cow horse canary baboon snake shark
+No match
+
+/word (?:[a-zA-Z0-9]+ ){0,300}otherword/
+\= Expect no match
+ word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope
+No match
+
+/^(a){0,0}/
+ bcd
+ 0:
+ abc
+ 0:
+ aab
+ 0:
+
+/^(a){0,1}/
+ bcd
+ 0:
+ abc
+ 0: a
+ 1: a
+ aab
+ 0: a
+ 1: a
+
+/^(a){0,2}/
+ bcd
+ 0:
+ abc
+ 0: a
+ 1: a
+ aab
+ 0: aa
+ 1: a
+
+/^(a){0,3}/
+ bcd
+ 0:
+ abc
+ 0: a
+ 1: a
+ aab
+ 0: aa
+ 1: a
+ aaa
+ 0: aaa
+ 1: a
+
+/^(a){0,}/
+ bcd
+ 0:
+ abc
+ 0: a
+ 1: a
+ aab
+ 0: aa
+ 1: a
+ aaa
+ 0: aaa
+ 1: a
+ aaaaaaaa
+ 0: aaaaaaaa
+ 1: a
+
+/^(a){1,1}/
+ abc
+ 0: a
+ 1: a
+ aab
+ 0: a
+ 1: a
+\= Expect no match
+ bcd
+No match
+
+/^(a){1,2}/
+ abc
+ 0: a
+ 1: a
+ aab
+ 0: aa
+ 1: a
+\= Expect no match
+ bcd
+No match
+
+/^(a){1,3}/
+ abc
+ 0: a
+ 1: a
+ aab
+ 0: aa
+ 1: a
+ aaa
+ 0: aaa
+ 1: a
+\= Expect no match
+ bcd
+No match
+
+/^(a){1,}/
+ abc
+ 0: a
+ 1: a
+ aab
+ 0: aa
+ 1: a
+ aaa
+ 0: aaa
+ 1: a
+ aaaaaaaa
+ 0: aaaaaaaa
+ 1: a
+\= Expect no match
+ bcd
+No match
+
+/.*\.gif/
+ borfle\nbib.gif\nno
+ 0: bib.gif
+
+/.{0,}\.gif/
+ borfle\nbib.gif\nno
+ 0: bib.gif
+
+/.*\.gif/m
+ borfle\nbib.gif\nno
+ 0: bib.gif
+
+/.*\.gif/s
+ borfle\nbib.gif\nno
+ 0: borfle\x0abib.gif
+
+/.*\.gif/ms
+ borfle\nbib.gif\nno
+ 0: borfle\x0abib.gif
+
+/.*$/
+ borfle\nbib.gif\nno
+ 0: no
+
+/.*$/m
+ borfle\nbib.gif\nno
+ 0: borfle
+
+/.*$/s
+ borfle\nbib.gif\nno
+ 0: borfle\x0abib.gif\x0ano
+
+/.*$/ms
+ borfle\nbib.gif\nno
+ 0: borfle\x0abib.gif\x0ano
+
+/.*$/
+ borfle\nbib.gif\nno\n
+ 0: no
+
+/.*$/m
+ borfle\nbib.gif\nno\n
+ 0: borfle
+
+/.*$/s
+ borfle\nbib.gif\nno\n
+ 0: borfle\x0abib.gif\x0ano\x0a
+
+/.*$/ms
+ borfle\nbib.gif\nno\n
+ 0: borfle\x0abib.gif\x0ano\x0a
+
+/(.*X|^B)/
+ abcde\n1234Xyz
+ 0: 1234X
+ 1: 1234X
+ BarFoo
+ 0: B
+ 1: B
+\= Expect no match
+ abcde\nBar
+No match
+
+/(.*X|^B)/m
+ abcde\n1234Xyz
+ 0: 1234X
+ 1: 1234X
+ BarFoo
+ 0: B
+ 1: B
+ abcde\nBar
+ 0: B
+ 1: B
+
+/(.*X|^B)/s
+ abcde\n1234Xyz
+ 0: abcde\x0a1234X
+ 1: abcde\x0a1234X
+ BarFoo
+ 0: B
+ 1: B
+\= Expect no match
+ abcde\nBar
+No match
+
+/(.*X|^B)/ms
+ abcde\n1234Xyz
+ 0: abcde\x0a1234X
+ 1: abcde\x0a1234X
+ BarFoo
+ 0: B
+ 1: B
+ abcde\nBar
+ 0: B
+ 1: B
+
+/(?s)(.*X|^B)/
+ abcde\n1234Xyz
+ 0: abcde\x0a1234X
+ 1: abcde\x0a1234X
+ BarFoo
+ 0: B
+ 1: B
+\= Expect no match
+ abcde\nBar
+No match
+
+/(?s:.*X|^B)/
+ abcde\n1234Xyz
+ 0: abcde\x0a1234X
+ BarFoo
+ 0: B
+\= Expect no match
+ abcde\nBar
+No match
+
+/^.*B/
+\= Expect no match
+ abc\nB
+No match
+
+/(?s)^.*B/
+ abc\nB
+ 0: abc\x0aB
+
+/(?m)^.*B/
+ abc\nB
+ 0: B
+
+/(?ms)^.*B/
+ abc\nB
+ 0: abc\x0aB
+
+/(?ms)^B/
+ abc\nB
+ 0: B
+
+/(?s)B$/
+ B\n
+ 0: B
+
+/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/
+ 123456654321
+ 0: 123456654321
+
+/^\d\d\d\d\d\d\d\d\d\d\d\d/
+ 123456654321
+ 0: 123456654321
+
+/^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/
+ 123456654321
+ 0: 123456654321
+
+/^[abc]{12}/
+ abcabcabcabc
+ 0: abcabcabcabc
+
+/^[a-c]{12}/
+ abcabcabcabc
+ 0: abcabcabcabc
+
+/^(a|b|c){12}/
+ abcabcabcabc
+ 0: abcabcabcabc
+ 1: c
+
+/^[abcdefghijklmnopqrstuvwxy0123456789]/
+ n
+ 0: n
+\= Expect no match
+ z
+No match
+
+/abcde{0,0}/
+ abcd
+ 0: abcd
+\= Expect no match
+ abce
+No match
+
+/ab[cd]{0,0}e/
+ abe
+ 0: abe
+\= Expect no match
+ abcde
+No match
+
+/ab(c){0,0}d/
+ abd
+ 0: abd
+\= Expect no match
+ abcd
+No match
+
+/a(b*)/
+ a
+ 0: a
+ 1:
+ ab
+ 0: ab
+ 1: b
+ abbbb
+ 0: abbbb
+ 1: bbbb
+\= Expect no match
+ bbbbb
+No match
+
+/ab\d{0}e/
+ abe
+ 0: abe
+\= Expect no match
+ ab1e
+No match
+
+/"([^\\"]+|\\.)*"/
+ the \"quick\" brown fox
+ 0: "quick"
+ 1: quick
+ \"the \\\"quick\\\" brown fox\"
+ 0: "the \"quick\" brown fox"
+ 1: brown fox
+
+/]{0,})>]{0,})>([\d]{0,}\.)(.*)((
([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD> ]{0,})>([\w\W\s\d][^<>]{0,})<\/TD> ]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is
+ 43.Word Processor
(N-1286) Lega lstaff.com CA - Statewide
+ 0: 43.Word Processor
(N-1286) Lega lstaff.com CA - Statewide
+ 1: BGCOLOR='#DBE9E9'
+ 2: align=left valign=top
+ 3: 43.
+ 4: Word Processor
(N-1286)
+ 5:
+ 6:
+ 7:
+ 8: align=left valign=top
+ 9: Lega lstaff.com
+10: align=left valign=top
+11: CA - Statewide
+
+/a[^a]b/
+ acb
+ 0: acb
+ a\nb
+ 0: a\x0ab
+
+/a.b/
+ acb
+ 0: acb
+\= Expect no match
+ a\nb
+No match
+
+/a[^a]b/s
+ acb
+ 0: acb
+ a\nb
+ 0: a\x0ab
+
+/a.b/s
+ acb
+ 0: acb
+ a\nb
+ 0: a\x0ab
+
+/^(b+?|a){1,2}?c/
+ bac
+ 0: bac
+ 1: a
+ bbac
+ 0: bbac
+ 1: a
+ bbbac
+ 0: bbbac
+ 1: a
+ bbbbac
+ 0: bbbbac
+ 1: a
+ bbbbbac
+ 0: bbbbbac
+ 1: a
+
+/^(b+|a){1,2}?c/
+ bac
+ 0: bac
+ 1: a
+ bbac
+ 0: bbac
+ 1: a
+ bbbac
+ 0: bbbac
+ 1: a
+ bbbbac
+ 0: bbbbac
+ 1: a
+ bbbbbac
+ 0: bbbbbac
+ 1: a
+
+/(?!\A)x/m
+ a\bx\n
+ 0: x
+ a\nx\n
+ 0: x
+\= Expect no match
+ x\nb\n
+No match
+
+/(A|B)*?CD/
+ CD
+ 0: CD
+
+/(A|B)*CD/
+ CD
+ 0: CD
+
+/(AB)*?\1/
+ ABABAB
+ 0: ABAB
+ 1: AB
+
+/(AB)*\1/
+ ABABAB
+ 0: ABABAB
+ 1: AB
+
+/(?.*/)foo"
+ /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo
+ 0: /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo
+\= Expect no match
+ /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/
+No match
+
+/(?>(\.\d\d[1-9]?))\d+/
+ 1.230003938
+ 0: .230003938
+ 1: .23
+ 1.875000282
+ 0: .875000282
+ 1: .875
+\= Expect no match
+ 1.235
+No match
+
+/^((?>\w+)|(?>\s+))*$/
+ now is the time for all good men to come to the aid of the party
+ 0: now is the time for all good men to come to the aid of the party
+ 1: party
+\= Expect no match
+ this is not a line with only words and spaces!
+No match
+
+/(\d+)(\w)/
+ 12345a
+ 0: 12345a
+ 1: 12345
+ 2: a
+ 12345+
+ 0: 12345
+ 1: 1234
+ 2: 5
+
+/((?>\d+))(\w)/
+ 12345a
+ 0: 12345a
+ 1: 12345
+ 2: a
+\= Expect no match
+ 12345+
+No match
+
+/(?>a+)b/
+ aaab
+ 0: aaab
+
+/((?>a+)b)/
+ aaab
+ 0: aaab
+ 1: aaab
+
+/(?>(a+))b/
+ aaab
+ 0: aaab
+ 1: aaa
+
+/(?>b)+/
+ aaabbbccc
+ 0: bbb
+
+/(?>a+|b+|c+)*c/
+ aaabbbbccccd
+ 0: aaabbbbc
+
+/((?>[^()]+)|\([^()]*\))+/
+ ((abc(ade)ufh()()x
+ 0: abc(ade)ufh()()x
+ 1: x
+
+/\(((?>[^()]+)|\([^()]+\))+\)/
+ (abc)
+ 0: (abc)
+ 1: abc
+ (abc(def)xyz)
+ 0: (abc(def)xyz)
+ 1: xyz
+\= Expect no match
+ ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+No match
+
+/a(?-i)b/i
+ ab
+ 0: ab
+ Ab
+ 0: Ab
+\= Expect no match
+ aB
+No match
+ AB
+No match
+
+/(a (?x)b c)d e/
+ a bcd e
+ 0: a bcd e
+ 1: a bc
+\= Expect no match
+ a b cd e
+No match
+ abcd e
+No match
+ a bcde
+No match
+
+/(a b(?x)c d (?-x)e f)/
+ a bcde f
+ 0: a bcde f
+ 1: a bcde f
+\= Expect no match
+ abcdef
+No match
+
+/(a(?i)b)c/
+ abc
+ 0: abc
+ 1: ab
+ aBc
+ 0: aBc
+ 1: aB
+\= Expect no match
+ abC
+No match
+ aBC
+No match
+ Abc
+No match
+ ABc
+No match
+ ABC
+No match
+ AbC
+No match
+
+/a(?i:b)c/
+ abc
+ 0: abc
+ aBc
+ 0: aBc
+\= Expect no match
+ ABC
+No match
+ abC
+No match
+ aBC
+No match
+
+/a(?i:b)*c/
+ aBc
+ 0: aBc
+ aBBc
+ 0: aBBc
+\= Expect no match
+ aBC
+No match
+ aBBC
+No match
+
+/a(?=b(?i)c)\w\wd/
+ abcd
+ 0: abcd
+ abCd
+ 0: abCd
+\= Expect no match
+ aBCd
+No match
+ abcD
+No match
+
+/(?s-i:more.*than).*million/i
+ more than million
+ 0: more than million
+ more than MILLION
+ 0: more than MILLION
+ more \n than Million
+ 0: more \x0a than Million
+\= Expect no match
+ MORE THAN MILLION
+No match
+ more \n than \n million
+No match
+
+/(?:(?s-i)more.*than).*million/i
+ more than million
+ 0: more than million
+ more than MILLION
+ 0: more than MILLION
+ more \n than Million
+ 0: more \x0a than Million
+\= Expect no match
+ MORE THAN MILLION
+No match
+ more \n than \n million
+No match
+
+/(?>a(?i)b+)+c/
+ abc
+ 0: abc
+ aBbc
+ 0: aBbc
+ aBBc
+ 0: aBBc
+\= Expect no match
+ Abc
+No match
+ abAb
+No match
+ abbC
+No match
+
+/(?=a(?i)b)\w\wc/
+ abc
+ 0: abc
+ aBc
+ 0: aBc
+\= Expect no match
+ Ab
+No match
+ abC
+No match
+ aBC
+No match
+
+/(?<=a(?i)b)(\w\w)c/
+ abxxc
+ 0: xxc
+ 1: xx
+ aBxxc
+ 0: xxc
+ 1: xx
+\= Expect no match
+ Abxxc
+No match
+ ABxxc
+No match
+ abxxC
+No match
+
+/(?:(a)|b)(?(1)A|B)/
+ aA
+ 0: aA
+ 1: a
+ bB
+ 0: bB
+\= Expect no match
+ aB
+No match
+ bA
+No match
+
+/^(a)?(?(1)a|b)+$/
+ aa
+ 0: aa
+ 1: a
+ b
+ 0: b
+ bb
+ 0: bb
+\= Expect no match
+ ab
+No match
+
+# Perl gets this next one wrong if the pattern ends with $; in that case it
+# fails to match "12".
+
+/^(?(?=abc)\w{3}:|\d\d)/
+ abc:
+ 0: abc:
+ 12
+ 0: 12
+ 123
+ 0: 12
+\= Expect no match
+ xyz
+No match
+
+/^(?(?!abc)\d\d|\w{3}:)$/
+ abc:
+ 0: abc:
+ 12
+ 0: 12
+\= Expect no match
+ 123
+No match
+ xyz
+No match
+
+/(?(?<=foo)bar|cat)/
+ foobar
+ 0: bar
+ cat
+ 0: cat
+ fcat
+ 0: cat
+ focat
+ 0: cat
+\= Expect no match
+ foocat
+No match
+
+/(?(?a*)*/
+ a
+ 0: a
+ aa
+ 0: aa
+ aaaa
+ 0: aaaa
+
+/(abc|)+/
+ abc
+ 0: abc
+ 1:
+ abcabc
+ 0: abcabc
+ 1:
+ abcabcabc
+ 0: abcabcabc
+ 1:
+ xyz
+ 0:
+ 1:
+
+/([a]*)*/
+ a
+ 0: a
+ 1:
+ aaaaa
+ 0: aaaaa
+ 1:
+
+/([ab]*)*/
+ a
+ 0: a
+ 1:
+ b
+ 0: b
+ 1:
+ ababab
+ 0: ababab
+ 1:
+ aaaabcde
+ 0: aaaab
+ 1:
+ bbbb
+ 0: bbbb
+ 1:
+
+/([^a]*)*/
+ b
+ 0: b
+ 1:
+ bbbb
+ 0: bbbb
+ 1:
+ aaa
+ 0:
+ 1:
+
+/([^ab]*)*/
+ cccc
+ 0: cccc
+ 1:
+ abab
+ 0:
+ 1:
+
+/([a]*?)*/
+ a
+ 0:
+ 1:
+ aaaa
+ 0:
+ 1:
+
+/([ab]*?)*/
+ a
+ 0:
+ 1:
+ b
+ 0:
+ 1:
+ abab
+ 0:
+ 1:
+ baba
+ 0:
+ 1:
+
+/([^a]*?)*/
+ b
+ 0:
+ 1:
+ bbbb
+ 0:
+ 1:
+ aaa
+ 0:
+ 1:
+
+/([^ab]*?)*/
+ c
+ 0:
+ 1:
+ cccc
+ 0:
+ 1:
+ baba
+ 0:
+ 1:
+
+/(?>a*)*/
+ a
+ 0: a
+ aaabcde
+ 0: aaa
+
+/((?>a*))*/
+ aaaaa
+ 0: aaaaa
+ 1:
+ aabbaa
+ 0: aa
+ 1:
+
+/((?>a*?))*/
+ aaaaa
+ 0:
+ 1:
+ aabbaa
+ 0:
+ 1:
+
+/(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x
+ 12-sep-98
+ 0: 12-sep-98
+ 12-09-98
+ 0: 12-09-98
+\= Expect no match
+ sep-12-98
+No match
+
+/(?<=(foo))bar\1/
+ foobarfoo
+ 0: barfoo
+ 1: foo
+ foobarfootling
+ 0: barfoo
+ 1: foo
+\= Expect no match
+ foobar
+No match
+ barfoo
+No match
+
+/(?i:saturday|sunday)/
+ saturday
+ 0: saturday
+ sunday
+ 0: sunday
+ Saturday
+ 0: Saturday
+ Sunday
+ 0: Sunday
+ SATURDAY
+ 0: SATURDAY
+ SUNDAY
+ 0: SUNDAY
+ SunDay
+ 0: SunDay
+
+/(a(?i)bc|BB)x/
+ abcx
+ 0: abcx
+ 1: abc
+ aBCx
+ 0: aBCx
+ 1: aBC
+ bbx
+ 0: bbx
+ 1: bb
+ BBx
+ 0: BBx
+ 1: BB
+\= Expect no match
+ abcX
+No match
+ aBCX
+No match
+ bbX
+No match
+ BBX
+No match
+
+/^([ab](?i)[cd]|[ef])/
+ ac
+ 0: ac
+ 1: ac
+ aC
+ 0: aC
+ 1: aC
+ bD
+ 0: bD
+ 1: bD
+ elephant
+ 0: e
+ 1: e
+ Europe
+ 0: E
+ 1: E
+ frog
+ 0: f
+ 1: f
+ France
+ 0: F
+ 1: F
+\= Expect no match
+ Africa
+No match
+
+/^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/
+ ab
+ 0: ab
+ 1: ab
+ aBd
+ 0: aBd
+ 1: aBd
+ xy
+ 0: xy
+ 1: xy
+ xY
+ 0: xY
+ 1: xY
+ zebra
+ 0: z
+ 1: z
+ Zambesi
+ 0: Z
+ 1: Z
+\= Expect no match
+ aCD
+No match
+ XY
+No match
+
+/(?<=foo\n)^bar/m
+ foo\nbar
+ 0: bar
+\= Expect no match
+ bar
+No match
+ baz\nbar
+No match
+
+/(?<=(?]&/
+ <&OUT
+ 0: <&
+
+/^(a\1?){4}$/
+ aaaaaaaaaa
+ 0: aaaaaaaaaa
+ 1: aaaa
+\= Expect no match
+ AB
+No match
+ aaaaaaaaa
+No match
+ aaaaaaaaaaa
+No match
+
+/^(a(?(1)\1)){4}$/
+ aaaaaaaaaa
+ 0: aaaaaaaaaa
+ 1: aaaa
+\= Expect no match
+ aaaaaaaaa
+No match
+ aaaaaaaaaaa
+No match
+
+/(?:(f)(o)(o)|(b)(a)(r))*/
+ foobar
+ 0: foobar
+ 1: f
+ 2: o
+ 3: o
+ 4: b
+ 5: a
+ 6: r
+
+/(?<=a)b/
+ ab
+ 0: b
+\= Expect no match
+ cb
+No match
+ b
+No match
+
+/(?
+ 2: abcd
+ xy:z:::abcd
+ 0: xy:z:::abcd
+ 1: xy:z:::
+ 2: abcd
+
+/^[^bcd]*(c+)/
+ aexycd
+ 0: aexyc
+ 1: c
+
+/(a*)b+/
+ caab
+ 0: aab
+ 1: aa
+
+/([\w:]+::)?(\w+)$/
+ abcd
+ 0: abcd
+ 1:
+ 2: abcd
+ xy:z:::abcd
+ 0: xy:z:::abcd
+ 1: xy:z:::
+ 2: abcd
+\= Expect no match
+ abcd:
+No match
+ abcd:
+No match
+
+/^[^bcd]*(c+)/
+ aexycd
+ 0: aexyc
+ 1: c
+
+/(>a+)ab/
+
+/(?>a+)b/
+ aaab
+ 0: aaab
+
+/([[:]+)/
+ a:[b]:
+ 0: :[
+ 1: :[
+
+/([[=]+)/
+ a=[b]=
+ 0: =[
+ 1: =[
+
+/([[.]+)/
+ a.[b].
+ 0: .[
+ 1: .[
+
+/((?>a+)b)/
+ aaab
+ 0: aaab
+ 1: aaab
+
+/(?>(a+))b/
+ aaab
+ 0: aaab
+ 1: aaa
+
+/((?>[^()]+)|\([^()]*\))+/
+ ((abc(ade)ufh()()x
+ 0: abc(ade)ufh()()x
+ 1: x
+
+/a\Z/
+\= Expect no match
+ aaab
+No match
+ a\nb\n
+No match
+
+/b\Z/
+ a\nb\n
+ 0: b
+
+/b\z/
+
+/b\Z/
+ a\nb
+ 0: b
+
+/b\z/
+ a\nb
+ 0: b
+
+/^(?>(?(1)\.|())[^\W_](?>[a-z0-9-]*[^\W_])?)+$/
+ a
+ 0: a
+ 1:
+ abc
+ 0: abc
+ 1:
+ a-b
+ 0: a-b
+ 1:
+ 0-9
+ 0: 0-9
+ 1:
+ a.b
+ 0: a.b
+ 1:
+ 5.6.7
+ 0: 5.6.7
+ 1:
+ the.quick.brown.fox
+ 0: the.quick.brown.fox
+ 1:
+ a100.b200.300c
+ 0: a100.b200.300c
+ 1:
+ 12-ab.1245
+ 0: 12-ab.1245
+ 1:
+\= Expect no match
+ \
+No match
+ .a
+No match
+ -a
+No match
+ a-
+No match
+ a.
+No match
+ a_b
+No match
+ a.-
+No match
+ a..
+No match
+ ab..bc
+No match
+ the.quick.brown.fox-
+No match
+ the.quick.brown.fox.
+No match
+ the.quick.brown.fox_
+No match
+ the.quick.brown.fox+
+No match
+
+/(?>.*)(?<=(abcd|wxyz))/
+ alphabetabcd
+ 0: alphabetabcd
+ 1: abcd
+ endingwxyz
+ 0: endingwxyz
+ 1: wxyz
+\= Expect no match
+ a rather long string that doesn't end with one of them
+No match
+
+/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/
+ word cat dog elephant mussel cow horse canary baboon snake shark otherword
+ 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword
+\= Expect no match
+ word cat dog elephant mussel cow horse canary baboon snake shark
+No match
+
+/word (?>[a-zA-Z0-9]+ ){0,30}otherword/
+\= Expect no match
+ word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope
+No match
+
+/(?<=\d{3}(?!999))foo/
+ 999foo
+ 0: foo
+ 123999foo
+ 0: foo
+\= Expect no match
+ 123abcfoo
+No match
+
+/(?<=(?!...999)\d{3})foo/
+ 999foo
+ 0: foo
+ 123999foo
+ 0: foo
+\= Expect no match
+ 123abcfoo
+No match
+
+/(?<=\d{3}(?!999)...)foo/
+ 123abcfoo
+ 0: foo
+ 123456foo
+ 0: foo
+\= Expect no match
+ 123999foo
+No match
+
+/(?<=\d{3}...)(?
+ 2:
+ 3: abcd
+
+ 2:
+ 3: abcd
+ \s*)=(?>\s*) # find
+ 2:
+ 3: abcd
+ Z)+|A)*/
+ ZABCDEFG
+ 0: ZA
+ 1: A
+
+/((?>)+|A)*/
+ ZABCDEFG
+ 0:
+ 1:
+
+/^[\d-a]/
+ abcde
+ 0: a
+ -things
+ 0: -
+ 0digit
+ 0: 0
+\= Expect no match
+ bcdef
+No match
+
+/[\s]+/
+ > \x09\x0a\x0c\x0d\x0b<
+ 0: \x09\x0a\x0c\x0d\x0b
+
+/\s+/
+ > \x09\x0a\x0c\x0d\x0b<
+ 0: \x09\x0a\x0c\x0d\x0b
+
+/ab/x
+ ab
+ 0: ab
+
+/(?!\A)x/m
+ a\nxb\n
+ 0: x
+
+/(?!^)x/m
+\= Expect no match
+ a\nxb\n
+No match
+
+#/abc\Qabc\Eabc/
+# abcabcabc
+# 0: abcabcabc
+
+#/abc\Q(*+|\Eabc/
+# abc(*+|abc
+# 0: abc(*+|abc
+
+#/ abc\Q abc\Eabc/x
+# abc abcabc
+# 0: abc abcabc
+#\= Expect no match
+# abcabcabc
+#No match
+
+#/abc#comment
+# \Q#not comment
+# literal\E/x
+# abc#not comment\n literal
+# 0: abc#not comment\x0a literal
+
+#/abc#comment
+# \Q#not comment
+# literal/x
+# abc#not comment\n literal
+# 0: abc#not comment\x0a literal
+
+#/abc#comment
+# \Q#not comment
+# literal\E #more comment
+# /x
+# abc#not comment\n literal
+# 0: abc#not comment\x0a literal
+
+#/abc#comment
+# \Q#not comment
+# literal\E #more comment/x
+# abc#not comment\n literal
+# 0: abc#not comment\x0a literal
+
+#/\Qabc\$xyz\E/
+# abc\\\$xyz
+# 0: abc\$xyz
+
+#/\Qabc\E\$\Qxyz\E/
+# abc\$xyz
+# 0: abc$xyz
+
+/\Gabc/
+ abc
+ 0: abc
+\= Expect no match
+ xyzabc
+No match
+
+/a(?x: b c )d/
+ XabcdY
+ 0: abcd
+\= Expect no match
+ Xa b c d Y
+No match
+
+/((?x)x y z | a b c)/
+ XabcY
+ 0: abc
+ 1: abc
+ AxyzB
+ 0: xyz
+ 1: xyz
+
+/(?i)AB(?-i)C/
+ XabCY
+ 0: abC
+\= Expect no match
+ XabcY
+No match
+
+/((?i)AB(?-i)C|D)E/
+ abCE
+ 0: abCE
+ 1: abC
+ DE
+ 0: DE
+ 1: D
+\= Expect no match
+ abcE
+No match
+ abCe
+No match
+ dE
+No match
+ De
+No match
+
+/(.*)\d+\1/
+ abc123abc
+ 0: abc123abc
+ 1: abc
+ abc123bc
+ 0: bc123bc
+ 1: bc
+
+/(.*)\d+\1/s
+ abc123abc
+ 0: abc123abc
+ 1: abc
+ abc123bc
+ 0: bc123bc
+ 1: bc
+
+/((.*))\d+\1/
+ abc123abc
+ 0: abc123abc
+ 1: abc
+ 2: abc
+ abc123bc
+ 0: bc123bc
+ 1: bc
+ 2: bc
+
+# This tests for an IPv6 address in the form where it can have up to
+# eight components, one and only one of which is empty. This must be
+# an internal component.
+
+/^(?!:) # colon disallowed at start
+ (?: # start of item
+ (?: [0-9a-f]{1,4} | # 1-4 hex digits or
+ (?(1)0 | () ) ) # if null previously matched, fail; else null
+ : # followed by colon
+ ){1,7} # end item; 1-7 of them required
+ [0-9a-f]{1,4} $ # final hex number at end of string
+ (?(1)|.) # check that there was an empty component
+ /ix
+ a123::a123
+ 0: a123::a123
+ 1:
+ a123:b342::abcd
+ 0: a123:b342::abcd
+ 1:
+ a123:b342::324e:abcd
+ 0: a123:b342::324e:abcd
+ 1:
+ a123:ddde:b342::324e:abcd
+ 0: a123:ddde:b342::324e:abcd
+ 1:
+ a123:ddde:b342::324e:dcba:abcd
+ 0: a123:ddde:b342::324e:dcba:abcd
+ 1:
+ a123:ddde:9999:b342::324e:dcba:abcd
+ 0: a123:ddde:9999:b342::324e:dcba:abcd
+ 1:
+\= Expect no match
+ 1:2:3:4:5:6:7:8
+No match
+ a123:bce:ddde:9999:b342::324e:dcba:abcd
+No match
+ a123::9999:b342::324e:dcba:abcd
+No match
+ abcde:2:3:4:5:6:7:8
+No match
+ ::1
+No match
+ abcd:fee0:123::
+No match
+ :1
+No match
+ 1:
+No match
+
+#/[z\Qa-d]\E]/
+# z
+# 0: z
+# a
+# 0: a
+# -
+# 0: -
+# d
+# 0: d
+# ]
+# 0: ]
+#\= Expect no match
+# b
+#No match
+
+#TODO: PCRE has an optimization to make this workable, .NET does not
+#/(a+)*b/
+#\= Expect no match
+# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+#No match
+
+# All these had to be updated because we understand unicode
+# and this looks like it's expecting single byte matches
+
+# .NET generates \xe4...not sure what's up, might just be different code pages
+/(?i)reg(?:ul(?:[aä]|ae)r|ex)/
+ REGular
+ 0: REGular
+ regulaer
+ 0: regulaer
+ Regex
+ 0: Regex
+ regulär
+ 0: regul\xc3\xa4r
+
+#/Åæåä[à-ÿÀ-ß]+/
+# Åæåäà
+# 0: \xc5\xe6\xe5\xe4\xe0
+# Åæåäÿ
+# 0: \xc5\xe6\xe5\xe4\xff
+# ÅæåäÀ
+# 0: \xc5\xe6\xe5\xe4\xc0
+# Åæåäß
+# 0: \xc5\xe6\xe5\xe4\xdf
+
+/(?<=Z)X./
+ \x84XAZXB
+ 0: XB
+
+/ab cd (?x) de fg/
+ ab cd defg
+ 0: ab cd defg
+
+/ab cd(?x) de fg/
+ ab cddefg
+ 0: ab cddefg
+\= Expect no match
+ abcddefg
+No match
+
+/(?
+ 2:
+ D
+ 0: D
+ 1:
+ 2:
+
+# this is really long with debug -- removing for now
+#/(a|)*\d/
+# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4
+# 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4
+# 1:
+#\= Expect no match
+# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+#No match
+
+/(?>a|)*\d/
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4
+ 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4
+\= Expect no match
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+No match
+
+/(?:a|)*\d/
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4
+ 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4
+\= Expect no match
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+No match
+
+/^(?s)(?>.*)(?
+ 2: a
+
+/(?>(a))b|(a)c/
+ ac
+ 0: ac
+ 1:
+ 2: a
+
+/(?=(a))ab|(a)c/
+ ac
+ 0: ac
+ 1:
+ 2: a
+
+/((?>(a))b|(a)c)/
+ ac
+ 0: ac
+ 1: ac
+ 2:
+ 3: a
+
+/(?=(?>(a))b|(a)c)(..)/
+ ac
+ 0: ac
+ 1:
+ 2: a
+ 3: ac
+
+/(?>(?>(a))b|(a)c)/
+ ac
+ 0: ac
+ 1:
+ 2: a
+
+/((?>(a+)b)+(aabab))/
+ aaaabaaabaabab
+ 0: aaaabaaabaabab
+ 1: aaaabaaabaabab
+ 2: aaa
+ 3: aabab
+
+/(?>a+|ab)+?c/
+\= Expect no match
+ aabc
+No match
+
+/(?>a+|ab)+c/
+\= Expect no match
+ aabc
+No match
+
+/(?:a+|ab)+c/
+ aabc
+ 0: aabc
+
+/^(?:a|ab)+c/
+ aaaabc
+ 0: aaaabc
+
+/(?=abc){0}xyz/
+ xyz
+ 0: xyz
+
+/(?=abc){1}xyz/
+\= Expect no match
+ xyz
+No match
+
+/(?=(a))?./
+ ab
+ 0: a
+ 1: a
+ bc
+ 0: b
+
+/(?=(a))??./
+ ab
+ 0: a
+ bc
+ 0: b
+
+/^(?!a){0}\w+/
+ aaaaa
+ 0: aaaaa
+
+/(?<=(abc))?xyz/
+ abcxyz
+ 0: xyz
+ 1: abc
+ pqrxyz
+ 0: xyz
+
+/^[g]+/
+ ggg<<>>
+ 0: ggg<<>>
+\= Expect no match
+ \\ga
+No match
+
+/^[ga]+/
+ gggagagaxyz
+ 0: gggagaga
+
+/[:a]xxx[b:]/
+ :xxx:
+ 0: :xxx:
+
+/(?<=a{2})b/i
+ xaabc
+ 0: b
+\= Expect no match
+ xabc
+No match
+
+/(?
+# 4:
+# 5: c
+# 6: d
+# 7: Y
+
+#/^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)/
+# XYabcdY
+# 0: XYabcdY
+# 1: a
+# 2: b
+# 3:
+# 4:
+# 5: c
+# 6: d
+# 7: Y
+
+/(?'abc'\w+):\k{2}/
+ a:aaxyz
+ 0: a:aa
+ 1: a
+ ab:ababxyz
+ 0: ab:abab
+ 1: ab
+\= Expect no match
+ a:axyz
+No match
+ ab:abxyz
+No match
+
+/^(?a)? (?(ab)b|c) (?(ab)d|e)/x
+ abd
+ 0: abd
+ 1: a
+ ce
+ 0: ce
+
+# .NET has more consistent grouping numbers with these dupe groups for the two options
+/(?:a(? (?')|(?")) |b(? (?')|(?")) ) (?(quote)[a-z]+|[0-9]+)/x,dupnames
+ a\"aaaaa
+ 0: a"aaaaa
+ 1: "
+ 2:
+ 3: "
+ b\"aaaaa
+ 0: b"aaaaa
+ 1: "
+ 2:
+ 3: "
+\= Expect no match
+ b\"11111
+No match
+
+#/(?P(?P0)(?P>L1)|(?P>L2))/
+# 0
+# 0: 0
+# 1: 0
+# 00
+# 0: 00
+# 1: 00
+# 2: 0
+# 0000
+# 0: 0000
+# 1: 0000
+# 2: 0
+
+#/(?P(?P0)|(?P>L2)(?P>L1))/
+# 0
+# 0: 0
+# 1: 0
+# 2: 0
+# 00
+# 0: 0
+# 1: 0
+# 2: 0
+# 0000
+# 0: 0
+# 1: 0
+# 2: 0
+
+# Check the use of names for failure
+
+# Check opening parens in comment when seeking forward reference.
+
+#/(?P(?P=abn)xxx|)+/
+# xxx
+# 0:
+# 1:
+
+#Posses
+/^(a)?(\w)/
+ aaaaX
+ 0: aa
+ 1: a
+ 2: a
+ YZ
+ 0: Y
+ 1:
+ 2: Y
+
+#Posses
+/^(?:a)?(\w)/
+ aaaaX
+ 0: aa
+ 1: a
+ YZ
+ 0: Y
+ 1: Y
+
+/\A.*?(a|bc)/
+ ba
+ 0: ba
+ 1: a
+
+/\A.*?(?:a|bc|d)/
+ ba
+ 0: ba
+
+# --------------------------
+
+/(another)?(\1?)test/
+ hello world test
+ 0: test
+ 1:
+ 2:
+
+/(another)?(\1+)test/
+\= Expect no match
+ hello world test
+No match
+
+/((?:a?)*)*c/
+ aac
+ 0: aac
+ 1:
+
+/((?>a?)*)*c/
+ aac
+ 0: aac
+ 1:
+
+/(?>.*?a)(?<=ba)/
+ aba
+ 0: ba
+
+/(?:.*?a)(?<=ba)/
+ aba
+ 0: aba
+
+/(?>.*?a)b/s
+ aab
+ 0: ab
+
+/(?>.*?a)b/
+ aab
+ 0: ab
+
+/(?>^a)b/s
+\= Expect no match
+ aab
+No match
+
+/(?>.*?)(?<=(abcd)|(wxyz))/
+ alphabetabcd
+ 0:
+ 1: abcd
+ endingwxyz
+ 0:
+ 1:
+ 2: wxyz
+
+/(?>.*)(?<=(abcd)|(wxyz))/
+ alphabetabcd
+ 0: alphabetabcd
+ 1: abcd
+ endingwxyz
+ 0: endingwxyz
+ 1:
+ 2: wxyz
+
+"(?>.*)foo"
+\= Expect no match
+ abcdfooxyz
+No match
+
+"(?>.*?)foo"
+ abcdfooxyz
+ 0: foo
+
+# Tests that try to figure out how Perl works. My hypothesis is that the first
+# verb that is backtracked onto is the one that acts. This seems to be the case
+# almost all the time, but there is one exception that is perhaps a bug.
+
+/a(?=bc).|abd/
+ abd
+ 0: abd
+ abc
+ 0: ab
+
+/a(?>bc)d|abd/
+ abceabd
+ 0: abd
+
+# These tests were formerly in test 2, but changes in PCRE and Perl have
+# made them compatible.
+
+/^(a)?(?(1)a|b)+$/
+\= Expect no match
+ a
+No match
+
+# ----
+
+/^\d*\w{4}/
+ 1234
+ 0: 1234
+\= Expect no match
+ 123
+No match
+
+/^[^b]*\w{4}/
+ aaaa
+ 0: aaaa
+\= Expect no match
+ aaa
+No match
+
+/^[^b]*\w{4}/i
+ aaaa
+ 0: aaaa
+\= Expect no match
+ aaa
+No match
+
+/^a*\w{4}/
+ aaaa
+ 0: aaaa
+\= Expect no match
+ aaa
+No match
+
+/^a*\w{4}/i
+ aaaa
+ 0: aaaa
+\= Expect no match
+ aaa
+No match
+
+/(?:(?foo)|(?bar))\k/dupnames
+ foofoo
+ 0: foofoo
+ 1: foo
+ barbar
+ 0: barbar
+ 1: bar
+
+# A notable difference between PCRE and .NET. According to
+# the PCRE docs:
+# If you make a subroutine call to a non-unique named
+# subpattern, the one that corresponds to the first
+# occurrence of the name is used. In the absence of
+# duplicate numbers (see the previous section) this is
+# the one with the lowest number.
+# .NET takes the most recently captured number according to MSDN:
+# A backreference refers to the most recent definition of
+# a group (the definition most immediately to the left,
+# when matching left to right). When a group makes multiple
+# captures, a backreference refers to the most recent capture.
+
+#/(?A)(?:(?foo)|(?bar))\k/dupnames
+# AfooA
+# 0: AfooA
+# 1: A
+# 2: foo
+# AbarA
+# 0: AbarA
+# 1: A
+# 2:
+# 3: bar
+#\= Expect no match
+# Afoofoo
+#No match
+# Abarbar
+#No match
+
+/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/
+ 1 IN SOA non-sp1 non-sp2(
+ 0: 1 IN SOA non-sp1 non-sp2(
+ 1: 1
+ 2: non-sp1
+ 3: non-sp2
+
+# TODO: .NET's group number ordering here in the second example is a bit odd
+/^ (?:(?A)|(?'B'B)(?A)) (?(A)x) (?(B)y)$/x,dupnames
+ Ax
+ 0: Ax
+ 1: A
+ BAxy
+ 0: BAxy
+ 1: A
+ 2: B
+
+/ ^ a + b $ /x
+ aaaab
+ 0: aaaab
+
+/ ^ a + #comment
+ b $ /x
+ aaaab
+ 0: aaaab
+
+/ ^ a + #comment
+ #comment
+ b $ /x
+ aaaab
+ 0: aaaab
+
+/ ^ (?> a + ) b $ /x
+ aaaab
+ 0: aaaab
+
+/ ^ ( a + ) + \w $ /x
+ aaaab
+ 0: aaaab
+ 1: aaaa
+
+/(?:x|(?:(xx|yy)+|x|x|x|x|x)|a|a|a)bc/
+\= Expect no match
+ acb
+No match
+
+#Posses
+#/\A(?:[^\"]+|\"(?:[^\"]*|\"\")*\")+/
+# NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
+# 0: NON QUOTED "QUOT""ED" AFTER
+
+#Posses
+#/\A(?:[^\"]+|\"(?:[^\"]+|\"\")*\")+/
+# NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
+# 0: NON QUOTED "QUOT""ED" AFTER
+
+#Posses
+#/\A(?:[^\"]+|\"(?:[^\"]+|\"\")+\")+/
+# NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
+# 0: NON QUOTED "QUOT""ED" AFTER
+
+#Posses
+#/\A([^\"1]+|[\"2]([^\"3]*|[\"4][\"5])*[\"6])+/
+# NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
+# 0: NON QUOTED "QUOT""ED" AFTER
+# 1: AFTER
+# 2:
+
+/^\w+(?>\s*)(?<=\w)/
+ test test
+ 0: tes
+
+#/(?Pa)?(?Pb)?(?()c|d)*l/
+# acl
+# 0: acl
+# 1: a
+# bdl
+# 0: bdl
+# 1:
+# 2: b
+# adl
+# 0: dl
+# bcl
+# 0: l
+
+/\sabc/
+ \x0babc
+ 0: \x0babc
+
+#/[\Qa]\E]+/
+# aa]]
+# 0: aa]]
+
+#/[\Q]a\E]+/
+# aa]]
+# 0: aa]]
+
+/A((((((((a))))))))\8B/
+ AaaB
+ 0: AaaB
+ 1: a
+ 2: a
+ 3: a
+ 4: a
+ 5: a
+ 6: a
+ 7: a
+ 8: a
+
+/A(((((((((a)))))))))\9B/
+ AaaB
+ 0: AaaB
+ 1: a
+ 2: a
+ 3: a
+ 4: a
+ 5: a
+ 6: a
+ 7: a
+ 8: a
+ 9: a
+
+/(|ab)*?d/
+ abd
+ 0: abd
+ 1: ab
+ xyd
+ 0: d
+
+/(\2|a)(\1)/
+ aaa
+ 0: aa
+ 1: a
+ 2: a
+
+/(\2)(\1)/
+
+"Z*(|d*){216}"
+
+/((((((((((((x))))))))))))\12/
+ xx
+ 0: xx
+ 1: x
+ 2: x
+ 3: x
+ 4: x
+ 5: x
+ 6: x
+ 7: x
+ 8: x
+ 9: x
+10: x
+11: x
+12: x
+
+#"(?|(\k'Pm')|(?'Pm'))"
+# abcd
+# 0:
+# 1:
+
+#/(?|(aaa)|(b))\g{1}/
+# aaaaaa
+# 0: aaaaaa
+# 1: aaa
+# bb
+# 0: bb
+# 1: b
+
+#/(?|(aaa)|(b))(?1)/
+# aaaaaa
+# 0: aaaaaa
+# 1: aaa
+# baaa
+# 0: baaa
+# 1: b
+#\= Expect no match
+# bb
+#No match
+
+#/(?|(aaa)|(b))/
+# xaaa
+# 0: aaa
+# 1: aaa
+# xbc
+# 0: b
+# 1: b
+
+#/(?|(?'a'aaa)|(?'a'b))\k'a'/
+# aaaaaa
+# 0: aaaaaa
+# 1: aaa
+# bb
+# 0: bb
+# 1: b
+
+#/(?|(?'a'aaa)|(?'a'b))(?'a'cccc)\k'a'/dupnames
+# aaaccccaaa
+# 0: aaaccccaaa
+# 1: aaa
+# 2: cccc
+# bccccb
+# 0: bccccb
+# 1: b
+# 2: cccc
+
+# End of testinput1
diff --git a/vendor/github.com/erikgeiser/coninput/.gitignore b/vendor/github.com/erikgeiser/coninput/.gitignore
new file mode 100644
index 0000000..66fd13c
--- /dev/null
+++ b/vendor/github.com/erikgeiser/coninput/.gitignore
@@ -0,0 +1,15 @@
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Dependency directories (remove the comment below to include it)
+# vendor/
diff --git a/vendor/github.com/erikgeiser/coninput/.golangci.yml b/vendor/github.com/erikgeiser/coninput/.golangci.yml
new file mode 100644
index 0000000..d3ed710
--- /dev/null
+++ b/vendor/github.com/erikgeiser/coninput/.golangci.yml
@@ -0,0 +1,24 @@
+linters:
+ enable-all: true
+ disable:
+ - golint
+ - interfacer
+ - scopelint
+ - maligned
+ - rowserrcheck
+ - funlen
+ - depguard
+ - goerr113
+ - exhaustivestruct
+ - testpackage
+ - gochecknoglobals
+ - wrapcheck
+ - forbidigo
+ - ifshort
+ - cyclop
+ - gomoddirectives
+linters-settings:
+ exhaustive:
+ default-signifies-exhaustive: true
+issues:
+ exclude-use-default: false
diff --git a/vendor/github.com/erikgeiser/coninput/LICENSE b/vendor/github.com/erikgeiser/coninput/LICENSE
new file mode 100644
index 0000000..83c2440
--- /dev/null
+++ b/vendor/github.com/erikgeiser/coninput/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Erik G.
+
+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/vendor/github.com/erikgeiser/coninput/README.md b/vendor/github.com/erikgeiser/coninput/README.md
new file mode 100644
index 0000000..22619d1
--- /dev/null
+++ b/vendor/github.com/erikgeiser/coninput/README.md
@@ -0,0 +1,2 @@
+# coninput
+Go library for input handling using Windows Console API
diff --git a/vendor/github.com/erikgeiser/coninput/keycodes.go b/vendor/github.com/erikgeiser/coninput/keycodes.go
new file mode 100644
index 0000000..902ee1b
--- /dev/null
+++ b/vendor/github.com/erikgeiser/coninput/keycodes.go
@@ -0,0 +1,205 @@
+package coninput
+
+// VirtualKeyCode holds a virtual key code (see
+// https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes).
+type VirtualKeyCode uint16
+
+const (
+ VK_LBUTTON VirtualKeyCode = 0x01
+ VK_RBUTTON VirtualKeyCode = 0x02
+ VK_CANCEL VirtualKeyCode = 0x03
+ VK_MBUTTON VirtualKeyCode = 0x04
+ VK_XBUTTON1 VirtualKeyCode = 0x05
+ VK_XBUTTON2 VirtualKeyCode = 0x06
+ VK_BACK VirtualKeyCode = 0x08
+ VK_TAB VirtualKeyCode = 0x09
+ VK_CLEAR VirtualKeyCode = 0x0C
+ VK_RETURN VirtualKeyCode = 0x0D
+ VK_SHIFT VirtualKeyCode = 0x10
+ VK_CONTROL VirtualKeyCode = 0x11
+ VK_MENU VirtualKeyCode = 0x12
+ VK_PAUSE VirtualKeyCode = 0x13
+ VK_CAPITAL VirtualKeyCode = 0x14
+ VK_KANA VirtualKeyCode = 0x15
+ VK_HANGEUL VirtualKeyCode = 0x15
+ VK_HANGUL VirtualKeyCode = 0x15
+ VK_IME_ON VirtualKeyCode = 0x16
+ VK_JUNJA VirtualKeyCode = 0x17
+ VK_FINAL VirtualKeyCode = 0x18
+ VK_HANJA VirtualKeyCode = 0x19
+ VK_KANJI VirtualKeyCode = 0x19
+ VK_IME_OFF VirtualKeyCode = 0x1A
+ VK_ESCAPE VirtualKeyCode = 0x1B
+ VK_CONVERT VirtualKeyCode = 0x1C
+ VK_NONCONVERT VirtualKeyCode = 0x1D
+ VK_ACCEPT VirtualKeyCode = 0x1E
+ VK_MODECHANGE VirtualKeyCode = 0x1F
+ VK_SPACE VirtualKeyCode = 0x20
+ VK_PRIOR VirtualKeyCode = 0x21
+ VK_NEXT VirtualKeyCode = 0x22
+ VK_END VirtualKeyCode = 0x23
+ VK_HOME VirtualKeyCode = 0x24
+ VK_LEFT VirtualKeyCode = 0x25
+ VK_UP VirtualKeyCode = 0x26
+ VK_RIGHT VirtualKeyCode = 0x27
+ VK_DOWN VirtualKeyCode = 0x28
+ VK_SELECT VirtualKeyCode = 0x29
+ VK_PRINT VirtualKeyCode = 0x2A
+ VK_EXECUTE VirtualKeyCode = 0x2B
+ VK_SNAPSHOT VirtualKeyCode = 0x2C
+ VK_INSERT VirtualKeyCode = 0x2D
+ VK_DELETE VirtualKeyCode = 0x2E
+ VK_HELP VirtualKeyCode = 0x2F
+ VK_0 VirtualKeyCode = 0x30
+ VK_1 VirtualKeyCode = 0x31
+ VK_2 VirtualKeyCode = 0x32
+ VK_3 VirtualKeyCode = 0x33
+ VK_4 VirtualKeyCode = 0x34
+ VK_5 VirtualKeyCode = 0x35
+ VK_6 VirtualKeyCode = 0x36
+ VK_7 VirtualKeyCode = 0x37
+ VK_8 VirtualKeyCode = 0x38
+ VK_9 VirtualKeyCode = 0x39
+ VK_A VirtualKeyCode = 0x41
+ VK_B VirtualKeyCode = 0x42
+ VK_C VirtualKeyCode = 0x43
+ VK_D VirtualKeyCode = 0x44
+ VK_E VirtualKeyCode = 0x45
+ VK_F VirtualKeyCode = 0x46
+ VK_G VirtualKeyCode = 0x47
+ VK_H VirtualKeyCode = 0x48
+ VK_I VirtualKeyCode = 0x49
+ VK_J VirtualKeyCode = 0x4A
+ VK_K VirtualKeyCode = 0x4B
+ VK_L VirtualKeyCode = 0x4C
+ VK_M VirtualKeyCode = 0x4D
+ VK_N VirtualKeyCode = 0x4E
+ VK_O VirtualKeyCode = 0x4F
+ VK_P VirtualKeyCode = 0x50
+ VK_Q VirtualKeyCode = 0x51
+ VK_R VirtualKeyCode = 0x52
+ VK_S VirtualKeyCode = 0x53
+ VK_T VirtualKeyCode = 0x54
+ VK_U VirtualKeyCode = 0x55
+ VK_V VirtualKeyCode = 0x56
+ VK_W VirtualKeyCode = 0x57
+ VK_X VirtualKeyCode = 0x58
+ VK_Y VirtualKeyCode = 0x59
+ VK_Z VirtualKeyCode = 0x5A
+ VK_LWIN VirtualKeyCode = 0x5B
+ VK_RWIN VirtualKeyCode = 0x5C
+ VK_APPS VirtualKeyCode = 0x5D
+ VK_SLEEP VirtualKeyCode = 0x5F
+ VK_NUMPAD0 VirtualKeyCode = 0x60
+ VK_NUMPAD1 VirtualKeyCode = 0x61
+ VK_NUMPAD2 VirtualKeyCode = 0x62
+ VK_NUMPAD3 VirtualKeyCode = 0x63
+ VK_NUMPAD4 VirtualKeyCode = 0x64
+ VK_NUMPAD5 VirtualKeyCode = 0x65
+ VK_NUMPAD6 VirtualKeyCode = 0x66
+ VK_NUMPAD7 VirtualKeyCode = 0x67
+ VK_NUMPAD8 VirtualKeyCode = 0x68
+ VK_NUMPAD9 VirtualKeyCode = 0x69
+ VK_MULTIPLY VirtualKeyCode = 0x6A
+ VK_ADD VirtualKeyCode = 0x6B
+ VK_SEPARATOR VirtualKeyCode = 0x6C
+ VK_SUBTRACT VirtualKeyCode = 0x6D
+ VK_DECIMAL VirtualKeyCode = 0x6E
+ VK_DIVIDE VirtualKeyCode = 0x6F
+ VK_F1 VirtualKeyCode = 0x70
+ VK_F2 VirtualKeyCode = 0x71
+ VK_F3 VirtualKeyCode = 0x72
+ VK_F4 VirtualKeyCode = 0x73
+ VK_F5 VirtualKeyCode = 0x74
+ VK_F6 VirtualKeyCode = 0x75
+ VK_F7 VirtualKeyCode = 0x76
+ VK_F8 VirtualKeyCode = 0x77
+ VK_F9 VirtualKeyCode = 0x78
+ VK_F10 VirtualKeyCode = 0x79
+ VK_F11 VirtualKeyCode = 0x7A
+ VK_F12 VirtualKeyCode = 0x7B
+ VK_F13 VirtualKeyCode = 0x7C
+ VK_F14 VirtualKeyCode = 0x7D
+ VK_F15 VirtualKeyCode = 0x7E
+ VK_F16 VirtualKeyCode = 0x7F
+ VK_F17 VirtualKeyCode = 0x80
+ VK_F18 VirtualKeyCode = 0x81
+ VK_F19 VirtualKeyCode = 0x82
+ VK_F20 VirtualKeyCode = 0x83
+ VK_F21 VirtualKeyCode = 0x84
+ VK_F22 VirtualKeyCode = 0x85
+ VK_F23 VirtualKeyCode = 0x86
+ VK_F24 VirtualKeyCode = 0x87
+ VK_NUMLOCK VirtualKeyCode = 0x90
+ VK_SCROLL VirtualKeyCode = 0x91
+ VK_OEM_NEC_EQUAL VirtualKeyCode = 0x92
+ VK_OEM_FJ_JISHO VirtualKeyCode = 0x92
+ VK_OEM_FJ_MASSHOU VirtualKeyCode = 0x93
+ VK_OEM_FJ_TOUROKU VirtualKeyCode = 0x94
+ VK_OEM_FJ_LOYA VirtualKeyCode = 0x95
+ VK_OEM_FJ_ROYA VirtualKeyCode = 0x96
+ VK_LSHIFT VirtualKeyCode = 0xA0
+ VK_RSHIFT VirtualKeyCode = 0xA1
+ VK_LCONTROL VirtualKeyCode = 0xA2
+ VK_RCONTROL VirtualKeyCode = 0xA3
+ VK_LMENU VirtualKeyCode = 0xA4
+ VK_RMENU VirtualKeyCode = 0xA5
+ VK_BROWSER_BACK VirtualKeyCode = 0xA6
+ VK_BROWSER_FORWARD VirtualKeyCode = 0xA7
+ VK_BROWSER_REFRESH VirtualKeyCode = 0xA8
+ VK_BROWSER_STOP VirtualKeyCode = 0xA9
+ VK_BROWSER_SEARCH VirtualKeyCode = 0xAA
+ VK_BROWSER_FAVORITES VirtualKeyCode = 0xAB
+ VK_BROWSER_HOME VirtualKeyCode = 0xAC
+ VK_VOLUME_MUTE VirtualKeyCode = 0xAD
+ VK_VOLUME_DOWN VirtualKeyCode = 0xAE
+ VK_VOLUME_UP VirtualKeyCode = 0xAF
+ VK_MEDIA_NEXT_TRACK VirtualKeyCode = 0xB0
+ VK_MEDIA_PREV_TRACK VirtualKeyCode = 0xB1
+ VK_MEDIA_STOP VirtualKeyCode = 0xB2
+ VK_MEDIA_PLAY_PAUSE VirtualKeyCode = 0xB3
+ VK_LAUNCH_MAIL VirtualKeyCode = 0xB4
+ VK_LAUNCH_MEDIA_SELECT VirtualKeyCode = 0xB5
+ VK_LAUNCH_APP1 VirtualKeyCode = 0xB6
+ VK_LAUNCH_APP2 VirtualKeyCode = 0xB7
+ VK_OEM_1 VirtualKeyCode = 0xBA
+ VK_OEM_PLUS VirtualKeyCode = 0xBB
+ VK_OEM_COMMA VirtualKeyCode = 0xBC
+ VK_OEM_MINUS VirtualKeyCode = 0xBD
+ VK_OEM_PERIOD VirtualKeyCode = 0xBE
+ VK_OEM_2 VirtualKeyCode = 0xBF
+ VK_OEM_3 VirtualKeyCode = 0xC0
+ VK_OEM_4 VirtualKeyCode = 0xDB
+ VK_OEM_5 VirtualKeyCode = 0xDC
+ VK_OEM_6 VirtualKeyCode = 0xDD
+ VK_OEM_7 VirtualKeyCode = 0xDE
+ VK_OEM_8 VirtualKeyCode = 0xDF
+ VK_OEM_AX VirtualKeyCode = 0xE1
+ VK_OEM_102 VirtualKeyCode = 0xE2
+ VK_ICO_HELP VirtualKeyCode = 0xE3
+ VK_ICO_00 VirtualKeyCode = 0xE4
+ VK_PROCESSKEY VirtualKeyCode = 0xE5
+ VK_ICO_CLEAR VirtualKeyCode = 0xE6
+ VK_OEM_RESET VirtualKeyCode = 0xE9
+ VK_OEM_JUMP VirtualKeyCode = 0xEA
+ VK_OEM_PA1 VirtualKeyCode = 0xEB
+ VK_OEM_PA2 VirtualKeyCode = 0xEC
+ VK_OEM_PA3 VirtualKeyCode = 0xED
+ VK_OEM_WSCTRL VirtualKeyCode = 0xEE
+ VK_OEM_CUSEL VirtualKeyCode = 0xEF
+ VK_OEM_ATTN VirtualKeyCode = 0xF0
+ VK_OEM_FINISH VirtualKeyCode = 0xF1
+ VK_OEM_COPY VirtualKeyCode = 0xF2
+ VK_OEM_AUTO VirtualKeyCode = 0xF3
+ VK_OEM_ENLW VirtualKeyCode = 0xF4
+ VK_OEM_BACKTAB VirtualKeyCode = 0xF5
+ VK_ATTN VirtualKeyCode = 0xF6
+ VK_CRSEL VirtualKeyCode = 0xF7
+ VK_EXSEL VirtualKeyCode = 0xF8
+ VK_EREOF VirtualKeyCode = 0xF9
+ VK_PLAY VirtualKeyCode = 0xFA
+ VK_ZOOM VirtualKeyCode = 0xFB
+ VK_NONAME VirtualKeyCode = 0xFC
+ VK_PA1 VirtualKeyCode = 0xFD
+ VK_OEM_CLEAR VirtualKeyCode = 0xFE
+)
diff --git a/vendor/github.com/erikgeiser/coninput/mode.go b/vendor/github.com/erikgeiser/coninput/mode.go
new file mode 100644
index 0000000..e6d8bf4
--- /dev/null
+++ b/vendor/github.com/erikgeiser/coninput/mode.go
@@ -0,0 +1,82 @@
+//go:build windows
+// +build windows
+
+package coninput
+
+import (
+ "strings"
+
+ "golang.org/x/sys/windows"
+)
+
+// AddInputModes returns the given mode with one or more additional modes enabled.
+func AddInputModes(mode uint32, enableModes ...uint32) uint32 {
+ for _, enableMode := range enableModes {
+ mode |= enableMode
+ }
+
+ return mode
+}
+
+// RemoveInputModes returns the given mode with one or more additional modes disabled.
+func RemoveInputModes(mode uint32, disableModes ...uint32) uint32 {
+ for _, disableMode := range disableModes {
+ mode &^= disableMode
+ }
+
+ return mode
+}
+
+// ToggleInputModes returns the given mode with one or more additional modes toggeled.
+func ToggleInputModes(mode uint32, toggleModes ...uint32) uint32 {
+ for _, toggeMode := range toggleModes {
+ mode ^= toggeMode
+ }
+
+ return mode
+}
+
+var inputModes = []struct {
+ mode uint32
+ name string
+}{
+ {mode: windows.ENABLE_ECHO_INPUT, name: "ENABLE_ECHO_INPUT"},
+ {mode: windows.ENABLE_INSERT_MODE, name: "ENABLE_INSERT_MODE"},
+ {mode: windows.ENABLE_LINE_INPUT, name: "ENABLE_LINE_INPUT"},
+ {mode: windows.ENABLE_MOUSE_INPUT, name: "ENABLE_MOUSE_INPUT"},
+ {mode: windows.ENABLE_PROCESSED_INPUT, name: "ENABLE_PROCESSED_INPUT"},
+ {mode: windows.ENABLE_QUICK_EDIT_MODE, name: "ENABLE_QUICK_EDIT_MODE"},
+ {mode: windows.ENABLE_WINDOW_INPUT, name: "ENABLE_WINDOW_INPUT"},
+ {mode: windows.ENABLE_VIRTUAL_TERMINAL_INPUT, name: "ENABLE_VIRTUAL_TERMINAL_INPUT"},
+}
+
+// ListInputMode returnes the isolated enabled input modes as a list.
+func ListInputModes(mode uint32) []uint32 {
+ modes := []uint32{}
+
+ for _, inputMode := range inputModes {
+ if mode&inputMode.mode > 0 {
+ modes = append(modes, inputMode.mode)
+ }
+ }
+
+ return modes
+}
+
+// ListInputMode returnes the isolated enabled input mode names as a list.
+func ListInputModeNames(mode uint32) []string {
+ modes := []string{}
+
+ for _, inputMode := range inputModes {
+ if mode&inputMode.mode > 0 {
+ modes = append(modes, inputMode.name)
+ }
+ }
+
+ return modes
+}
+
+// DescribeInputMode returns a string containing the names of each enabled input mode.
+func DescribeInputMode(mode uint32) string {
+ return strings.Join(ListInputModeNames(mode), "|")
+}
diff --git a/vendor/github.com/erikgeiser/coninput/read.go b/vendor/github.com/erikgeiser/coninput/read.go
new file mode 100644
index 0000000..b2dd82f
--- /dev/null
+++ b/vendor/github.com/erikgeiser/coninput/read.go
@@ -0,0 +1,154 @@
+//go:build windows
+// +build windows
+
+package coninput
+
+import (
+ "fmt"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+var (
+ modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
+ procReadConsoleInputW = modkernel32.NewProc("ReadConsoleInputW")
+ procPeekConsoleInputW = modkernel32.NewProc("PeekConsoleInputW")
+ procGetNumberOfConsoleInputEvents = modkernel32.NewProc("GetNumberOfConsoleInputEvents")
+ procFlushConsoleInputBuffer = modkernel32.NewProc("FlushConsoleInputBuffer")
+)
+
+// NewStdinHandle is a shortcut for windows.GetStdHandle(windows.STD_INPUT_HANDLE).
+func NewStdinHandle() (windows.Handle, error) {
+ return windows.GetStdHandle(windows.STD_INPUT_HANDLE)
+}
+
+// WinReadConsoleInput is a thin wrapper around the Windows console API function
+// ReadConsoleInput (see
+// https://docs.microsoft.com/en-us/windows/console/readconsoleinput). In most
+// cases it is more practical to either use ReadConsoleInput or
+// ReadNConsoleInputs.
+func WinReadConsoleInput(consoleInput windows.Handle, buffer *InputRecord,
+ length uint32, numberOfEventsRead *uint32) error {
+ r, _, e := syscall.Syscall6(procReadConsoleInputW.Addr(), 4,
+ uintptr(consoleInput), uintptr(unsafe.Pointer(buffer)), uintptr(length),
+ uintptr(unsafe.Pointer(numberOfEventsRead)), 0, 0)
+ if r == 0 {
+ return error(e)
+ }
+
+ return nil
+}
+
+// ReadNConsoleInputs is a wrapper around ReadConsoleInput (see
+// https://docs.microsoft.com/en-us/windows/console/readconsoleinput) that
+// automates the event buffer allocation in oder to provide io.Reader-like
+// sematics. maxEvents must be greater than zero.
+func ReadNConsoleInputs(console windows.Handle, maxEvents uint32) ([]InputRecord, error) {
+ if maxEvents == 0 {
+ return nil, fmt.Errorf("maxEvents cannot be zero")
+ }
+
+ var inputRecords = make([]InputRecord, maxEvents)
+ n, err := ReadConsoleInput(console, inputRecords)
+
+ return inputRecords[:n], err
+}
+
+// ReadConsoleInput provides an ideomatic interface to the Windows console API
+// function ReadConsoleInput (see
+// https://docs.microsoft.com/en-us/windows/console/readconsoleinput). The size
+// of inputRecords must be greater than zero.
+func ReadConsoleInput(console windows.Handle, inputRecords []InputRecord) (uint32, error) {
+ if len(inputRecords) == 0 {
+ return 0, fmt.Errorf("size of input record buffer cannot be zero")
+ }
+
+ var read uint32
+ err := WinReadConsoleInput(console, &inputRecords[0], uint32(len(inputRecords)), &read)
+
+ return read, err
+}
+
+// WinPeekConsoleInput is a thin wrapper around the Windows console API function
+// PeekConsoleInput (see
+// https://docs.microsoft.com/en-us/windows/console/peekconsoleinput). In most
+// cases it is more practical to either use PeekConsoleInput or
+// PeekNConsoleInputs.
+func WinPeekConsoleInput(consoleInput windows.Handle, buffer *InputRecord,
+ length uint32, numberOfEventsRead *uint32) error {
+ r, _, e := syscall.Syscall6(procPeekConsoleInputW.Addr(), 4,
+ uintptr(consoleInput), uintptr(unsafe.Pointer(buffer)), uintptr(length),
+ uintptr(unsafe.Pointer(numberOfEventsRead)), 0, 0)
+ if r == 0 {
+ return error(e)
+ }
+
+ return nil
+
+}
+
+// PeekNConsoleInputs is a wrapper around PeekConsoleInput (see
+// https://docs.microsoft.com/en-us/windows/console/peekconsoleinput) that
+// automates the event buffer allocation in oder to provide io.Reader-like
+// sematics. maxEvents must be greater than zero.
+func PeekNConsoleInputs(console windows.Handle, maxEvents uint32) ([]InputRecord, error) {
+ if maxEvents == 0 {
+ return nil, fmt.Errorf("maxEvents cannot be zero")
+ }
+
+ var inputRecords = make([]InputRecord, maxEvents)
+ n, err := PeekConsoleInput(console, inputRecords)
+
+ return inputRecords[:n], err
+}
+
+// PeekConsoleInput provides an ideomatic interface to the Windows console API
+// function PeekConsoleInput (see
+// https://docs.microsoft.com/en-us/windows/console/peekconsoleinput). The size
+// of inputRecords must be greater than zero.
+func PeekConsoleInput(console windows.Handle, inputRecords []InputRecord) (uint32, error) {
+ if len(inputRecords) == 0 {
+ return 0, fmt.Errorf("size of input record buffer cannot be zero")
+ }
+
+ var read uint32
+
+ err := WinPeekConsoleInput(console, &inputRecords[0], uint32(len(inputRecords)), &read)
+
+ return read, err
+}
+
+// WinGetNumberOfConsoleInputEvents provides an ideomatic interface to the
+// Windows console API function GetNumberOfConsoleInputEvents (see
+// https://docs.microsoft.com/en-us/windows/console/getnumberofconsoleinputevents).
+func WinGetNumberOfConsoleInputEvents(consoleInput windows.Handle, numberOfEvents *uint32) error {
+ r, _, e := syscall.Syscall6(procGetNumberOfConsoleInputEvents.Addr(), 2,
+ uintptr(consoleInput), uintptr(unsafe.Pointer(numberOfEvents)), 0,
+ 0, 0, 0)
+ if r == 0 {
+ return error(e)
+ }
+
+ return nil
+}
+
+// GetNumberOfConsoleInputEvents provides an ideomatic interface to the Windows
+// console API function GetNumberOfConsoleInputEvents (see
+// https://docs.microsoft.com/en-us/windows/console/getnumberofconsoleinputevents).
+func GetNumberOfConsoleInputEvents(console windows.Handle) (uint32, error) {
+ var nEvents uint32
+ err := WinGetNumberOfConsoleInputEvents(console, &nEvents)
+
+ return nEvents, err
+}
+
+func FlushConsoleInputBuffer(consoleInput windows.Handle) error {
+ r, _, e := syscall.Syscall(procFlushConsoleInputBuffer.Addr(), 1, uintptr(consoleInput), 0, 0)
+ if r == 0 {
+ return error(e)
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/erikgeiser/coninput/records.go b/vendor/github.com/erikgeiser/coninput/records.go
new file mode 100644
index 0000000..cccf7fb
--- /dev/null
+++ b/vendor/github.com/erikgeiser/coninput/records.go
@@ -0,0 +1,486 @@
+package coninput
+
+import (
+ "encoding/binary"
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+const (
+ maxEventSize = 16
+ wordPaddingBytes = 2
+)
+
+// EventType denots the type of an event
+type EventType uint16
+
+// EventUnion is the union data type that contains the data for any event.
+type EventUnion [maxEventSize]byte
+
+// InputRecord corresponds to the INPUT_RECORD structure from the Windows
+// console API (see
+// https://docs.microsoft.com/en-us/windows/console/input-record-str).
+type InputRecord struct {
+ // EventType specifies the type of event that helt in Event.
+ EventType EventType
+
+ // Padding of the 16-bit EventType to a whole 32-bit dword.
+ _ [wordPaddingBytes]byte
+
+ // Event holds the actual event data. Use Unrap to access it as its
+ // respective event type.
+ Event EventUnion
+}
+
+// String implements fmt.Stringer for InputRecord.
+func (ir InputRecord) String() string {
+ return ir.Unwrap().String()
+}
+
+// Unwrap parses the event data into an EventRecord of the respective event
+// type. The data in the returned EventRecord does not contain any references to
+// the passed InputRecord.
+func (ir InputRecord) Unwrap() EventRecord {
+ switch ir.EventType {
+ case FocusEventType:
+ return FocusEventRecord{SetFocus: ir.Event[0] > 0}
+ case KeyEventType:
+ return KeyEventRecord{
+ KeyDown: binary.LittleEndian.Uint32(ir.Event[0:4]) > 0,
+ RepeatCount: binary.LittleEndian.Uint16(ir.Event[4:6]),
+ VirtualKeyCode: VirtualKeyCode(binary.LittleEndian.Uint16(ir.Event[6:8])),
+ VirtualScanCode: VirtualKeyCode(binary.LittleEndian.Uint16(ir.Event[8:10])),
+ Char: rune(binary.LittleEndian.Uint16(ir.Event[10:12])),
+ ControlKeyState: ControlKeyState(binary.LittleEndian.Uint32(ir.Event[12:16])),
+ }
+ case MouseEventType:
+ m := MouseEventRecord{
+ MousePositon: Coord{
+ X: binary.LittleEndian.Uint16(ir.Event[0:2]),
+ Y: binary.LittleEndian.Uint16(ir.Event[2:4]),
+ },
+ ButtonState: ButtonState(binary.LittleEndian.Uint32(ir.Event[4:8])),
+ ControlKeyState: ControlKeyState(binary.LittleEndian.Uint32(ir.Event[8:12])),
+ EventFlags: EventFlags(binary.LittleEndian.Uint32(ir.Event[12:16])),
+ }
+
+ if (m.EventFlags&MOUSE_WHEELED > 0) || (m.EventFlags&MOUSE_HWHEELED > 0) {
+ if int16(highWord(uint32(m.ButtonState))) > 0 {
+ m.WheelDirection = 1
+ } else {
+ m.WheelDirection = -1
+ }
+ }
+
+ return m
+ case WindowBufferSizeEventType:
+ return WindowBufferSizeEventRecord{
+ Size: Coord{
+ X: binary.LittleEndian.Uint16(ir.Event[0:2]),
+ Y: binary.LittleEndian.Uint16(ir.Event[2:4]),
+ },
+ }
+ case MenuEventType:
+ return MenuEventRecord{
+ CommandID: binary.LittleEndian.Uint32(ir.Event[0:4]),
+ }
+ default:
+ return &UnknownEvent{InputRecord: ir}
+ }
+}
+
+// EventRecord represents one of the following event types:
+// TypeFocusEventRecord, TypeKeyEventRecord, TypeMouseEventRecord,
+// TypeWindowBufferSizeEvent, TypeMenuEventRecord and UnknownEvent.
+type EventRecord interface {
+ Type() string
+ fmt.Stringer
+}
+
+// FocusEventType is the event type for a FocusEventRecord (see
+// https://docs.microsoft.com/en-us/windows/console/input-record-str).
+const FocusEventType EventType = 0x0010
+
+// FocusEventRecord represent the FOCUS_EVENT_RECORD structure from the Windows
+// console API (see
+// https://docs.microsoft.com/en-us/windows/console/focus-event-record-str).
+// These events are used internally by the Windows console API and should be
+// ignored.
+type FocusEventRecord struct {
+ // SetFocus is reserved and should not be used.
+ SetFocus bool
+}
+
+// Ensure that FocusEventRecord satisfies EventRecord interface.
+var _ EventRecord = FocusEventRecord{}
+
+// Type ensures that FocusEventRecord satisfies EventRecord interface.
+func (e FocusEventRecord) Type() string { return "FocusEvent" }
+
+// String ensures that FocusEventRecord satisfies EventRecord and fmt.Stringer
+// interfaces.
+func (e FocusEventRecord) String() string { return fmt.Sprintf("%s[%v]", e.Type(), e.SetFocus) }
+
+// KeyEventType is the event type for a KeyEventRecord (see
+// https://docs.microsoft.com/en-us/windows/console/input-record-str).
+const KeyEventType EventType = 0x0001
+
+// KeyEventRecord represent the KEY_EVENT_RECORD structure from the Windows
+// console API (see
+// https://docs.microsoft.com/en-us/windows/console/key-event-record-str).
+type KeyEventRecord struct {
+ // KeyDown specified whether the key is pressed or released.
+ KeyDown bool
+
+ // RepeatCount indicates that a key is being held down. For example, when a
+ // key is held down, five events with RepeatCount equal to 1 may be
+ // generated, one event with RepeatCount equal to 5, or multiple events
+ // with RepeatCount greater than or equal to 1.
+ RepeatCount uint16
+
+ // VirtualKeyCode identifies the given key in a device-independent manner
+ // (see
+ // https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes).
+ VirtualKeyCode VirtualKeyCode
+
+ // VirtualScanCode represents the device-dependent value generated by the
+ // keyboard hardware.
+ VirtualScanCode VirtualKeyCode
+
+ // Char is the character that corresponds to the pressed key. Char can be
+ // zero for some keys.
+ Char rune
+
+ //ControlKeyState holds the state of the control keys.
+ ControlKeyState ControlKeyState
+}
+
+// Ensure that KeyEventRecord satisfies EventRecord interface.
+var _ EventRecord = KeyEventRecord{}
+
+// Type ensures that KeyEventRecord satisfies EventRecord interface.
+func (e KeyEventRecord) Type() string { return "KeyEvent" }
+
+// String ensures that KeyEventRecord satisfies EventRecord and fmt.Stringer
+// interfaces.
+func (e KeyEventRecord) String() string {
+ infos := []string{}
+
+ repeat := ""
+ if e.RepeatCount > 1 {
+ repeat = "x" + strconv.Itoa(int(e.RepeatCount))
+ }
+
+ infos = append(infos, fmt.Sprintf("%q%s", e.Char, repeat))
+
+ direction := "up"
+ if e.KeyDown {
+ direction = "down"
+ }
+
+ infos = append(infos, direction)
+
+ if e.ControlKeyState != NO_CONTROL_KEY {
+ infos = append(infos, e.ControlKeyState.String())
+ }
+
+ infos = append(infos, fmt.Sprintf("KeyCode: %d", e.VirtualKeyCode))
+ infos = append(infos, fmt.Sprintf("ScanCode: %d", e.VirtualScanCode))
+
+ return fmt.Sprintf("%s[%s]", e.Type(), strings.Join(infos, ", "))
+}
+
+// MenuEventType is the event type for a MenuEventRecord (see
+// https://docs.microsoft.com/en-us/windows/console/input-record-str).
+const MenuEventType EventType = 0x0008
+
+// MenuEventRecord represent the MENU_EVENT_RECORD structure from the Windows
+// console API (see
+// https://docs.microsoft.com/en-us/windows/console/menu-event-record-str).
+// These events are deprecated by the Windows console API and should be ignored.
+type MenuEventRecord struct {
+ CommandID uint32
+}
+
+// Ensure that MenuEventRecord satisfies EventRecord interface.
+var _ EventRecord = MenuEventRecord{}
+
+// Type ensures that MenuEventRecord satisfies EventRecord interface.
+func (e MenuEventRecord) Type() string { return "MenuEvent" }
+
+// String ensures that MenuEventRecord satisfies EventRecord and fmt.Stringer
+// interfaces.
+func (e MenuEventRecord) String() string { return fmt.Sprintf("MenuEvent[%d]", e.CommandID) }
+
+// MouseEventType is the event type for a MouseEventRecord (see
+// https://docs.microsoft.com/en-us/windows/console/input-record-str).
+const MouseEventType EventType = 0x0002
+
+// MouseEventRecord represent the MOUSE_EVENT_RECORD structure from the Windows
+// console API (see
+// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str).
+type MouseEventRecord struct {
+ // MousePosition contains the location of the cursor, in terms of the
+ // console screen buffer's character-cell coordinates.
+ MousePositon Coord
+
+ // ButtonState holds the status of the mouse buttons.
+ ButtonState ButtonState
+
+ // ControlKeyState holds the state of the control keys.
+ ControlKeyState ControlKeyState
+
+ // EventFlags specify tge type of mouse event.
+ EventFlags EventFlags
+
+ // WheelDirection specified the direction in which the mouse wheel is
+ // spinning when EventFlags contains MOUSE_HWHEELED or MOUSE_WHEELED. When
+ // the event flags specify MOUSE_WHEELED it is 1 if the wheel rotated
+ // forward (away from the user) or -1 when it rotates backwards. When
+ // MOUSE_HWHEELED is specified it is 1 when the wheel rotates right and -1
+ // when it rotates left. When the EventFlags do not indicate a mouse wheel
+ // event it is 0.
+ WheelDirection int
+}
+
+// Ensure that MouseEventRecord satisfies EventRecord interface.
+var _ EventRecord = MouseEventRecord{}
+
+func (e MouseEventRecord) WheelDirectionName() string {
+ if e.EventFlags&MOUSE_WHEELED > 0 {
+ if e.WheelDirection > 0 {
+ return "Forward"
+ }
+
+ return "Backward"
+ } else if e.EventFlags&MOUSE_HWHEELED > 0 {
+ if e.WheelDirection > 0 {
+ return "Right"
+ }
+
+ return "Left"
+ }
+
+ return ""
+}
+
+// Type ensures that MouseEventRecord satisfies EventRecord interface.
+func (e MouseEventRecord) Type() string { return "MouseEvent" }
+
+// String ensures that MouseEventRecord satisfies EventRecord and fmt.Stringer
+// interfaces.
+func (e MouseEventRecord) String() string {
+ infos := []string{e.MousePositon.String()}
+
+ if e.ButtonState&0xFF != 0 {
+ infos = append(infos, e.ButtonState.String())
+ }
+
+ eventDescription := e.EventFlags.String()
+
+ wheelDirection := e.WheelDirectionName()
+ if wheelDirection != "" {
+ eventDescription += "(" + wheelDirection + ")"
+ }
+
+ infos = append(infos, eventDescription)
+
+ if e.ControlKeyState != NO_CONTROL_KEY {
+ infos = append(infos, e.ControlKeyState.String())
+ }
+
+ return fmt.Sprintf("%s[%s]", e.Type(), strings.Join(infos, ", "))
+}
+
+// WindowBufferSizeEventType is the event type for a WindowBufferSizeEventRecord
+// (see https://docs.microsoft.com/en-us/windows/console/input-record-str).
+const WindowBufferSizeEventType EventType = 0x0004
+
+// WindowBufferSizeEventRecord represent the WINDOW_BUFFER_SIZE_RECORD structure
+// from the Windows console API (see
+// https://docs.microsoft.com/en-us/windows/console/window-buffer-size-record-str).
+type WindowBufferSizeEventRecord struct {
+ // Size contains the size of the console screen buffer, in character cell columns and rows.
+ Size Coord
+}
+
+// Ensure that WindowBufferSizeEventRecord satisfies EventRecord interface.
+var _ EventRecord = WindowBufferSizeEventRecord{}
+
+// Type ensures that WindowBufferSizeEventRecord satisfies EventRecord interface.
+func (e WindowBufferSizeEventRecord) Type() string { return "WindowBufferSizeEvent" }
+
+// String ensures that WindowBufferSizeEventRecord satisfies EventRecord and fmt.Stringer
+// interfaces.
+func (e WindowBufferSizeEventRecord) String() string {
+ return fmt.Sprintf("WindowBufferSizeEvent[%s]", e.Size)
+}
+
+// UnknownEvent is generated when the event type does not match one of the
+// following types: TypeFocusEventRecord, TypeKeyEventRecord,
+// TypeMouseEventRecord, TypeWindowBufferSizeEvent, TypeMenuEventRecord and
+// UnknownEvent.
+type UnknownEvent struct {
+ InputRecord
+}
+
+// Ensure that UnknownEvent satisfies EventRecord interface.
+var _ EventRecord = UnknownEvent{}
+
+// Type ensures that UnknownEvent satisfies EventRecord interface.
+func (e UnknownEvent) Type() string { return "UnknownEvent" }
+
+// String ensures that UnknownEvent satisfies EventRecord and fmt.Stringer
+// interfaces.
+func (e UnknownEvent) String() string {
+ return fmt.Sprintf("%s[Type: %d, Data: %v]", e.Type(), e.InputRecord.EventType, e.InputRecord.Event[:])
+}
+
+// Coord represent the COORD structure from the Windows
+// console API (see https://docs.microsoft.com/en-us/windows/console/coord-str).
+type Coord struct {
+ // X is the horizontal coordinate or column value. The units depend on the function call.
+ X uint16
+ // Y is the vertical coordinate or row value. The units depend on the function call.
+ Y uint16
+}
+
+// String ensures that Coord satisfies the fmt.Stringer interface.
+func (c Coord) String() string {
+ return fmt.Sprintf("(%d, %d)", c.X, c.Y)
+}
+
+// ButtonState holds the state of the mouse buttons (see
+// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str).
+type ButtonState uint32
+
+func (bs ButtonState) Contains(state ButtonState) bool {
+ return bs&state > 0
+}
+
+// String ensures that ButtonState satisfies the fmt.Stringer interface.
+func (bs ButtonState) String() string {
+ switch {
+ case bs&FROM_LEFT_1ST_BUTTON_PRESSED > 0:
+ return "Left"
+ case bs&FROM_LEFT_2ND_BUTTON_PRESSED > 0:
+ return "2"
+ case bs&FROM_LEFT_3RD_BUTTON_PRESSED > 0:
+ return "3"
+ case bs&FROM_LEFT_4TH_BUTTON_PRESSED > 0:
+ return "4"
+ case bs&RIGHTMOST_BUTTON_PRESSED > 0:
+ return "Right"
+ case bs&0xFF == 0:
+ return "No Button"
+ default:
+ return fmt.Sprintf("Unknown(%d)", bs)
+ }
+}
+
+func (bs ButtonState) IsReleased() bool {
+ return bs&0xff > 0
+}
+
+// Valid values for ButtonState.
+const (
+ FROM_LEFT_1ST_BUTTON_PRESSED ButtonState = 0x0001
+ RIGHTMOST_BUTTON_PRESSED ButtonState = 0x0002
+ FROM_LEFT_2ND_BUTTON_PRESSED ButtonState = 0x0004
+ FROM_LEFT_3RD_BUTTON_PRESSED ButtonState = 0x0008
+ FROM_LEFT_4TH_BUTTON_PRESSED ButtonState = 0x0010
+)
+
+// ControlKeyState holds the state of the control keys for key and mouse events
+// (see https://docs.microsoft.com/en-us/windows/console/key-event-record-str
+// and https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str).
+type ControlKeyState uint32
+
+func (cks ControlKeyState) Contains(state ControlKeyState) bool {
+ return cks&state > 0
+}
+
+// Valid values for ControlKeyState.
+const (
+ CAPSLOCK_ON ControlKeyState = 0x0080
+ ENHANCED_KEY ControlKeyState = 0x0100
+ LEFT_ALT_PRESSED ControlKeyState = 0x0002
+ LEFT_CTRL_PRESSED ControlKeyState = 0x0008
+ NUMLOCK_ON ControlKeyState = 0x0020
+ RIGHT_ALT_PRESSED ControlKeyState = 0x0001
+ RIGHT_CTRL_PRESSED ControlKeyState = 0x0004
+ SCROLLLOCK_ON ControlKeyState = 0x0040
+ SHIFT_PRESSED ControlKeyState = 0x0010
+ NO_CONTROL_KEY ControlKeyState = 0x0000
+)
+
+// String ensures that ControlKeyState satisfies the fmt.Stringer interface.
+func (cks ControlKeyState) String() string {
+ controlKeys := []string{}
+
+ switch {
+ case cks&CAPSLOCK_ON > 0:
+ controlKeys = append(controlKeys, "CapsLock")
+ case cks&ENHANCED_KEY > 0:
+ controlKeys = append(controlKeys, "Enhanced")
+ case cks&LEFT_ALT_PRESSED > 0:
+ controlKeys = append(controlKeys, "Alt")
+ case cks&LEFT_CTRL_PRESSED > 0:
+ controlKeys = append(controlKeys, "CTRL")
+ case cks&NUMLOCK_ON > 0:
+ controlKeys = append(controlKeys, "NumLock")
+ case cks&RIGHT_ALT_PRESSED > 0:
+ controlKeys = append(controlKeys, "RightAlt")
+ case cks&RIGHT_CTRL_PRESSED > 0:
+ controlKeys = append(controlKeys, "RightCTRL")
+ case cks&SCROLLLOCK_ON > 0:
+ controlKeys = append(controlKeys, "ScrollLock")
+ case cks&SHIFT_PRESSED > 0:
+ controlKeys = append(controlKeys, "Shift")
+ case cks == NO_CONTROL_KEY:
+ default:
+ return fmt.Sprintf("Unknown(%d)", cks)
+ }
+
+ return strings.Join(controlKeys, ",")
+}
+
+// EventFlags specifies the type of a mouse event (see
+// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str).
+type EventFlags uint32
+
+// String ensures that EventFlags satisfies the fmt.Stringer interface.
+func (ef EventFlags) String() string {
+ switch {
+ case ef&DOUBLE_CLICK > 0:
+ return "DoubleClick"
+ case ef&MOUSE_WHEELED > 0:
+ return "Wheeled"
+ case ef&MOUSE_MOVED > 0:
+ return "Moved"
+ case ef&MOUSE_HWHEELED > 0:
+ return "HWheeld"
+ case ef == CLICK:
+ return "Click"
+ default:
+ return fmt.Sprintf("Unknown(%d)", ef)
+ }
+}
+
+func (ef EventFlags) Contains(flag EventFlags) bool {
+ return ef&flag > 0
+}
+
+// Valid values for EventFlags.
+const (
+ CLICK EventFlags = 0x0000
+ MOUSE_MOVED EventFlags = 0x0001
+ DOUBLE_CLICK EventFlags = 0x0002
+ MOUSE_WHEELED EventFlags = 0x0004
+ MOUSE_HWHEELED EventFlags = 0x0008
+)
+
+func highWord(data uint32) uint16 {
+ return uint16((data & 0xFFFF0000) >> 16)
+}
diff --git a/vendor/github.com/expr-lang/expr/.gitattributes b/vendor/github.com/expr-lang/expr/.gitattributes
new file mode 100644
index 0000000..efd3030
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/.gitattributes
@@ -0,0 +1 @@
+*\[generated\].go linguist-language=txt
diff --git a/vendor/github.com/expr-lang/expr/.gitignore b/vendor/github.com/expr-lang/expr/.gitignore
new file mode 100644
index 0000000..9d3410b
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/.gitignore
@@ -0,0 +1,11 @@
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+*.test
+*.out
+*.html
+custom_tests.json
+pro/
+test/avs/
diff --git a/vendor/github.com/expr-lang/expr/LICENSE b/vendor/github.com/expr-lang/expr/LICENSE
new file mode 100644
index 0000000..ec46ce3
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 Anton Medvedev
+
+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/vendor/github.com/expr-lang/expr/README.md b/vendor/github.com/expr-lang/expr/README.md
new file mode 100644
index 0000000..c0778a8
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/README.md
@@ -0,0 +1,181 @@
+
Expr
+
+> [!IMPORTANT]
+> The repository [github.com/antonmedv/expr](https://github.com/antonmedv/expr) moved to [github.com/**expr-lang**/expr](https://github.com/expr-lang/expr).
+
+[](https://github.com/expr-lang/expr/actions/workflows/test.yml)
+[](https://goreportcard.com/report/github.com/expr-lang/expr)
+[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:expr)
+[](https://godoc.org/github.com/expr-lang/expr)
+
+**Expr** is a Go-centric expression language designed to deliver dynamic configurations with unparalleled accuracy, safety, and speed.
+**Expr** combines simple [syntax](https://expr-lang.org/docs/language-definition) with powerful features for ease of use:
+
+```js
+// Allow only admins and moderators to moderate comments.
+user.Group in ["admin", "moderator"] || user.Id == comment.UserId
+```
+
+```js
+// Determine whether the request is in the permitted time window.
+request.Time - resource.Age < duration("24h")
+```
+
+```js
+// Ensure all tweets are less than 240 characters.
+all(tweets, len(.Content) <= 240)
+```
+
+## Features
+
+**Expr** is a safe, fast, and intuitive expression evaluator optimized for the Go language.
+Here are its standout features:
+
+### Safety and Isolation
+* **Memory-Safe**: Expr is designed with a focus on safety, ensuring that programs do not access unrelated memory or introduce memory vulnerabilities.
+* **Side-Effect-Free**: Expressions evaluated in Expr only compute outputs from their inputs, ensuring no side-effects that can change state or produce unintended results.
+* **Always Terminating**: Expr is designed to prevent infinite loops, ensuring that every program will conclude in a reasonable amount of time.
+
+### Go Integration
+* **Seamless with Go**: Integrate Expr into your Go projects without the need to redefine types.
+
+### Static Typing
+* Ensures type correctness and prevents runtime type errors.
+ ```go
+ out, err := expr.Compile(`name + age`)
+ // err: invalid operation + (mismatched types string and int)
+ // | name + age
+ // | .....^
+ ```
+
+### User-Friendly
+* Provides user-friendly error messages to assist with debugging and development.
+
+### Flexibility and Utility
+* **Rich Operators**: Offers a reasonable set of basic operators for a variety of applications.
+* **Built-in Functions**: Functions like `all`, `none`, `any`, `one`, `filter`, and `map` are provided out-of-the-box.
+
+### Performance
+* **Optimized for Speed**: Expr stands out in its performance, utilizing an optimizing compiler and a bytecode virtual machine. Check out these [benchmarks](https://github.com/antonmedv/golang-expression-evaluation-comparison#readme) for more details.
+
+## Install
+
+```
+go get github.com/expr-lang/expr
+```
+
+## Documentation
+
+* See [Getting Started](https://expr-lang.org/docs/Getting-Started) page for developer documentation.
+* See [Language Definition](https://expr-lang.org/docs/language-definition) page to learn the syntax.
+
+## Examples
+
+[Play Online](https://go.dev/play/p/XCoNXEjm3TS)
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/expr-lang/expr"
+)
+
+func main() {
+ env := map[string]interface{}{
+ "greet": "Hello, %v!",
+ "names": []string{"world", "you"},
+ "sprintf": fmt.Sprintf,
+ }
+
+ code := `sprintf(greet, names[0])`
+
+ program, err := expr.Compile(code, expr.Env(env))
+ if err != nil {
+ panic(err)
+ }
+
+ output, err := expr.Run(program, env)
+ if err != nil {
+ panic(err)
+ }
+
+ fmt.Println(output)
+}
+```
+
+[Play Online](https://go.dev/play/p/tz-ZneBfSuw)
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/expr-lang/expr"
+)
+
+type Tweet struct {
+ Len int
+}
+
+type Env struct {
+ Tweets []Tweet
+}
+
+func main() {
+ code := `all(Tweets, {.Len <= 240})`
+
+ program, err := expr.Compile(code, expr.Env(Env{}))
+ if err != nil {
+ panic(err)
+ }
+
+ env := Env{
+ Tweets: []Tweet{{42}, {98}, {69}},
+ }
+ output, err := expr.Run(program, env)
+ if err != nil {
+ panic(err)
+ }
+
+ fmt.Println(output)
+}
+```
+
+## Who uses Expr?
+
+* [Google](https://google.com) uses Expr as one of its expression languages on the [Google Cloud Platform](https://cloud.google.com).
+* [Uber](https://uber.com) uses Expr to allow customization of its Uber Eats marketplace.
+* [GoDaddy](https://godaddy.com) employs Expr for the customization of its GoDaddy Pro product.
+* [ByteDance](https://bytedance.com) incorporates Expr into its internal business rule engine.
+* [Aviasales](https://aviasales.ru) utilizes Expr as a business rule engine for its flight search engine.
+* [Wish.com](https://www.wish.com) employs Expr in its decision-making rule engine for the Wish Assistant.
+* [Argo](https://argoproj.github.io) integrates Expr into Argo Rollouts and Argo Workflows for Kubernetes.
+* [OpenTelemetry](https://opentelemetry.io) integrates Expr into the OpenTelemetry Collector.
+* [Philips Labs](https://github.com/philips-labs/tabia) employs Expr in Tabia, a tool designed to collect insights on their code bases.
+* [CrowdSec](https://crowdsec.net) incorporates Expr into its security automation tool.
+* [CoreDNS](https://coredns.io) uses Expr in CoreDNS, which is a DNS server.
+* [qiniu](https://www.qiniu.com) implements Expr in its trade systems.
+* [Junglee Games](https://www.jungleegames.com/) uses Expr for its in-house marketing retention tool, Project Audience.
+* [Faceit](https://www.faceit.com) uses Expr to enhance customization of its eSports matchmaking algorithm.
+* [Chaos Mesh](https://chaos-mesh.org) incorporates Expr into Chaos Mesh, a cloud-native Chaos Engineering platform.
+* [Visually.io](https://visually.io) employs Expr as a business rule engine for its personalization targeting algorithm.
+* [Akvorado](https://github.com/akvorado/akvorado) utilizes Expr to classify exporters and interfaces in network flows.
+* [keda.sh](https://keda.sh) uses Expr to allow customization of its Kubernetes-based event-driven autoscaling.
+* [Span Digital](https://spandigital.com/) uses Expr in its Knowledge Management products.
+* [Xiaohongshu](https://www.xiaohongshu.com/) combining yaml with Expr for dynamically policies delivery.
+* [Melrōse](https://melrōse.org) uses Expr to implement its music programming language.
+* [Tork](https://www.tork.run/) integrates Expr into its workflow execution.
+* [Critical Moments](https://criticalmoments.io) uses Expr for its mobile realtime conditional targeting system.
+* [WoodpeckerCI](https://woodpecker-ci.org) uses Expr for [filtering workflows/steps](https://woodpecker-ci.org/docs/usage/workflow-syntax#evaluate).
+* [FastSchema](https://github.com/fastschema/fastschema) - A BaaS leveraging Expr for its customizable and dynamic Access Control system.
+* [WunderGraph Cosmo](https://github.com/wundergraph/cosmo) - GraphQL Federeration Router uses Expr to customize Middleware behaviour
+* [SOLO](https://solo.one) uses Expr interally to allow dynamic code execution with custom defined functions.
+
+[Add your company too](https://github.com/expr-lang/expr/edit/master/README.md)
+
+## License
+
+[MIT](https://github.com/expr-lang/expr/blob/master/LICENSE)
+
+
diff --git a/vendor/github.com/expr-lang/expr/SECURITY.md b/vendor/github.com/expr-lang/expr/SECURITY.md
new file mode 100644
index 0000000..8d692a3
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/SECURITY.md
@@ -0,0 +1,25 @@
+# Security Policy
+
+## Supported Versions
+
+Expr is generally backwards compatible with very few exceptions, so we
+recommend users to always use the latest version to experience stability,
+performance and security.
+
+We generally backport security issues to a single previous minor version,
+unless this is not possible or feasible with a reasonable effort.
+
+| Version | Supported |
+|---------|--------------------|
+| 1.16 | :white_check_mark: |
+| 1.15 | :white_check_mark: |
+| 1.14 | :white_check_mark: |
+| 1.13 | :white_check_mark: |
+| < 1.13 | :x: |
+
+## Reporting a Vulnerability
+
+If you believe you've discovered a serious vulnerability, please contact the
+Expr core team at anton+security@medv.io. We will evaluate your report and if
+necessary issue a fix and an advisory. If the issue was previously undisclosed,
+we'll also mention your name in the credits.
diff --git a/vendor/github.com/expr-lang/expr/ast/dump.go b/vendor/github.com/expr-lang/expr/ast/dump.go
new file mode 100644
index 0000000..56bc7db
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/ast/dump.go
@@ -0,0 +1,59 @@
+package ast
+
+import (
+ "fmt"
+ "reflect"
+ "regexp"
+)
+
+func Dump(node Node) string {
+ return dump(reflect.ValueOf(node), "")
+}
+
+func dump(v reflect.Value, ident string) string {
+ if !v.IsValid() {
+ return "nil"
+ }
+ t := v.Type()
+ switch t.Kind() {
+ case reflect.Struct:
+ out := t.Name() + "{\n"
+ for i := 0; i < t.NumField(); i++ {
+ f := t.Field(i)
+ if isPrivate(f.Name) {
+ continue
+ }
+ s := v.Field(i)
+ out += fmt.Sprintf("%v%v: %v,\n", ident+"\t", f.Name, dump(s, ident+"\t"))
+ }
+ return out + ident + "}"
+ case reflect.Slice:
+ if v.Len() == 0 {
+ return t.String() + "{}"
+ }
+ out := t.String() + "{\n"
+ for i := 0; i < v.Len(); i++ {
+ s := v.Index(i)
+ out += fmt.Sprintf("%v%v,", ident+"\t", dump(s, ident+"\t"))
+ if i+1 < v.Len() {
+ out += "\n"
+ }
+ }
+ return out + "\n" + ident + "}"
+ case reflect.Ptr:
+ return dump(v.Elem(), ident)
+ case reflect.Interface:
+ return dump(reflect.ValueOf(v.Interface()), ident)
+
+ case reflect.String:
+ return fmt.Sprintf("%q", v)
+ default:
+ return fmt.Sprintf("%v", v)
+ }
+}
+
+var isCapital = regexp.MustCompile("^[A-Z]")
+
+func isPrivate(s string) bool {
+ return !isCapital.Match([]byte(s))
+}
diff --git a/vendor/github.com/expr-lang/expr/ast/find.go b/vendor/github.com/expr-lang/expr/ast/find.go
new file mode 100644
index 0000000..247ff6c
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/ast/find.go
@@ -0,0 +1,18 @@
+package ast
+
+func Find(node Node, fn func(node Node) bool) Node {
+ v := &finder{fn: fn}
+ Walk(&node, v)
+ return v.node
+}
+
+type finder struct {
+ node Node
+ fn func(node Node) bool
+}
+
+func (f *finder) Visit(node *Node) {
+ if f.fn(*node) {
+ f.node = *node
+ }
+}
diff --git a/vendor/github.com/expr-lang/expr/ast/node.go b/vendor/github.com/expr-lang/expr/ast/node.go
new file mode 100644
index 0000000..02923ac
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/ast/node.go
@@ -0,0 +1,243 @@
+package ast
+
+import (
+ "reflect"
+
+ "github.com/expr-lang/expr/checker/nature"
+ "github.com/expr-lang/expr/file"
+)
+
+var (
+ anyType = reflect.TypeOf(new(any)).Elem()
+)
+
+// Node represents items of abstract syntax tree.
+type Node interface {
+ Location() file.Location
+ SetLocation(file.Location)
+ Nature() nature.Nature
+ SetNature(nature.Nature)
+ Type() reflect.Type
+ SetType(reflect.Type)
+ String() string
+}
+
+// Patch replaces the node with a new one.
+// Location information is preserved.
+// Type information is lost.
+func Patch(node *Node, newNode Node) {
+ newNode.SetLocation((*node).Location())
+ *node = newNode
+}
+
+// base is a base struct for all nodes.
+type base struct {
+ loc file.Location
+ nature nature.Nature
+}
+
+// Location returns the location of the node in the source code.
+func (n *base) Location() file.Location {
+ return n.loc
+}
+
+// SetLocation sets the location of the node in the source code.
+func (n *base) SetLocation(loc file.Location) {
+ n.loc = loc
+}
+
+// Nature returns the nature of the node.
+func (n *base) Nature() nature.Nature {
+ return n.nature
+}
+
+// SetNature sets the nature of the node.
+func (n *base) SetNature(nature nature.Nature) {
+ n.nature = nature
+}
+
+// Type returns the type of the node.
+func (n *base) Type() reflect.Type {
+ if n.nature.Type == nil {
+ return anyType
+ }
+ return n.nature.Type
+}
+
+// SetType sets the type of the node.
+func (n *base) SetType(t reflect.Type) {
+ n.nature.Type = t
+}
+
+// NilNode represents nil.
+type NilNode struct {
+ base
+}
+
+// IdentifierNode represents an identifier.
+type IdentifierNode struct {
+ base
+ Value string // Name of the identifier. Like "foo" in "foo.bar".
+}
+
+// IntegerNode represents an integer.
+type IntegerNode struct {
+ base
+ Value int // Value of the integer.
+}
+
+// FloatNode represents a float.
+type FloatNode struct {
+ base
+ Value float64 // Value of the float.
+}
+
+// BoolNode represents a boolean.
+type BoolNode struct {
+ base
+ Value bool // Value of the boolean.
+}
+
+// StringNode represents a string.
+type StringNode struct {
+ base
+ Value string // Value of the string.
+}
+
+// ConstantNode represents a constant.
+// Constants are predefined values like nil, true, false, array, map, etc.
+// The parser.Parse will never generate ConstantNode, it is only generated
+// by the optimizer.
+type ConstantNode struct {
+ base
+ Value any // Value of the constant.
+}
+
+// UnaryNode represents a unary operator.
+type UnaryNode struct {
+ base
+ Operator string // Operator of the unary operator. Like "!" in "!foo" or "not" in "not foo".
+ Node Node // Node of the unary operator. Like "foo" in "!foo".
+}
+
+// BinaryNode represents a binary operator.
+type BinaryNode struct {
+ base
+ Operator string // Operator of the binary operator. Like "+" in "foo + bar" or "matches" in "foo matches bar".
+ Left Node // Left node of the binary operator.
+ Right Node // Right node of the binary operator.
+}
+
+// ChainNode represents an optional chaining group.
+// A few MemberNode nodes can be chained together,
+// and will be wrapped in a ChainNode. Example:
+//
+// foo.bar?.baz?.qux
+//
+// The whole chain will be wrapped in a ChainNode.
+type ChainNode struct {
+ base
+ Node Node // Node of the chain.
+}
+
+// MemberNode represents a member access.
+// It can be a field access, a method call,
+// or an array element access.
+// Example:
+//
+// foo.bar or foo["bar"]
+// foo.bar()
+// array[0]
+type MemberNode struct {
+ base
+ Node Node // Node of the member access. Like "foo" in "foo.bar".
+ Property Node // Property of the member access. For property access it is a StringNode.
+ Optional bool // If true then the member access is optional. Like "foo?.bar".
+ Method bool
+}
+
+// SliceNode represents access to a slice of an array.
+// Example:
+//
+// array[1:4]
+type SliceNode struct {
+ base
+ Node Node // Node of the slice. Like "array" in "array[1:4]".
+ From Node // From an index of the array. Like "1" in "array[1:4]".
+ To Node // To an index of the array. Like "4" in "array[1:4]".
+}
+
+// CallNode represents a function or a method call.
+type CallNode struct {
+ base
+ Callee Node // Node of the call. Like "foo" in "foo()".
+ Arguments []Node // Arguments of the call.
+}
+
+// BuiltinNode represents a builtin function call.
+type BuiltinNode struct {
+ base
+ Name string // Name of the builtin function. Like "len" in "len(foo)".
+ Arguments []Node // Arguments of the builtin function.
+ Throws bool // If true then accessing a field or array index can throw an error. Used by optimizer.
+ Map Node // Used by optimizer to fold filter() and map() builtins.
+}
+
+// PredicateNode represents a predicate.
+// Example:
+//
+// filter(foo, .bar == 1)
+//
+// The predicate is ".bar == 1".
+type PredicateNode struct {
+ base
+ Node Node // Node of the predicate body.
+}
+
+// PointerNode represents a pointer to a current value in predicate.
+type PointerNode struct {
+ base
+ Name string // Name of the pointer. Like "index" in "#index".
+}
+
+// ConditionalNode represents a ternary operator.
+type ConditionalNode struct {
+ base
+ Cond Node // Condition of the ternary operator. Like "foo" in "foo ? bar : baz".
+ Exp1 Node // Expression 1 of the ternary operator. Like "bar" in "foo ? bar : baz".
+ Exp2 Node // Expression 2 of the ternary operator. Like "baz" in "foo ? bar : baz".
+}
+
+// VariableDeclaratorNode represents a variable declaration.
+type VariableDeclaratorNode struct {
+ base
+ Name string // Name of the variable. Like "foo" in "let foo = 1; foo + 1".
+ Value Node // Value of the variable. Like "1" in "let foo = 1; foo + 1".
+ Expr Node // Expression of the variable. Like "foo + 1" in "let foo = 1; foo + 1".
+}
+
+// SequenceNode represents a sequence of nodes separated by semicolons.
+// All nodes are executed, only the last node will be returned.
+type SequenceNode struct {
+ base
+ Nodes []Node
+}
+
+// ArrayNode represents an array.
+type ArrayNode struct {
+ base
+ Nodes []Node // Nodes of the array.
+}
+
+// MapNode represents a map.
+type MapNode struct {
+ base
+ Pairs []Node // PairNode nodes.
+}
+
+// PairNode represents a key-value pair of a map.
+type PairNode struct {
+ base
+ Key Node // Key of the pair.
+ Value Node // Value of the pair.
+}
diff --git a/vendor/github.com/expr-lang/expr/ast/print.go b/vendor/github.com/expr-lang/expr/ast/print.go
new file mode 100644
index 0000000..e4e45f0
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/ast/print.go
@@ -0,0 +1,253 @@
+package ast
+
+import (
+ "encoding/json"
+ "fmt"
+ "strings"
+
+ "github.com/expr-lang/expr/parser/operator"
+ "github.com/expr-lang/expr/parser/utils"
+)
+
+func (n *NilNode) String() string {
+ return "nil"
+}
+
+func (n *IdentifierNode) String() string {
+ return n.Value
+}
+
+func (n *IntegerNode) String() string {
+ return fmt.Sprintf("%d", n.Value)
+}
+
+func (n *FloatNode) String() string {
+ return fmt.Sprintf("%v", n.Value)
+}
+
+func (n *BoolNode) String() string {
+ return fmt.Sprintf("%t", n.Value)
+}
+
+func (n *StringNode) String() string {
+ return fmt.Sprintf("%q", n.Value)
+}
+
+func (n *ConstantNode) String() string {
+ if n.Value == nil {
+ return "nil"
+ }
+ b, err := json.Marshal(n.Value)
+ if err != nil {
+ panic(err)
+ }
+ return string(b)
+}
+
+func (n *UnaryNode) String() string {
+ op := n.Operator
+ if n.Operator == "not" {
+ op = fmt.Sprintf("%s ", n.Operator)
+ }
+ wrap := false
+ switch b := n.Node.(type) {
+ case *BinaryNode:
+ if operator.Binary[b.Operator].Precedence <
+ operator.Unary[n.Operator].Precedence {
+ wrap = true
+ }
+ case *ConditionalNode:
+ wrap = true
+ }
+ if wrap {
+ return fmt.Sprintf("%s(%s)", op, n.Node.String())
+ }
+ return fmt.Sprintf("%s%s", op, n.Node.String())
+}
+
+func (n *BinaryNode) String() string {
+ if n.Operator == ".." {
+ return fmt.Sprintf("%s..%s", n.Left, n.Right)
+ }
+
+ var lhs, rhs string
+ var lwrap, rwrap bool
+
+ if l, ok := n.Left.(*UnaryNode); ok {
+ if operator.Unary[l.Operator].Precedence <
+ operator.Binary[n.Operator].Precedence {
+ lwrap = true
+ }
+ }
+ if lb, ok := n.Left.(*BinaryNode); ok {
+ if operator.Less(lb.Operator, n.Operator) {
+ lwrap = true
+ }
+ if operator.Binary[lb.Operator].Precedence ==
+ operator.Binary[n.Operator].Precedence &&
+ operator.Binary[n.Operator].Associativity == operator.Right {
+ lwrap = true
+ }
+ if lb.Operator == "??" {
+ lwrap = true
+ }
+ if operator.IsBoolean(lb.Operator) && n.Operator != lb.Operator {
+ lwrap = true
+ }
+ }
+ if rb, ok := n.Right.(*BinaryNode); ok {
+ if operator.Less(rb.Operator, n.Operator) {
+ rwrap = true
+ }
+ if operator.Binary[rb.Operator].Precedence ==
+ operator.Binary[n.Operator].Precedence &&
+ operator.Binary[n.Operator].Associativity == operator.Left {
+ rwrap = true
+ }
+ if operator.IsBoolean(rb.Operator) && n.Operator != rb.Operator {
+ rwrap = true
+ }
+ }
+
+ if _, ok := n.Left.(*ConditionalNode); ok {
+ lwrap = true
+ }
+ if _, ok := n.Right.(*ConditionalNode); ok {
+ rwrap = true
+ }
+
+ if lwrap {
+ lhs = fmt.Sprintf("(%s)", n.Left.String())
+ } else {
+ lhs = n.Left.String()
+ }
+
+ if rwrap {
+ rhs = fmt.Sprintf("(%s)", n.Right.String())
+ } else {
+ rhs = n.Right.String()
+ }
+
+ return fmt.Sprintf("%s %s %s", lhs, n.Operator, rhs)
+}
+
+func (n *ChainNode) String() string {
+ return n.Node.String()
+}
+
+func (n *MemberNode) String() string {
+ node := n.Node.String()
+ if _, ok := n.Node.(*BinaryNode); ok {
+ node = fmt.Sprintf("(%s)", node)
+ }
+
+ if n.Optional {
+ if str, ok := n.Property.(*StringNode); ok && utils.IsValidIdentifier(str.Value) {
+ return fmt.Sprintf("%s?.%s", node, str.Value)
+ } else {
+ return fmt.Sprintf("%s?.[%s]", node, n.Property.String())
+ }
+ }
+ if str, ok := n.Property.(*StringNode); ok && utils.IsValidIdentifier(str.Value) {
+ if _, ok := n.Node.(*PointerNode); ok {
+ return fmt.Sprintf(".%s", str.Value)
+ }
+ return fmt.Sprintf("%s.%s", node, str.Value)
+ }
+ return fmt.Sprintf("%s[%s]", node, n.Property.String())
+}
+
+func (n *SliceNode) String() string {
+ if n.From == nil && n.To == nil {
+ return fmt.Sprintf("%s[:]", n.Node.String())
+ }
+ if n.From == nil {
+ return fmt.Sprintf("%s[:%s]", n.Node.String(), n.To.String())
+ }
+ if n.To == nil {
+ return fmt.Sprintf("%s[%s:]", n.Node.String(), n.From.String())
+ }
+ return fmt.Sprintf("%s[%s:%s]", n.Node.String(), n.From.String(), n.To.String())
+}
+
+func (n *CallNode) String() string {
+ arguments := make([]string, len(n.Arguments))
+ for i, arg := range n.Arguments {
+ arguments[i] = arg.String()
+ }
+ return fmt.Sprintf("%s(%s)", n.Callee.String(), strings.Join(arguments, ", "))
+}
+
+func (n *BuiltinNode) String() string {
+ arguments := make([]string, len(n.Arguments))
+ for i, arg := range n.Arguments {
+ arguments[i] = arg.String()
+ }
+ return fmt.Sprintf("%s(%s)", n.Name, strings.Join(arguments, ", "))
+}
+
+func (n *PredicateNode) String() string {
+ return n.Node.String()
+}
+
+func (n *PointerNode) String() string {
+ return fmt.Sprintf("#%s", n.Name)
+}
+
+func (n *VariableDeclaratorNode) String() string {
+ return fmt.Sprintf("let %s = %s; %s", n.Name, n.Value.String(), n.Expr.String())
+}
+
+func (n *SequenceNode) String() string {
+ nodes := make([]string, len(n.Nodes))
+ for i, node := range n.Nodes {
+ nodes[i] = node.String()
+ }
+ return strings.Join(nodes, "; ")
+}
+
+func (n *ConditionalNode) String() string {
+ var cond, exp1, exp2 string
+ if _, ok := n.Cond.(*ConditionalNode); ok {
+ cond = fmt.Sprintf("(%s)", n.Cond.String())
+ } else {
+ cond = n.Cond.String()
+ }
+ if _, ok := n.Exp1.(*ConditionalNode); ok {
+ exp1 = fmt.Sprintf("(%s)", n.Exp1.String())
+ } else {
+ exp1 = n.Exp1.String()
+ }
+ if _, ok := n.Exp2.(*ConditionalNode); ok {
+ exp2 = fmt.Sprintf("(%s)", n.Exp2.String())
+ } else {
+ exp2 = n.Exp2.String()
+ }
+ return fmt.Sprintf("%s ? %s : %s", cond, exp1, exp2)
+}
+
+func (n *ArrayNode) String() string {
+ nodes := make([]string, len(n.Nodes))
+ for i, node := range n.Nodes {
+ nodes[i] = node.String()
+ }
+ return fmt.Sprintf("[%s]", strings.Join(nodes, ", "))
+}
+
+func (n *MapNode) String() string {
+ pairs := make([]string, len(n.Pairs))
+ for i, pair := range n.Pairs {
+ pairs[i] = pair.String()
+ }
+ return fmt.Sprintf("{%s}", strings.Join(pairs, ", "))
+}
+
+func (n *PairNode) String() string {
+ if str, ok := n.Key.(*StringNode); ok {
+ if utils.IsValidIdentifier(str.Value) {
+ return fmt.Sprintf("%s: %s", str.Value, n.Value.String())
+ }
+ return fmt.Sprintf("%s: %s", str.String(), n.Value.String())
+ }
+ return fmt.Sprintf("(%s): %s", n.Key.String(), n.Value.String())
+}
diff --git a/vendor/github.com/expr-lang/expr/ast/visitor.go b/vendor/github.com/expr-lang/expr/ast/visitor.go
new file mode 100644
index 0000000..72cd636
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/ast/visitor.go
@@ -0,0 +1,78 @@
+package ast
+
+import "fmt"
+
+type Visitor interface {
+ Visit(node *Node)
+}
+
+func Walk(node *Node, v Visitor) {
+ if *node == nil {
+ return
+ }
+ switch n := (*node).(type) {
+ case *NilNode:
+ case *IdentifierNode:
+ case *IntegerNode:
+ case *FloatNode:
+ case *BoolNode:
+ case *StringNode:
+ case *ConstantNode:
+ case *UnaryNode:
+ Walk(&n.Node, v)
+ case *BinaryNode:
+ Walk(&n.Left, v)
+ Walk(&n.Right, v)
+ case *ChainNode:
+ Walk(&n.Node, v)
+ case *MemberNode:
+ Walk(&n.Node, v)
+ Walk(&n.Property, v)
+ case *SliceNode:
+ Walk(&n.Node, v)
+ if n.From != nil {
+ Walk(&n.From, v)
+ }
+ if n.To != nil {
+ Walk(&n.To, v)
+ }
+ case *CallNode:
+ Walk(&n.Callee, v)
+ for i := range n.Arguments {
+ Walk(&n.Arguments[i], v)
+ }
+ case *BuiltinNode:
+ for i := range n.Arguments {
+ Walk(&n.Arguments[i], v)
+ }
+ case *PredicateNode:
+ Walk(&n.Node, v)
+ case *PointerNode:
+ case *VariableDeclaratorNode:
+ Walk(&n.Value, v)
+ Walk(&n.Expr, v)
+ case *SequenceNode:
+ for i := range n.Nodes {
+ Walk(&n.Nodes[i], v)
+ }
+ case *ConditionalNode:
+ Walk(&n.Cond, v)
+ Walk(&n.Exp1, v)
+ Walk(&n.Exp2, v)
+ case *ArrayNode:
+ for i := range n.Nodes {
+ Walk(&n.Nodes[i], v)
+ }
+ case *MapNode:
+ for i := range n.Pairs {
+ Walk(&n.Pairs[i], v)
+ }
+ case *PairNode:
+ Walk(&n.Key, v)
+ Walk(&n.Value, v)
+ default:
+ panic(fmt.Sprintf("undefined node type (%T)", node))
+ }
+
+ v.Visit(node)
+}
diff --git a/vendor/github.com/expr-lang/expr/builtin/builtin.go b/vendor/github.com/expr-lang/expr/builtin/builtin.go
new file mode 100644
index 0000000..c23daf4
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/builtin/builtin.go
@@ -0,0 +1,1069 @@
+package builtin
+
+import (
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+ "reflect"
+ "sort"
+ "strings"
+ "time"
+
+ "github.com/expr-lang/expr/internal/deref"
+ "github.com/expr-lang/expr/vm/runtime"
+)
+
+var (
+ Index map[string]int
+ Names []string
+)
+
+func init() {
+ Index = make(map[string]int)
+ Names = make([]string, len(Builtins))
+ for i, fn := range Builtins {
+ Index[fn.Name] = i
+ Names[i] = fn.Name
+ }
+}
+
+var Builtins = []*Function{
+ {
+ Name: "all",
+ Predicate: true,
+ Types: types(new(func([]any, func(any) bool) bool)),
+ },
+ {
+ Name: "none",
+ Predicate: true,
+ Types: types(new(func([]any, func(any) bool) bool)),
+ },
+ {
+ Name: "any",
+ Predicate: true,
+ Types: types(new(func([]any, func(any) bool) bool)),
+ },
+ {
+ Name: "one",
+ Predicate: true,
+ Types: types(new(func([]any, func(any) bool) bool)),
+ },
+ {
+ Name: "filter",
+ Predicate: true,
+ Types: types(new(func([]any, func(any) bool) []any)),
+ },
+ {
+ Name: "map",
+ Predicate: true,
+ Types: types(new(func([]any, func(any) any) []any)),
+ },
+ {
+ Name: "find",
+ Predicate: true,
+ Types: types(new(func([]any, func(any) bool) any)),
+ },
+ {
+ Name: "findIndex",
+ Predicate: true,
+ Types: types(new(func([]any, func(any) bool) int)),
+ },
+ {
+ Name: "findLast",
+ Predicate: true,
+ Types: types(new(func([]any, func(any) bool) any)),
+ },
+ {
+ Name: "findLastIndex",
+ Predicate: true,
+ Types: types(new(func([]any, func(any) bool) int)),
+ },
+ {
+ Name: "count",
+ Predicate: true,
+ Types: types(new(func([]any, func(any) bool) int)),
+ },
+ {
+ Name: "sum",
+ Predicate: true,
+ Types: types(new(func([]any, func(any) bool) int)),
+ },
+ {
+ Name: "groupBy",
+ Predicate: true,
+ Types: types(new(func([]any, func(any) any) map[any][]any)),
+ },
+ {
+ Name: "sortBy",
+ Predicate: true,
+ Types: types(new(func([]any, func(any) bool, string) []any)),
+ },
+ {
+ Name: "reduce",
+ Predicate: true,
+ Types: types(new(func([]any, func(any, any) any, any) any)),
+ },
+ {
+ Name: "len",
+ Fast: Len,
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ if len(args) != 1 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+ switch kind(args[0]) {
+ case reflect.Array, reflect.Map, reflect.Slice, reflect.String, reflect.Interface:
+ return integerType, nil
+ }
+ return anyType, fmt.Errorf("invalid argument for len (type %s)", args[0])
+ },
+ },
+ {
+ Name: "type",
+ Fast: Type,
+ Types: types(new(func(any) string)),
+ },
+ {
+ Name: "abs",
+ Fast: Abs,
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ if len(args) != 1 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+ switch kind(args[0]) {
+ case reflect.Float32, reflect.Float64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Interface:
+ return args[0], nil
+ }
+ return anyType, fmt.Errorf("invalid argument for abs (type %s)", args[0])
+ },
+ },
+ {
+ Name: "ceil",
+ Fast: Ceil,
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ return validateRoundFunc("ceil", args)
+ },
+ },
+ {
+ Name: "floor",
+ Fast: Floor,
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ return validateRoundFunc("floor", args)
+ },
+ },
+ {
+ Name: "round",
+ Fast: Round,
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ return validateRoundFunc("round", args)
+ },
+ },
+ {
+ Name: "int",
+ Fast: Int,
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ if len(args) != 1 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+ switch kind(args[0]) {
+ case reflect.Interface:
+ return integerType, nil
+ case reflect.Float32, reflect.Float64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return integerType, nil
+ case reflect.String:
+ return integerType, nil
+ }
+ return anyType, fmt.Errorf("invalid argument for int (type %s)", args[0])
+ },
+ },
+ {
+ Name: "float",
+ Fast: Float,
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ if len(args) != 1 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+ switch kind(args[0]) {
+ case reflect.Interface:
+ return floatType, nil
+ case reflect.Float32, reflect.Float64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return floatType, nil
+ case reflect.String:
+ return floatType, nil
+ }
+ return anyType, fmt.Errorf("invalid argument for float (type %s)", args[0])
+ },
+ },
+ {
+ Name: "string",
+ Fast: String,
+ Types: types(new(func(any any) string)),
+ },
+ {
+ Name: "trim",
+ Func: func(args ...any) (any, error) {
+ if len(args) == 1 {
+ return strings.TrimSpace(args[0].(string)), nil
+ } else if len(args) == 2 {
+ return strings.Trim(args[0].(string), args[1].(string)), nil
+ } else {
+ return nil, fmt.Errorf("invalid number of arguments for trim (expected 1 or 2, got %d)", len(args))
+ }
+ },
+ Types: types(
+ strings.TrimSpace,
+ strings.Trim,
+ ),
+ },
+ {
+ Name: "trimPrefix",
+ Func: func(args ...any) (any, error) {
+ s := " "
+ if len(args) == 2 {
+ s = args[1].(string)
+ }
+ return strings.TrimPrefix(args[0].(string), s), nil
+ },
+ Types: types(
+ strings.TrimPrefix,
+ new(func(string) string),
+ ),
+ },
+ {
+ Name: "trimSuffix",
+ Func: func(args ...any) (any, error) {
+ s := " "
+ if len(args) == 2 {
+ s = args[1].(string)
+ }
+ return strings.TrimSuffix(args[0].(string), s), nil
+ },
+ Types: types(
+ strings.TrimSuffix,
+ new(func(string) string),
+ ),
+ },
+ {
+ Name: "upper",
+ Fast: func(arg any) any {
+ return strings.ToUpper(arg.(string))
+ },
+ Types: types(strings.ToUpper),
+ },
+ {
+ Name: "lower",
+ Fast: func(arg any) any {
+ return strings.ToLower(arg.(string))
+ },
+ Types: types(strings.ToLower),
+ },
+ {
+ Name: "split",
+ Func: func(args ...any) (any, error) {
+ if len(args) == 2 {
+ return strings.Split(args[0].(string), args[1].(string)), nil
+ } else if len(args) == 3 {
+ return strings.SplitN(args[0].(string), args[1].(string), runtime.ToInt(args[2])), nil
+ } else {
+ return nil, fmt.Errorf("invalid number of arguments for split (expected 2 or 3, got %d)", len(args))
+ }
+ },
+ Types: types(
+ strings.Split,
+ strings.SplitN,
+ ),
+ },
+ {
+ Name: "splitAfter",
+ Func: func(args ...any) (any, error) {
+ if len(args) == 2 {
+ return strings.SplitAfter(args[0].(string), args[1].(string)), nil
+ } else if len(args) == 3 {
+ return strings.SplitAfterN(args[0].(string), args[1].(string), runtime.ToInt(args[2])), nil
+ } else {
+ return nil, fmt.Errorf("invalid number of arguments for splitAfter (expected 2 or 3, got %d)", len(args))
+ }
+ },
+ Types: types(
+ strings.SplitAfter,
+ strings.SplitAfterN,
+ ),
+ },
+ {
+ Name: "replace",
+ Func: func(args ...any) (any, error) {
+ if len(args) == 4 {
+ return strings.Replace(args[0].(string), args[1].(string), args[2].(string), runtime.ToInt(args[3])), nil
+ } else if len(args) == 3 {
+ return strings.ReplaceAll(args[0].(string), args[1].(string), args[2].(string)), nil
+ } else {
+ return nil, fmt.Errorf("invalid number of arguments for replace (expected 3 or 4, got %d)", len(args))
+ }
+ },
+ Types: types(
+ strings.Replace,
+ strings.ReplaceAll,
+ ),
+ },
+ {
+ Name: "repeat",
+ Safe: func(args ...any) (any, uint, error) {
+ s := args[0].(string)
+ n := runtime.ToInt(args[1])
+ if n < 0 {
+ return nil, 0, fmt.Errorf("invalid argument for repeat (expected positive integer, got %d)", n)
+ }
+ if n > 1e6 {
+ return nil, 0, fmt.Errorf("memory budget exceeded")
+ }
+ return strings.Repeat(s, n), uint(len(s) * n), nil
+ },
+ Types: types(strings.Repeat),
+ },
+ {
+ Name: "join",
+ Func: func(args ...any) (any, error) {
+ glue := ""
+ if len(args) == 2 {
+ glue = args[1].(string)
+ }
+ switch args[0].(type) {
+ case []string:
+ return strings.Join(args[0].([]string), glue), nil
+ case []any:
+ var s []string
+ for _, arg := range args[0].([]any) {
+ s = append(s, arg.(string))
+ }
+ return strings.Join(s, glue), nil
+ }
+ return nil, fmt.Errorf("invalid argument for join (type %s)", reflect.TypeOf(args[0]))
+ },
+ Types: types(
+ strings.Join,
+ new(func([]any, string) string),
+ new(func([]any) string),
+ new(func([]string, string) string),
+ new(func([]string) string),
+ ),
+ },
+ {
+ Name: "indexOf",
+ Func: func(args ...any) (any, error) {
+ return strings.Index(args[0].(string), args[1].(string)), nil
+ },
+ Types: types(strings.Index),
+ },
+ {
+ Name: "lastIndexOf",
+ Func: func(args ...any) (any, error) {
+ return strings.LastIndex(args[0].(string), args[1].(string)), nil
+ },
+ Types: types(strings.LastIndex),
+ },
+ {
+ Name: "hasPrefix",
+ Func: func(args ...any) (any, error) {
+ return strings.HasPrefix(args[0].(string), args[1].(string)), nil
+ },
+ Types: types(strings.HasPrefix),
+ },
+ {
+ Name: "hasSuffix",
+ Func: func(args ...any) (any, error) {
+ return strings.HasSuffix(args[0].(string), args[1].(string)), nil
+ },
+ Types: types(strings.HasSuffix),
+ },
+ {
+ Name: "max",
+ Func: func(args ...any) (any, error) {
+ return minMax("max", runtime.Less, args...)
+ },
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ return validateAggregateFunc("max", args)
+ },
+ },
+ {
+ Name: "min",
+ Func: func(args ...any) (any, error) {
+ return minMax("min", runtime.More, args...)
+ },
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ return validateAggregateFunc("min", args)
+ },
+ },
+ {
+ Name: "mean",
+ Func: func(args ...any) (any, error) {
+ count, sum, err := mean(args...)
+ if err != nil {
+ return nil, err
+ }
+ if count == 0 {
+ return 0.0, nil
+ }
+ return sum / float64(count), nil
+ },
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ return validateAggregateFunc("mean", args)
+ },
+ },
+ {
+ Name: "median",
+ Func: func(args ...any) (any, error) {
+ values, err := median(args...)
+ if err != nil {
+ return nil, err
+ }
+ if n := len(values); n > 0 {
+ sort.Float64s(values)
+ if n%2 == 1 {
+ return values[n/2], nil
+ }
+ return (values[n/2-1] + values[n/2]) / 2, nil
+ }
+ return 0.0, nil
+ },
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ return validateAggregateFunc("median", args)
+ },
+ },
+ {
+ Name: "toJSON",
+ Func: func(args ...any) (any, error) {
+ b, err := json.MarshalIndent(args[0], "", " ")
+ if err != nil {
+ return nil, err
+ }
+ return string(b), nil
+ },
+ Types: types(new(func(any) string)),
+ },
+ {
+ Name: "fromJSON",
+ Func: func(args ...any) (any, error) {
+ var v any
+ err := json.Unmarshal([]byte(args[0].(string)), &v)
+ if err != nil {
+ return nil, err
+ }
+ return v, nil
+ },
+ Types: types(new(func(string) any)),
+ },
+ {
+ Name: "toBase64",
+ Func: func(args ...any) (any, error) {
+ return base64.StdEncoding.EncodeToString([]byte(args[0].(string))), nil
+ },
+ Types: types(new(func(string) string)),
+ },
+ {
+ Name: "fromBase64",
+ Func: func(args ...any) (any, error) {
+ b, err := base64.StdEncoding.DecodeString(args[0].(string))
+ if err != nil {
+ return nil, err
+ }
+ return string(b), nil
+ },
+ Types: types(new(func(string) string)),
+ },
+ {
+ Name: "now",
+ Func: func(args ...any) (any, error) {
+ if len(args) == 0 {
+ return time.Now(), nil
+ }
+ if len(args) == 1 {
+ if tz, ok := args[0].(*time.Location); ok {
+ return time.Now().In(tz), nil
+ }
+ }
+ return nil, fmt.Errorf("invalid number of arguments (expected 0, got %d)", len(args))
+ },
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ if len(args) == 0 {
+ return timeType, nil
+ }
+ if len(args) == 1 {
+ if args[0] != nil && args[0].AssignableTo(locationType) {
+ return timeType, nil
+ }
+ }
+ return anyType, fmt.Errorf("invalid number of arguments (expected 0, got %d)", len(args))
+ },
+ Deref: func(i int, arg reflect.Type) bool {
+ return false
+ },
+ },
+ {
+ Name: "duration",
+ Func: func(args ...any) (any, error) {
+ return time.ParseDuration(args[0].(string))
+ },
+ Types: types(time.ParseDuration),
+ },
+ {
+ Name: "date",
+ Func: func(args ...any) (any, error) {
+ tz, ok := args[0].(*time.Location)
+ if ok {
+ args = args[1:]
+ }
+
+ date := args[0].(string)
+ if len(args) == 2 {
+ layout := args[1].(string)
+ if tz != nil {
+ return time.ParseInLocation(layout, date, tz)
+ }
+ return time.Parse(layout, date)
+ }
+ if len(args) == 3 {
+ layout := args[1].(string)
+ timeZone := args[2].(string)
+ tz, err := time.LoadLocation(timeZone)
+ if err != nil {
+ return nil, err
+ }
+ t, err := time.ParseInLocation(layout, date, tz)
+ if err != nil {
+ return nil, err
+ }
+ return t, nil
+ }
+
+ layouts := []string{
+ "2006-01-02",
+ "15:04:05",
+ "2006-01-02 15:04:05",
+ time.RFC3339,
+ time.RFC822,
+ time.RFC850,
+ time.RFC1123,
+ }
+ for _, layout := range layouts {
+ if tz == nil {
+ t, err := time.Parse(layout, date)
+ if err == nil {
+ return t, nil
+ }
+ } else {
+ t, err := time.ParseInLocation(layout, date, tz)
+ if err == nil {
+ return t, nil
+ }
+ }
+ }
+ return nil, fmt.Errorf("invalid date %s", date)
+ },
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ if len(args) < 1 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected at least 1, got %d)", len(args))
+ }
+ if args[0] != nil && args[0].AssignableTo(locationType) {
+ args = args[1:]
+ }
+ if len(args) > 3 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected at most 3, got %d)", len(args))
+ }
+ return timeType, nil
+ },
+ Deref: func(i int, arg reflect.Type) bool {
+ if arg.AssignableTo(locationType) {
+ return false
+ }
+ return true
+ },
+ },
+ {
+ Name: "timezone",
+ Func: func(args ...any) (any, error) {
+ tz, err := time.LoadLocation(args[0].(string))
+ if err != nil {
+ return nil, err
+ }
+ return tz, nil
+ },
+ Types: types(time.LoadLocation),
+ },
+ {
+ Name: "first",
+ Func: func(args ...any) (any, error) {
+ defer func() {
+ if r := recover(); r != nil {
+ return
+ }
+ }()
+ return runtime.Fetch(args[0], 0), nil
+ },
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ if len(args) != 1 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+ switch kind(args[0]) {
+ case reflect.Interface:
+ return anyType, nil
+ case reflect.Slice, reflect.Array:
+ return args[0].Elem(), nil
+ }
+ return anyType, fmt.Errorf("cannot get first element from %s", args[0])
+ },
+ },
+ {
+ Name: "last",
+ Func: func(args ...any) (any, error) {
+ defer func() {
+ if r := recover(); r != nil {
+ return
+ }
+ }()
+ return runtime.Fetch(args[0], -1), nil
+ },
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ if len(args) != 1 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+ switch kind(args[0]) {
+ case reflect.Interface:
+ return anyType, nil
+ case reflect.Slice, reflect.Array:
+ return args[0].Elem(), nil
+ }
+ return anyType, fmt.Errorf("cannot get last element from %s", args[0])
+ },
+ },
+ {
+ Name: "get",
+ Func: get,
+ },
+ {
+ Name: "take",
+ Func: func(args ...any) (any, error) {
+ if len(args) != 2 {
+ return nil, fmt.Errorf("invalid number of arguments (expected 2, got %d)", len(args))
+ }
+ v := reflect.ValueOf(args[0])
+ if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {
+ return nil, fmt.Errorf("cannot take from %s", v.Kind())
+ }
+ n := reflect.ValueOf(args[1])
+ if !n.CanInt() {
+ return nil, fmt.Errorf("cannot take %s elements", n.Kind())
+ }
+ to := 0
+ if n.Int() > int64(v.Len()) {
+ to = v.Len()
+ } else {
+ to = int(n.Int())
+ }
+ return v.Slice(0, to).Interface(), nil
+ },
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ if len(args) != 2 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected 2, got %d)", len(args))
+ }
+ switch kind(args[0]) {
+ case reflect.Interface, reflect.Slice, reflect.Array:
+ default:
+ return anyType, fmt.Errorf("cannot take from %s", args[0])
+ }
+ switch kind(args[1]) {
+ case reflect.Interface, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ default:
+ return anyType, fmt.Errorf("cannot take %s elements", args[1])
+ }
+ return args[0], nil
+ },
+ },
+ {
+ Name: "keys",
+ Func: func(args ...any) (any, error) {
+ if len(args) != 1 {
+ return nil, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+ v := reflect.ValueOf(args[0])
+ if v.Kind() != reflect.Map {
+ return nil, fmt.Errorf("cannot get keys from %s", v.Kind())
+ }
+ keys := v.MapKeys()
+ out := make([]any, len(keys))
+ for i, key := range keys {
+ out[i] = key.Interface()
+ }
+ return out, nil
+ },
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ if len(args) != 1 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+ switch kind(args[0]) {
+ case reflect.Interface:
+ return arrayType, nil
+ case reflect.Map:
+ return arrayType, nil
+ }
+ return anyType, fmt.Errorf("cannot get keys from %s", args[0])
+ },
+ },
+ {
+ Name: "values",
+ Func: func(args ...any) (any, error) {
+ if len(args) != 1 {
+ return nil, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+ v := reflect.ValueOf(args[0])
+ if v.Kind() != reflect.Map {
+ return nil, fmt.Errorf("cannot get values from %s", v.Kind())
+ }
+ keys := v.MapKeys()
+ out := make([]any, len(keys))
+ for i, key := range keys {
+ out[i] = v.MapIndex(key).Interface()
+ }
+ return out, nil
+ },
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ if len(args) != 1 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+ switch kind(args[0]) {
+ case reflect.Interface:
+ return arrayType, nil
+ case reflect.Map:
+ return arrayType, nil
+ }
+ return anyType, fmt.Errorf("cannot get values from %s", args[0])
+ },
+ },
+ {
+ Name: "toPairs",
+ Func: func(args ...any) (any, error) {
+ if len(args) != 1 {
+ return nil, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+ v := reflect.ValueOf(args[0])
+ if v.Kind() != reflect.Map {
+ return nil, fmt.Errorf("cannot transform %s to pairs", v.Kind())
+ }
+ keys := v.MapKeys()
+ out := make([][2]any, len(keys))
+ for i, key := range keys {
+ out[i] = [2]any{key.Interface(), v.MapIndex(key).Interface()}
+ }
+ return out, nil
+ },
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ if len(args) != 1 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+ switch kind(args[0]) {
+ case reflect.Interface, reflect.Map:
+ return arrayType, nil
+ }
+ return anyType, fmt.Errorf("cannot transform %s to pairs", args[0])
+ },
+ },
+ {
+ Name: "fromPairs",
+ Func: func(args ...any) (any, error) {
+ if len(args) != 1 {
+ return nil, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+ v := reflect.ValueOf(args[0])
+ if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {
+ return nil, fmt.Errorf("cannot transform %s from pairs", v)
+ }
+ out := reflect.MakeMap(mapType)
+ for i := 0; i < v.Len(); i++ {
+ pair := deref.Value(v.Index(i))
+ if pair.Kind() != reflect.Array && pair.Kind() != reflect.Slice {
+ return nil, fmt.Errorf("invalid pair %v", pair)
+ }
+ if pair.Len() != 2 {
+ return nil, fmt.Errorf("invalid pair length %v", pair)
+ }
+ key := pair.Index(0)
+ value := pair.Index(1)
+ out.SetMapIndex(key, value)
+ }
+ return out.Interface(), nil
+ },
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ if len(args) != 1 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+ switch kind(args[0]) {
+ case reflect.Interface, reflect.Slice, reflect.Array:
+ return mapType, nil
+ }
+ return anyType, fmt.Errorf("cannot transform %s from pairs", args[0])
+ },
+ },
+ {
+ Name: "reverse",
+ Safe: func(args ...any) (any, uint, error) {
+ if len(args) != 1 {
+ return nil, 0, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+
+ v := reflect.ValueOf(args[0])
+ if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {
+ return nil, 0, fmt.Errorf("cannot reverse %s", v.Kind())
+ }
+
+ size := v.Len()
+ arr := make([]any, size)
+
+ for i := 0; i < size; i++ {
+ arr[i] = v.Index(size - i - 1).Interface()
+ }
+
+ return arr, uint(size), nil
+
+ },
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ if len(args) != 1 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+ switch kind(args[0]) {
+ case reflect.Interface, reflect.Slice, reflect.Array:
+ return arrayType, nil
+ default:
+ return anyType, fmt.Errorf("cannot reverse %s", args[0])
+ }
+ },
+ },
+
+ {
+ Name: "uniq",
+ Func: func(args ...any) (any, error) {
+ if len(args) != 1 {
+ return nil, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+
+ v := reflect.ValueOf(args[0])
+ if v.Kind() != reflect.Array && v.Kind() != reflect.Slice {
+ return nil, fmt.Errorf("cannot uniq %s", v.Kind())
+ }
+
+ size := v.Len()
+ ret := []any{}
+
+ eq := func(i int) bool {
+ for _, r := range ret {
+ if runtime.Equal(v.Index(i).Interface(), r) {
+ return true
+ }
+ }
+
+ return false
+ }
+
+ for i := 0; i < size; i += 1 {
+ if eq(i) {
+ continue
+ }
+
+ ret = append(ret, v.Index(i).Interface())
+ }
+
+ return ret, nil
+ },
+
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ if len(args) != 1 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+
+ switch kind(args[0]) {
+ case reflect.Interface, reflect.Slice, reflect.Array:
+ return arrayType, nil
+ default:
+ return anyType, fmt.Errorf("cannot uniq %s", args[0])
+ }
+ },
+ },
+
+ {
+ Name: "concat",
+ Safe: func(args ...any) (any, uint, error) {
+ if len(args) == 0 {
+ return nil, 0, fmt.Errorf("invalid number of arguments (expected at least 1, got 0)")
+ }
+
+ var size uint
+ var arr []any
+
+ for _, arg := range args {
+ v := reflect.ValueOf(arg)
+
+ if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {
+ return nil, 0, fmt.Errorf("cannot concat %s", v.Kind())
+ }
+
+ size += uint(v.Len())
+
+ for i := 0; i < v.Len(); i++ {
+ item := v.Index(i)
+ arr = append(arr, item.Interface())
+ }
+ }
+
+ return arr, size, nil
+ },
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ if len(args) == 0 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected at least 1, got 0)")
+ }
+
+ for _, arg := range args {
+ switch kind(arg) {
+ case reflect.Interface, reflect.Slice, reflect.Array:
+ default:
+ return anyType, fmt.Errorf("cannot concat %s", arg)
+ }
+ }
+
+ return arrayType, nil
+ },
+ },
+ {
+ Name: "flatten",
+ Safe: func(args ...any) (any, uint, error) {
+ var size uint
+ if len(args) != 1 {
+ return nil, 0, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+ v := reflect.ValueOf(args[0])
+ if v.Kind() != reflect.Array && v.Kind() != reflect.Slice {
+ return nil, size, fmt.Errorf("cannot flatten %s", v.Kind())
+ }
+ ret := flatten(v)
+ size = uint(len(ret))
+ return ret, size, nil
+ },
+ Validate: func(args []reflect.Type) (reflect.Type, error) {
+ if len(args) != 1 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+
+ for _, arg := range args {
+ switch kind(arg) {
+ case reflect.Interface, reflect.Slice, reflect.Array:
+ default:
+ return anyType, fmt.Errorf("cannot flatten %s", arg)
+ }
+ }
+
+ return arrayType, nil
+ },
+ },
+ {
+ Name: "sort",
+ Safe: func(args ...any) (any, uint, error) {
+ if len(args) != 1 && len(args) != 2 {
+ return nil, 0, fmt.Errorf("invalid number of arguments (expected 1 or 2, got %d)", len(args))
+ }
+
+ var array []any
+
+ switch in := args[0].(type) {
+ case []any:
+ array = make([]any, len(in))
+ copy(array, in)
+ case []int:
+ array = make([]any, len(in))
+ for i, v := range in {
+ array[i] = v
+ }
+ case []float64:
+ array = make([]any, len(in))
+ for i, v := range in {
+ array[i] = v
+ }
+ case []string:
+ array = make([]any, len(in))
+ for i, v := range in {
+ array[i] = v
+ }
+ }
+
+ var desc bool
+ if len(args) == 2 {
+ switch args[1].(string) {
+ case "asc":
+ desc = false
+ case "desc":
+ desc = true
+ default:
+ return nil, 0, fmt.Errorf("invalid order %s, expected asc or desc", args[1])
+ }
+ }
+
+ sortable := &runtime.Sort{
+ Desc: desc,
+ Array: array,
+ }
+ sort.Sort(sortable)
+
+ return sortable.Array, uint(len(array)), nil
+ },
+ Types: types(
+ new(func([]any, string) []any),
+ new(func([]int, string) []any),
+ new(func([]float64, string) []any),
+ new(func([]string, string) []any),
+
+ new(func([]any) []any),
+ new(func([]float64) []any),
+ new(func([]string) []any),
+ new(func([]int) []any),
+ ),
+ },
+ bitFunc("bitand", func(x, y int) (any, error) {
+ return x & y, nil
+ }),
+ bitFunc("bitor", func(x, y int) (any, error) {
+ return x | y, nil
+ }),
+ bitFunc("bitxor", func(x, y int) (any, error) {
+ return x ^ y, nil
+ }),
+ bitFunc("bitnand", func(x, y int) (any, error) {
+ return x &^ y, nil
+ }),
+ bitFunc("bitshl", func(x, y int) (any, error) {
+ if y < 0 {
+ return nil, fmt.Errorf("invalid operation: negative shift count %d (type int)", y)
+ }
+ return x << y, nil
+ }),
+ bitFunc("bitshr", func(x, y int) (any, error) {
+ if y < 0 {
+ return nil, fmt.Errorf("invalid operation: negative shift count %d (type int)", y)
+ }
+ return x >> y, nil
+ }),
+ bitFunc("bitushr", func(x, y int) (any, error) {
+ if y < 0 {
+ return nil, fmt.Errorf("invalid operation: negative shift count %d (type int)", y)
+ }
+ return int(uint(x) >> y), nil
+ }),
+ {
+ Name: "bitnot",
+ Func: func(args ...any) (any, error) {
+ if len(args) != 1 {
+ return nil, fmt.Errorf("invalid number of arguments for bitnot (expected 1, got %d)", len(args))
+ }
+ x, err := toInt(args[0])
+ if err != nil {
+ return nil, fmt.Errorf("%v to call bitnot", err)
+ }
+ return ^x, nil
+ },
+ Types: types(new(func(int) int)),
+ },
+}
diff --git a/vendor/github.com/expr-lang/expr/builtin/function.go b/vendor/github.com/expr-lang/expr/builtin/function.go
new file mode 100644
index 0000000..6634ac3
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/builtin/function.go
@@ -0,0 +1,23 @@
+package builtin
+
+import (
+ "reflect"
+)
+
+type Function struct {
+ Name string
+ Fast func(arg any) any
+ Func func(args ...any) (any, error)
+ Safe func(args ...any) (any, uint, error)
+ Types []reflect.Type
+ Validate func(args []reflect.Type) (reflect.Type, error)
+ Deref func(i int, arg reflect.Type) bool
+ Predicate bool
+}
+
+func (f *Function) Type() reflect.Type {
+ if len(f.Types) > 0 {
+ return f.Types[0]
+ }
+ return reflect.TypeOf(f.Func)
+}
diff --git a/vendor/github.com/expr-lang/expr/builtin/lib.go b/vendor/github.com/expr-lang/expr/builtin/lib.go
new file mode 100644
index 0000000..5a70a6b
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/builtin/lib.go
@@ -0,0 +1,433 @@
+package builtin
+
+import (
+ "fmt"
+ "math"
+ "reflect"
+ "strconv"
+ "unicode/utf8"
+
+ "github.com/expr-lang/expr/internal/deref"
+ "github.com/expr-lang/expr/vm/runtime"
+)
+
+func Len(x any) any {
+ v := reflect.ValueOf(x)
+ switch v.Kind() {
+ case reflect.Array, reflect.Slice, reflect.Map:
+ return v.Len()
+ case reflect.String:
+ return utf8.RuneCountInString(v.String())
+ default:
+ panic(fmt.Sprintf("invalid argument for len (type %T)", x))
+ }
+}
+
+func Type(arg any) any {
+ if arg == nil {
+ return "nil"
+ }
+ v := reflect.ValueOf(arg)
+ if v.Type().Name() != "" && v.Type().PkgPath() != "" {
+ return fmt.Sprintf("%s.%s", v.Type().PkgPath(), v.Type().Name())
+ }
+ switch v.Type().Kind() {
+ case reflect.Invalid:
+ return "invalid"
+ case reflect.Bool:
+ return "bool"
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return "int"
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return "uint"
+ case reflect.Float32, reflect.Float64:
+ return "float"
+ case reflect.String:
+ return "string"
+ case reflect.Array, reflect.Slice:
+ return "array"
+ case reflect.Map:
+ return "map"
+ case reflect.Func:
+ return "func"
+ case reflect.Struct:
+ return "struct"
+ default:
+ return "unknown"
+ }
+}
+
+func Abs(x any) any {
+ switch x := x.(type) {
+ case float32:
+ if x < 0 {
+ return -x
+ } else {
+ return x
+ }
+ case float64:
+ if x < 0 {
+ return -x
+ } else {
+ return x
+ }
+ case int:
+ if x < 0 {
+ return -x
+ } else {
+ return x
+ }
+ case int8:
+ if x < 0 {
+ return -x
+ } else {
+ return x
+ }
+ case int16:
+ if x < 0 {
+ return -x
+ } else {
+ return x
+ }
+ case int32:
+ if x < 0 {
+ return -x
+ } else {
+ return x
+ }
+ case int64:
+ if x < 0 {
+ return -x
+ } else {
+ return x
+ }
+ case uint:
+ if x < 0 {
+ return -x
+ } else {
+ return x
+ }
+ case uint8:
+ if x < 0 {
+ return -x
+ } else {
+ return x
+ }
+ case uint16:
+ if x < 0 {
+ return -x
+ } else {
+ return x
+ }
+ case uint32:
+ if x < 0 {
+ return -x
+ } else {
+ return x
+ }
+ case uint64:
+ if x < 0 {
+ return -x
+ } else {
+ return x
+ }
+ }
+ panic(fmt.Sprintf("invalid argument for abs (type %T)", x))
+}
+
+func Ceil(x any) any {
+ switch x := x.(type) {
+ case float32:
+ return math.Ceil(float64(x))
+ case float64:
+ return math.Ceil(x)
+ case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
+ return Float(x)
+ }
+ panic(fmt.Sprintf("invalid argument for ceil (type %T)", x))
+}
+
+func Floor(x any) any {
+ switch x := x.(type) {
+ case float32:
+ return math.Floor(float64(x))
+ case float64:
+ return math.Floor(x)
+ case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
+ return Float(x)
+ }
+ panic(fmt.Sprintf("invalid argument for floor (type %T)", x))
+}
+
+func Round(x any) any {
+ switch x := x.(type) {
+ case float32:
+ return math.Round(float64(x))
+ case float64:
+ return math.Round(x)
+ case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
+ return Float(x)
+ }
+ panic(fmt.Sprintf("invalid argument for round (type %T)", x))
+}
+
+func Int(x any) any {
+ switch x := x.(type) {
+ case float32:
+ return int(x)
+ case float64:
+ return int(x)
+ case int:
+ return x
+ case int8:
+ return int(x)
+ case int16:
+ return int(x)
+ case int32:
+ return int(x)
+ case int64:
+ return int(x)
+ case uint:
+ return int(x)
+ case uint8:
+ return int(x)
+ case uint16:
+ return int(x)
+ case uint32:
+ return int(x)
+ case uint64:
+ return int(x)
+ case string:
+ i, err := strconv.Atoi(x)
+ if err != nil {
+ panic(fmt.Sprintf("invalid operation: int(%s)", x))
+ }
+ return i
+ default:
+ val := reflect.ValueOf(x)
+ if val.CanConvert(integerType) {
+ return val.Convert(integerType).Interface()
+ }
+ panic(fmt.Sprintf("invalid operation: int(%T)", x))
+ }
+}
+
+func Float(x any) any {
+ switch x := x.(type) {
+ case float32:
+ return float64(x)
+ case float64:
+ return x
+ case int:
+ return float64(x)
+ case int8:
+ return float64(x)
+ case int16:
+ return float64(x)
+ case int32:
+ return float64(x)
+ case int64:
+ return float64(x)
+ case uint:
+ return float64(x)
+ case uint8:
+ return float64(x)
+ case uint16:
+ return float64(x)
+ case uint32:
+ return float64(x)
+ case uint64:
+ return float64(x)
+ case string:
+ f, err := strconv.ParseFloat(x, 64)
+ if err != nil {
+ panic(fmt.Sprintf("invalid operation: float(%s)", x))
+ }
+ return f
+ default:
+ panic(fmt.Sprintf("invalid operation: float(%T)", x))
+ }
+}
+
+func String(arg any) any {
+ return fmt.Sprintf("%v", arg)
+}
+
+func minMax(name string, fn func(any, any) bool, args ...any) (any, error) {
+ var val any
+ for _, arg := range args {
+ rv := reflect.ValueOf(arg)
+ switch rv.Kind() {
+ case reflect.Array, reflect.Slice:
+ size := rv.Len()
+ for i := 0; i < size; i++ {
+ elemVal, err := minMax(name, fn, rv.Index(i).Interface())
+ if err != nil {
+ return nil, err
+ }
+ switch elemVal.(type) {
+ case int, int8, int16, int32, int64,
+ uint, uint8, uint16, uint32, uint64,
+ float32, float64:
+ if elemVal != nil && (val == nil || fn(val, elemVal)) {
+ val = elemVal
+ }
+ default:
+ return nil, fmt.Errorf("invalid argument for %s (type %T)", name, elemVal)
+ }
+
+ }
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+ reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
+ reflect.Float32, reflect.Float64:
+ elemVal := rv.Interface()
+ if val == nil || fn(val, elemVal) {
+ val = elemVal
+ }
+ default:
+ if len(args) == 1 {
+ return args[0], nil
+ }
+ return nil, fmt.Errorf("invalid argument for %s (type %T)", name, arg)
+ }
+ }
+ return val, nil
+}
+
+func mean(args ...any) (int, float64, error) {
+ var total float64
+ var count int
+
+ for _, arg := range args {
+ rv := reflect.ValueOf(arg)
+ switch rv.Kind() {
+ case reflect.Array, reflect.Slice:
+ size := rv.Len()
+ for i := 0; i < size; i++ {
+ elemCount, elemSum, err := mean(rv.Index(i).Interface())
+ if err != nil {
+ return 0, 0, err
+ }
+ total += elemSum
+ count += elemCount
+ }
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ total += float64(rv.Int())
+ count++
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ total += float64(rv.Uint())
+ count++
+ case reflect.Float32, reflect.Float64:
+ total += rv.Float()
+ count++
+ default:
+ return 0, 0, fmt.Errorf("invalid argument for mean (type %T)", arg)
+ }
+ }
+ return count, total, nil
+}
+
+func median(args ...any) ([]float64, error) {
+ var values []float64
+
+ for _, arg := range args {
+ rv := reflect.ValueOf(arg)
+ switch rv.Kind() {
+ case reflect.Array, reflect.Slice:
+ size := rv.Len()
+ for i := 0; i < size; i++ {
+ elems, err := median(rv.Index(i).Interface())
+ if err != nil {
+ return nil, err
+ }
+ values = append(values, elems...)
+ }
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ values = append(values, float64(rv.Int()))
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ values = append(values, float64(rv.Uint()))
+ case reflect.Float32, reflect.Float64:
+ values = append(values, rv.Float())
+ default:
+ return nil, fmt.Errorf("invalid argument for median (type %T)", arg)
+ }
+ }
+ return values, nil
+}
+
+func flatten(arg reflect.Value) []any {
+ ret := []any{}
+ for i := 0; i < arg.Len(); i++ {
+ v := deref.Value(arg.Index(i))
+ if v.Kind() == reflect.Array || v.Kind() == reflect.Slice {
+ x := flatten(v)
+ ret = append(ret, x...)
+ } else {
+ ret = append(ret, v.Interface())
+ }
+ }
+ return ret
+}
+
+func get(params ...any) (out any, err error) {
+ from := params[0]
+ i := params[1]
+ v := reflect.ValueOf(from)
+
+ if v.Kind() == reflect.Invalid {
+ panic(fmt.Sprintf("cannot fetch %v from %T", i, from))
+ }
+
+ // Methods can be defined on any type.
+ if v.NumMethod() > 0 {
+ if methodName, ok := i.(string); ok {
+ method := v.MethodByName(methodName)
+ if method.IsValid() {
+ return method.Interface(), nil
+ }
+ }
+ }
+
+ switch v.Kind() {
+ case reflect.Array, reflect.Slice, reflect.String:
+ index := runtime.ToInt(i)
+ l := v.Len()
+ if index < 0 {
+ index = l + index
+ }
+ if 0 <= index && index < l {
+ value := v.Index(index)
+ if value.IsValid() {
+ return value.Interface(), nil
+ }
+ }
+
+ case reflect.Map:
+ var value reflect.Value
+ if i == nil {
+ value = v.MapIndex(reflect.Zero(v.Type().Key()))
+ } else {
+ value = v.MapIndex(reflect.ValueOf(i))
+ }
+ if value.IsValid() {
+ return value.Interface(), nil
+ }
+
+ case reflect.Struct:
+ fieldName := i.(string)
+ value := v.FieldByNameFunc(func(name string) bool {
+ field, _ := v.Type().FieldByName(name)
+ if field.Tag.Get("expr") == fieldName {
+ return true
+ }
+ return name == fieldName
+ })
+ if value.IsValid() {
+ return value.Interface(), nil
+ }
+ }
+
+ // Main difference from runtime.Fetch
+ // is that we return `nil` instead of panic.
+ return nil, nil
+}
diff --git a/vendor/github.com/expr-lang/expr/builtin/utils.go b/vendor/github.com/expr-lang/expr/builtin/utils.go
new file mode 100644
index 0000000..262bb37
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/builtin/utils.go
@@ -0,0 +1,90 @@
+package builtin
+
+import (
+ "fmt"
+ "reflect"
+ "time"
+
+ "github.com/expr-lang/expr/internal/deref"
+)
+
+var (
+ anyType = reflect.TypeOf(new(any)).Elem()
+ integerType = reflect.TypeOf(0)
+ floatType = reflect.TypeOf(float64(0))
+ arrayType = reflect.TypeOf([]any{})
+ mapType = reflect.TypeOf(map[any]any{})
+ timeType = reflect.TypeOf(new(time.Time)).Elem()
+ locationType = reflect.TypeOf(new(time.Location))
+)
+
+func kind(t reflect.Type) reflect.Kind {
+ if t == nil {
+ return reflect.Invalid
+ }
+ t = deref.Type(t)
+ return t.Kind()
+}
+
+func types(types ...any) []reflect.Type {
+ ts := make([]reflect.Type, len(types))
+ for i, t := range types {
+ t := reflect.TypeOf(t)
+ if t.Kind() == reflect.Ptr {
+ t = t.Elem()
+ }
+ if t.Kind() != reflect.Func {
+ panic("not a function")
+ }
+ ts[i] = t
+ }
+ return ts
+}
+
+func toInt(val any) (int, error) {
+ switch v := val.(type) {
+ case int:
+ return v, nil
+ case int8:
+ return int(v), nil
+ case int16:
+ return int(v), nil
+ case int32:
+ return int(v), nil
+ case int64:
+ return int(v), nil
+ case uint:
+ return int(v), nil
+ case uint8:
+ return int(v), nil
+ case uint16:
+ return int(v), nil
+ case uint32:
+ return int(v), nil
+ case uint64:
+ return int(v), nil
+ default:
+ return 0, fmt.Errorf("cannot use %T as argument (type int)", val)
+ }
+}
+
+func bitFunc(name string, fn func(x, y int) (any, error)) *Function {
+ return &Function{
+ Name: name,
+ Func: func(args ...any) (any, error) {
+ if len(args) != 2 {
+ return nil, fmt.Errorf("invalid number of arguments for %s (expected 2, got %d)", name, len(args))
+ }
+ x, err := toInt(args[0])
+ if err != nil {
+ return nil, fmt.Errorf("%v to call %s", err, name)
+ }
+ y, err := toInt(args[1])
+ if err != nil {
+ return nil, fmt.Errorf("%v to call %s", err, name)
+ }
+ return fn(x, y)
+ },
+ Types: types(new(func(int, int) int)),
+ }
+}
diff --git a/vendor/github.com/expr-lang/expr/builtin/validation.go b/vendor/github.com/expr-lang/expr/builtin/validation.go
new file mode 100644
index 0000000..057f247
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/builtin/validation.go
@@ -0,0 +1,38 @@
+package builtin
+
+import (
+ "fmt"
+ "reflect"
+
+ "github.com/expr-lang/expr/internal/deref"
+)
+
+func validateAggregateFunc(name string, args []reflect.Type) (reflect.Type, error) {
+ switch len(args) {
+ case 0:
+ return anyType, fmt.Errorf("not enough arguments to call %s", name)
+ default:
+ for _, arg := range args {
+ switch kind(deref.Type(arg)) {
+ case reflect.Interface, reflect.Array, reflect.Slice:
+ return anyType, nil
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64:
+ default:
+ return anyType, fmt.Errorf("invalid argument for %s (type %s)", name, arg)
+ }
+ }
+ return args[0], nil
+ }
+}
+
+func validateRoundFunc(name string, args []reflect.Type) (reflect.Type, error) {
+ if len(args) != 1 {
+ return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
+ }
+ switch kind(args[0]) {
+ case reflect.Float32, reflect.Float64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Interface:
+ return floatType, nil
+ default:
+ return anyType, fmt.Errorf("invalid argument for %s (type %s)", name, args[0])
+ }
+}
diff --git a/vendor/github.com/expr-lang/expr/checker/checker.go b/vendor/github.com/expr-lang/expr/checker/checker.go
new file mode 100644
index 0000000..f492341
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/checker/checker.go
@@ -0,0 +1,1285 @@
+package checker
+
+import (
+ "fmt"
+ "reflect"
+ "regexp"
+
+ "github.com/expr-lang/expr/ast"
+ "github.com/expr-lang/expr/builtin"
+ . "github.com/expr-lang/expr/checker/nature"
+ "github.com/expr-lang/expr/conf"
+ "github.com/expr-lang/expr/file"
+ "github.com/expr-lang/expr/parser"
+)
+
+// Run visitors in a given config over the given tree
+// runRepeatable controls whether to filter for only vistors that require multiple passes or not
+func runVisitors(tree *parser.Tree, config *conf.Config, runRepeatable bool) {
+ for {
+ more := false
+ for _, v := range config.Visitors {
+ // We need to perform types check, because some visitors may rely on
+ // types information available in the tree.
+ _, _ = Check(tree, config)
+
+ r, repeatable := v.(interface {
+ Reset()
+ ShouldRepeat() bool
+ })
+
+ if repeatable {
+ if runRepeatable {
+ r.Reset()
+ ast.Walk(&tree.Node, v)
+ more = more || r.ShouldRepeat()
+ }
+ } else {
+ if !runRepeatable {
+ ast.Walk(&tree.Node, v)
+ }
+ }
+ }
+
+ if !more {
+ break
+ }
+ }
+}
+
+// ParseCheck parses input expression and checks its types. Also, it applies
+// all provided patchers. In case of error, it returns error with a tree.
+func ParseCheck(input string, config *conf.Config) (*parser.Tree, error) {
+ tree, err := parser.ParseWithConfig(input, config)
+ if err != nil {
+ return tree, err
+ }
+
+ if len(config.Visitors) > 0 {
+ // Run all patchers that dont support being run repeatedly first
+ runVisitors(tree, config, false)
+
+ // Run patchers that require multiple passes next (currently only Operator patching)
+ runVisitors(tree, config, true)
+ }
+ _, err = Check(tree, config)
+ if err != nil {
+ return tree, err
+ }
+
+ return tree, nil
+}
+
+// Check checks types of the expression tree. It returns type of the expression
+// and error if any. If config is nil, then default configuration will be used.
+func Check(tree *parser.Tree, config *conf.Config) (reflect.Type, error) {
+ if config == nil {
+ config = conf.New(nil)
+ }
+
+ v := &checker{config: config}
+
+ nt := v.visit(tree.Node)
+
+ // To keep compatibility with previous versions, we should return any, if nature is unknown.
+ t := nt.Type
+ if t == nil {
+ t = anyType
+ }
+
+ if v.err != nil {
+ return t, v.err.Bind(tree.Source)
+ }
+
+ if v.config.Expect != reflect.Invalid {
+ if v.config.ExpectAny {
+ if isUnknown(nt) {
+ return t, nil
+ }
+ }
+
+ switch v.config.Expect {
+ case reflect.Int, reflect.Int64, reflect.Float64:
+ if !isNumber(nt) {
+ return nil, fmt.Errorf("expected %v, but got %v", v.config.Expect, nt)
+ }
+ default:
+ if nt.Kind() != v.config.Expect {
+ return nil, fmt.Errorf("expected %v, but got %s", v.config.Expect, nt)
+ }
+ }
+ }
+
+ return t, nil
+}
+
+type checker struct {
+ config *conf.Config
+ predicateScopes []predicateScope
+ varScopes []varScope
+ err *file.Error
+}
+
+type predicateScope struct {
+ collection Nature
+ vars map[string]Nature
+}
+
+type varScope struct {
+ name string
+ nature Nature
+}
+
+type info struct {
+ method bool
+ fn *builtin.Function
+
+ // elem is element type of array or map.
+ // Arrays created with type []any, but
+ // we would like to detect expressions
+ // like `42 in ["a"]` as invalid.
+ elem reflect.Type
+}
+
+func (v *checker) visit(node ast.Node) Nature {
+ var nt Nature
+ switch n := node.(type) {
+ case *ast.NilNode:
+ nt = v.NilNode(n)
+ case *ast.IdentifierNode:
+ nt = v.IdentifierNode(n)
+ case *ast.IntegerNode:
+ nt = v.IntegerNode(n)
+ case *ast.FloatNode:
+ nt = v.FloatNode(n)
+ case *ast.BoolNode:
+ nt = v.BoolNode(n)
+ case *ast.StringNode:
+ nt = v.StringNode(n)
+ case *ast.ConstantNode:
+ nt = v.ConstantNode(n)
+ case *ast.UnaryNode:
+ nt = v.UnaryNode(n)
+ case *ast.BinaryNode:
+ nt = v.BinaryNode(n)
+ case *ast.ChainNode:
+ nt = v.ChainNode(n)
+ case *ast.MemberNode:
+ nt = v.MemberNode(n)
+ case *ast.SliceNode:
+ nt = v.SliceNode(n)
+ case *ast.CallNode:
+ nt = v.CallNode(n)
+ case *ast.BuiltinNode:
+ nt = v.BuiltinNode(n)
+ case *ast.PredicateNode:
+ nt = v.PredicateNode(n)
+ case *ast.PointerNode:
+ nt = v.PointerNode(n)
+ case *ast.VariableDeclaratorNode:
+ nt = v.VariableDeclaratorNode(n)
+ case *ast.SequenceNode:
+ nt = v.SequenceNode(n)
+ case *ast.ConditionalNode:
+ nt = v.ConditionalNode(n)
+ case *ast.ArrayNode:
+ nt = v.ArrayNode(n)
+ case *ast.MapNode:
+ nt = v.MapNode(n)
+ case *ast.PairNode:
+ nt = v.PairNode(n)
+ default:
+ panic(fmt.Sprintf("undefined node type (%T)", node))
+ }
+ node.SetNature(nt)
+ return nt
+}
+
+func (v *checker) error(node ast.Node, format string, args ...any) Nature {
+ if v.err == nil { // show first error
+ v.err = &file.Error{
+ Location: node.Location(),
+ Message: fmt.Sprintf(format, args...),
+ }
+ }
+ return unknown
+}
+
+func (v *checker) NilNode(*ast.NilNode) Nature {
+ return nilNature
+}
+
+func (v *checker) IdentifierNode(node *ast.IdentifierNode) Nature {
+ if variable, ok := v.lookupVariable(node.Value); ok {
+ return variable.nature
+ }
+ if node.Value == "$env" {
+ return unknown
+ }
+
+ return v.ident(node, node.Value, v.config.Strict, true)
+}
+
+// ident method returns type of environment variable, builtin or function.
+func (v *checker) ident(node ast.Node, name string, strict, builtins bool) Nature {
+ if nt, ok := v.config.Env.Get(name); ok {
+ return nt
+ }
+ if builtins {
+ if fn, ok := v.config.Functions[name]; ok {
+ return Nature{Type: fn.Type(), Func: fn}
+ }
+ if fn, ok := v.config.Builtins[name]; ok {
+ return Nature{Type: fn.Type(), Func: fn}
+ }
+ }
+ if v.config.Strict && strict {
+ return v.error(node, "unknown name %v", name)
+ }
+ return unknown
+}
+
+func (v *checker) IntegerNode(*ast.IntegerNode) Nature {
+ return integerNature
+}
+
+func (v *checker) FloatNode(*ast.FloatNode) Nature {
+ return floatNature
+}
+
+func (v *checker) BoolNode(*ast.BoolNode) Nature {
+ return boolNature
+}
+
+func (v *checker) StringNode(*ast.StringNode) Nature {
+ return stringNature
+}
+
+func (v *checker) ConstantNode(node *ast.ConstantNode) Nature {
+ return Nature{Type: reflect.TypeOf(node.Value)}
+}
+
+func (v *checker) UnaryNode(node *ast.UnaryNode) Nature {
+ nt := v.visit(node.Node)
+ nt = nt.Deref()
+
+ switch node.Operator {
+
+ case "!", "not":
+ if isBool(nt) {
+ return boolNature
+ }
+ if isUnknown(nt) {
+ return boolNature
+ }
+
+ case "+", "-":
+ if isNumber(nt) {
+ return nt
+ }
+ if isUnknown(nt) {
+ return unknown
+ }
+
+ default:
+ return v.error(node, "unknown operator (%v)", node.Operator)
+ }
+
+ return v.error(node, `invalid operation: %v (mismatched type %s)`, node.Operator, nt)
+}
+
+func (v *checker) BinaryNode(node *ast.BinaryNode) Nature {
+ l := v.visit(node.Left)
+ r := v.visit(node.Right)
+
+ l = l.Deref()
+ r = r.Deref()
+
+ switch node.Operator {
+ case "==", "!=":
+ if isComparable(l, r) {
+ return boolNature
+ }
+
+ case "or", "||", "and", "&&":
+ if isBool(l) && isBool(r) {
+ return boolNature
+ }
+ if or(l, r, isBool) {
+ return boolNature
+ }
+
+ case "<", ">", ">=", "<=":
+ if isNumber(l) && isNumber(r) {
+ return boolNature
+ }
+ if isString(l) && isString(r) {
+ return boolNature
+ }
+ if isTime(l) && isTime(r) {
+ return boolNature
+ }
+ if isDuration(l) && isDuration(r) {
+ return boolNature
+ }
+ if or(l, r, isNumber, isString, isTime, isDuration) {
+ return boolNature
+ }
+
+ case "-":
+ if isNumber(l) && isNumber(r) {
+ return combined(l, r)
+ }
+ if isTime(l) && isTime(r) {
+ return durationNature
+ }
+ if isTime(l) && isDuration(r) {
+ return timeNature
+ }
+ if isDuration(l) && isDuration(r) {
+ return durationNature
+ }
+ if or(l, r, isNumber, isTime, isDuration) {
+ return unknown
+ }
+
+ case "*":
+ if isNumber(l) && isNumber(r) {
+ return combined(l, r)
+ }
+ if isNumber(l) && isDuration(r) {
+ return durationNature
+ }
+ if isDuration(l) && isNumber(r) {
+ return durationNature
+ }
+ if isDuration(l) && isDuration(r) {
+ return durationNature
+ }
+ if or(l, r, isNumber, isDuration) {
+ return unknown
+ }
+
+ case "/":
+ if isNumber(l) && isNumber(r) {
+ return floatNature
+ }
+ if or(l, r, isNumber) {
+ return floatNature
+ }
+
+ case "**", "^":
+ if isNumber(l) && isNumber(r) {
+ return floatNature
+ }
+ if or(l, r, isNumber) {
+ return floatNature
+ }
+
+ case "%":
+ if isInteger(l) && isInteger(r) {
+ return integerNature
+ }
+ if or(l, r, isInteger) {
+ return integerNature
+ }
+
+ case "+":
+ if isNumber(l) && isNumber(r) {
+ return combined(l, r)
+ }
+ if isString(l) && isString(r) {
+ return stringNature
+ }
+ if isTime(l) && isDuration(r) {
+ return timeNature
+ }
+ if isDuration(l) && isTime(r) {
+ return timeNature
+ }
+ if isDuration(l) && isDuration(r) {
+ return durationNature
+ }
+ if or(l, r, isNumber, isString, isTime, isDuration) {
+ return unknown
+ }
+
+ case "in":
+ if (isString(l) || isUnknown(l)) && isStruct(r) {
+ return boolNature
+ }
+ if isMap(r) {
+ if !isUnknown(l) && !l.AssignableTo(r.Key()) {
+ return v.error(node, "cannot use %v as type %v in map key", l, r.Key())
+ }
+ return boolNature
+ }
+ if isArray(r) {
+ if !isComparable(l, r.Elem()) {
+ return v.error(node, "cannot use %v as type %v in array", l, r.Elem())
+ }
+ return boolNature
+ }
+ if isUnknown(l) && anyOf(r, isString, isArray, isMap) {
+ return boolNature
+ }
+ if isUnknown(r) {
+ return boolNature
+ }
+
+ case "matches":
+ if s, ok := node.Right.(*ast.StringNode); ok {
+ _, err := regexp.Compile(s.Value)
+ if err != nil {
+ return v.error(node, err.Error())
+ }
+ }
+ if isString(l) && isString(r) {
+ return boolNature
+ }
+ if or(l, r, isString) {
+ return boolNature
+ }
+
+ case "contains", "startsWith", "endsWith":
+ if isString(l) && isString(r) {
+ return boolNature
+ }
+ if or(l, r, isString) {
+ return boolNature
+ }
+
+ case "..":
+ if isInteger(l) && isInteger(r) {
+ return arrayOf(integerNature)
+ }
+ if or(l, r, isInteger) {
+ return arrayOf(integerNature)
+ }
+
+ case "??":
+ if isNil(l) && !isNil(r) {
+ return r
+ }
+ if !isNil(l) && isNil(r) {
+ return l
+ }
+ if isNil(l) && isNil(r) {
+ return nilNature
+ }
+ if r.AssignableTo(l) {
+ return l
+ }
+ return unknown
+
+ default:
+ return v.error(node, "unknown operator (%v)", node.Operator)
+
+ }
+
+ return v.error(node, `invalid operation: %v (mismatched types %v and %v)`, node.Operator, l, r)
+}
+
+func (v *checker) ChainNode(node *ast.ChainNode) Nature {
+ return v.visit(node.Node)
+}
+
+func (v *checker) MemberNode(node *ast.MemberNode) Nature {
+ // $env variable
+ if an, ok := node.Node.(*ast.IdentifierNode); ok && an.Value == "$env" {
+ if name, ok := node.Property.(*ast.StringNode); ok {
+ strict := v.config.Strict
+ if node.Optional {
+ // If user explicitly set optional flag, then we should not
+ // throw error if field is not found (as user trying to handle
+ // this case). But if user did not set optional flag, then we
+ // should throw error if field is not found & v.config.Strict.
+ strict = false
+ }
+ return v.ident(node, name.Value, strict, false /* no builtins and no functions */)
+ }
+ return unknown
+ }
+
+ base := v.visit(node.Node)
+ prop := v.visit(node.Property)
+
+ if isUnknown(base) {
+ return unknown
+ }
+
+ if name, ok := node.Property.(*ast.StringNode); ok {
+ if isNil(base) {
+ return v.error(node, "type nil has no field %v", name.Value)
+ }
+
+ // First, check methods defined on base type itself,
+ // independent of which type it is. Without dereferencing.
+ if m, ok := base.MethodByName(name.Value); ok {
+ return m
+ }
+ }
+
+ base = base.Deref()
+
+ switch base.Kind() {
+ case reflect.Map:
+ if !prop.AssignableTo(base.Key()) && !isUnknown(prop) {
+ return v.error(node.Property, "cannot use %v to get an element from %v", prop, base)
+ }
+ if prop, ok := node.Property.(*ast.StringNode); ok {
+ if field, ok := base.Fields[prop.Value]; ok {
+ return field
+ } else if base.Strict {
+ return v.error(node.Property, "unknown field %v", prop.Value)
+ }
+ }
+ return base.Elem()
+
+ case reflect.Array, reflect.Slice:
+ if !isInteger(prop) && !isUnknown(prop) {
+ return v.error(node.Property, "array elements can only be selected using an integer (got %v)", prop)
+ }
+ return base.Elem()
+
+ case reflect.Struct:
+ if name, ok := node.Property.(*ast.StringNode); ok {
+ propertyName := name.Value
+ if field, ok := base.FieldByName(propertyName); ok {
+ return Nature{Type: field.Type}
+ }
+ if node.Method {
+ return v.error(node, "type %v has no method %v", base, propertyName)
+ }
+ return v.error(node, "type %v has no field %v", base, propertyName)
+ }
+ }
+
+ // Not found.
+
+ if name, ok := node.Property.(*ast.StringNode); ok {
+ if node.Method {
+ return v.error(node, "type %v has no method %v", base, name.Value)
+ }
+ return v.error(node, "type %v has no field %v", base, name.Value)
+ }
+ return v.error(node, "type %v[%v] is undefined", base, prop)
+}
+
+func (v *checker) SliceNode(node *ast.SliceNode) Nature {
+ nt := v.visit(node.Node)
+
+ if isUnknown(nt) {
+ return unknown
+ }
+
+ switch nt.Kind() {
+ case reflect.String, reflect.Array, reflect.Slice:
+ // ok
+ default:
+ return v.error(node, "cannot slice %s", nt)
+ }
+
+ if node.From != nil {
+ from := v.visit(node.From)
+ if !isInteger(from) && !isUnknown(from) {
+ return v.error(node.From, "non-integer slice index %v", from)
+ }
+ }
+
+ if node.To != nil {
+ to := v.visit(node.To)
+ if !isInteger(to) && !isUnknown(to) {
+ return v.error(node.To, "non-integer slice index %v", to)
+ }
+ }
+
+ return nt
+}
+
+func (v *checker) CallNode(node *ast.CallNode) Nature {
+ nt := v.functionReturnType(node)
+
+ // Check if type was set on node (for example, by patcher)
+ // and use node type instead of function return type.
+ //
+ // If node type is anyType, then we should use function
+ // return type. For example, on error we return anyType
+ // for a call `errCall().Method()` and method will be
+ // evaluated on `anyType.Method()`, so return type will
+ // be anyType `anyType.Method(): anyType`. Patcher can
+ // fix `errCall()` to return proper type, so on second
+ // checker pass we should replace anyType on method node
+ // with new correct function return type.
+ if node.Type() != nil && node.Type() != anyType {
+ return node.Nature()
+ }
+
+ return nt
+}
+
+func (v *checker) functionReturnType(node *ast.CallNode) Nature {
+ nt := v.visit(node.Callee)
+
+ if nt.Func != nil {
+ return v.checkFunction(nt.Func, node, node.Arguments)
+ }
+
+ fnName := "function"
+ if identifier, ok := node.Callee.(*ast.IdentifierNode); ok {
+ fnName = identifier.Value
+ }
+ if member, ok := node.Callee.(*ast.MemberNode); ok {
+ if name, ok := member.Property.(*ast.StringNode); ok {
+ fnName = name.Value
+ }
+ }
+
+ if isUnknown(nt) {
+ return unknown
+ }
+
+ if isNil(nt) {
+ return v.error(node, "%v is nil; cannot call nil as function", fnName)
+ }
+
+ switch nt.Kind() {
+ case reflect.Func:
+ outType, err := v.checkArguments(fnName, nt, node.Arguments, node)
+ if err != nil {
+ if v.err == nil {
+ v.err = err
+ }
+ return unknown
+ }
+ return outType
+ }
+ return v.error(node, "%s is not callable", nt)
+}
+
+func (v *checker) BuiltinNode(node *ast.BuiltinNode) Nature {
+ switch node.Name {
+ case "all", "none", "any", "one":
+ collection := v.visit(node.Arguments[0]).Deref()
+ if !isArray(collection) && !isUnknown(collection) {
+ return v.error(node.Arguments[0], "builtin %v takes only array (got %v)", node.Name, collection)
+ }
+
+ v.begin(collection)
+ predicate := v.visit(node.Arguments[1])
+ v.end()
+
+ if isFunc(predicate) &&
+ predicate.NumOut() == 1 &&
+ predicate.NumIn() == 1 && isUnknown(predicate.In(0)) {
+
+ if !isBool(predicate.Out(0)) && !isUnknown(predicate.Out(0)) {
+ return v.error(node.Arguments[1], "predicate should return boolean (got %v)", predicate.Out(0).String())
+ }
+ return boolNature
+ }
+ return v.error(node.Arguments[1], "predicate should has one input and one output param")
+
+ case "filter":
+ collection := v.visit(node.Arguments[0]).Deref()
+ if !isArray(collection) && !isUnknown(collection) {
+ return v.error(node.Arguments[0], "builtin %v takes only array (got %v)", node.Name, collection)
+ }
+
+ v.begin(collection)
+ predicate := v.visit(node.Arguments[1])
+ v.end()
+
+ if isFunc(predicate) &&
+ predicate.NumOut() == 1 &&
+ predicate.NumIn() == 1 && isUnknown(predicate.In(0)) {
+
+ if !isBool(predicate.Out(0)) && !isUnknown(predicate.Out(0)) {
+ return v.error(node.Arguments[1], "predicate should return boolean (got %v)", predicate.Out(0).String())
+ }
+ if isUnknown(collection) {
+ return arrayNature
+ }
+ return arrayOf(collection.Elem())
+ }
+ return v.error(node.Arguments[1], "predicate should has one input and one output param")
+
+ case "map":
+ collection := v.visit(node.Arguments[0]).Deref()
+ if !isArray(collection) && !isUnknown(collection) {
+ return v.error(node.Arguments[0], "builtin %v takes only array (got %v)", node.Name, collection)
+ }
+
+ v.begin(collection, scopeVar{"index", integerNature})
+ predicate := v.visit(node.Arguments[1])
+ v.end()
+
+ if isFunc(predicate) &&
+ predicate.NumOut() == 1 &&
+ predicate.NumIn() == 1 && isUnknown(predicate.In(0)) {
+
+ return arrayOf(*predicate.PredicateOut)
+ }
+ return v.error(node.Arguments[1], "predicate should has one input and one output param")
+
+ case "count":
+ collection := v.visit(node.Arguments[0]).Deref()
+ if !isArray(collection) && !isUnknown(collection) {
+ return v.error(node.Arguments[0], "builtin %v takes only array (got %v)", node.Name, collection)
+ }
+
+ if len(node.Arguments) == 1 {
+ return integerNature
+ }
+
+ v.begin(collection)
+ predicate := v.visit(node.Arguments[1])
+ v.end()
+
+ if isFunc(predicate) &&
+ predicate.NumOut() == 1 &&
+ predicate.NumIn() == 1 && isUnknown(predicate.In(0)) {
+ if !isBool(predicate.Out(0)) && !isUnknown(predicate.Out(0)) {
+ return v.error(node.Arguments[1], "predicate should return boolean (got %v)", predicate.Out(0).String())
+ }
+
+ return integerNature
+ }
+ return v.error(node.Arguments[1], "predicate should has one input and one output param")
+
+ case "sum":
+ collection := v.visit(node.Arguments[0]).Deref()
+ if !isArray(collection) && !isUnknown(collection) {
+ return v.error(node.Arguments[0], "builtin %v takes only array (got %v)", node.Name, collection)
+ }
+
+ if len(node.Arguments) == 2 {
+ v.begin(collection)
+ predicate := v.visit(node.Arguments[1])
+ v.end()
+
+ if isFunc(predicate) &&
+ predicate.NumOut() == 1 &&
+ predicate.NumIn() == 1 && isUnknown(predicate.In(0)) {
+ return predicate.Out(0)
+ }
+ } else {
+ if isUnknown(collection) {
+ return unknown
+ }
+ return collection.Elem()
+ }
+
+ case "find", "findLast":
+ collection := v.visit(node.Arguments[0]).Deref()
+ if !isArray(collection) && !isUnknown(collection) {
+ return v.error(node.Arguments[0], "builtin %v takes only array (got %v)", node.Name, collection)
+ }
+
+ v.begin(collection)
+ predicate := v.visit(node.Arguments[1])
+ v.end()
+
+ if isFunc(predicate) &&
+ predicate.NumOut() == 1 &&
+ predicate.NumIn() == 1 && isUnknown(predicate.In(0)) {
+
+ if !isBool(predicate.Out(0)) && !isUnknown(predicate.Out(0)) {
+ return v.error(node.Arguments[1], "predicate should return boolean (got %v)", predicate.Out(0).String())
+ }
+ if isUnknown(collection) {
+ return unknown
+ }
+ return collection.Elem()
+ }
+ return v.error(node.Arguments[1], "predicate should has one input and one output param")
+
+ case "findIndex", "findLastIndex":
+ collection := v.visit(node.Arguments[0]).Deref()
+ if !isArray(collection) && !isUnknown(collection) {
+ return v.error(node.Arguments[0], "builtin %v takes only array (got %v)", node.Name, collection)
+ }
+
+ v.begin(collection)
+ predicate := v.visit(node.Arguments[1])
+ v.end()
+
+ if isFunc(predicate) &&
+ predicate.NumOut() == 1 &&
+ predicate.NumIn() == 1 && isUnknown(predicate.In(0)) {
+
+ if !isBool(predicate.Out(0)) && !isUnknown(predicate.Out(0)) {
+ return v.error(node.Arguments[1], "predicate should return boolean (got %v)", predicate.Out(0).String())
+ }
+ return integerNature
+ }
+ return v.error(node.Arguments[1], "predicate should has one input and one output param")
+
+ case "groupBy":
+ collection := v.visit(node.Arguments[0]).Deref()
+ if !isArray(collection) && !isUnknown(collection) {
+ return v.error(node.Arguments[0], "builtin %v takes only array (got %v)", node.Name, collection)
+ }
+
+ v.begin(collection)
+ predicate := v.visit(node.Arguments[1])
+ v.end()
+
+ if isFunc(predicate) &&
+ predicate.NumOut() == 1 &&
+ predicate.NumIn() == 1 && isUnknown(predicate.In(0)) {
+
+ groups := arrayOf(collection.Elem())
+ return Nature{Type: reflect.TypeOf(map[any][]any{}), ArrayOf: &groups}
+ }
+ return v.error(node.Arguments[1], "predicate should has one input and one output param")
+
+ case "sortBy":
+ collection := v.visit(node.Arguments[0]).Deref()
+ if !isArray(collection) && !isUnknown(collection) {
+ return v.error(node.Arguments[0], "builtin %v takes only array (got %v)", node.Name, collection)
+ }
+
+ v.begin(collection)
+ predicate := v.visit(node.Arguments[1])
+ v.end()
+
+ if len(node.Arguments) == 3 {
+ _ = v.visit(node.Arguments[2])
+ }
+
+ if isFunc(predicate) &&
+ predicate.NumOut() == 1 &&
+ predicate.NumIn() == 1 && isUnknown(predicate.In(0)) {
+
+ return collection
+ }
+ return v.error(node.Arguments[1], "predicate should has one input and one output param")
+
+ case "reduce":
+ collection := v.visit(node.Arguments[0]).Deref()
+ if !isArray(collection) && !isUnknown(collection) {
+ return v.error(node.Arguments[0], "builtin %v takes only array (got %v)", node.Name, collection)
+ }
+
+ v.begin(collection, scopeVar{"index", integerNature}, scopeVar{"acc", unknown})
+ predicate := v.visit(node.Arguments[1])
+ v.end()
+
+ if len(node.Arguments) == 3 {
+ _ = v.visit(node.Arguments[2])
+ }
+
+ if isFunc(predicate) && predicate.NumOut() == 1 {
+ return *predicate.PredicateOut
+ }
+ return v.error(node.Arguments[1], "predicate should has two input and one output param")
+
+ }
+
+ if id, ok := builtin.Index[node.Name]; ok {
+ switch node.Name {
+ case "get":
+ return v.checkBuiltinGet(node)
+ }
+ return v.checkFunction(builtin.Builtins[id], node, node.Arguments)
+ }
+
+ return v.error(node, "unknown builtin %v", node.Name)
+}
+
+type scopeVar struct {
+ varName string
+ varNature Nature
+}
+
+func (v *checker) begin(collectionNature Nature, vars ...scopeVar) {
+ scope := predicateScope{collection: collectionNature, vars: make(map[string]Nature)}
+ for _, v := range vars {
+ scope.vars[v.varName] = v.varNature
+ }
+ v.predicateScopes = append(v.predicateScopes, scope)
+}
+
+func (v *checker) end() {
+ v.predicateScopes = v.predicateScopes[:len(v.predicateScopes)-1]
+}
+
+func (v *checker) checkBuiltinGet(node *ast.BuiltinNode) Nature {
+ if len(node.Arguments) != 2 {
+ return v.error(node, "invalid number of arguments (expected 2, got %d)", len(node.Arguments))
+ }
+
+ base := v.visit(node.Arguments[0])
+ prop := v.visit(node.Arguments[1])
+
+ if id, ok := node.Arguments[0].(*ast.IdentifierNode); ok && id.Value == "$env" {
+ if s, ok := node.Arguments[1].(*ast.StringNode); ok {
+ if nt, ok := v.config.Env.Get(s.Value); ok {
+ return nt
+ }
+ }
+ return unknown
+ }
+
+ if isUnknown(base) {
+ return unknown
+ }
+
+ switch base.Kind() {
+ case reflect.Slice, reflect.Array:
+ if !isInteger(prop) && !isUnknown(prop) {
+ return v.error(node.Arguments[1], "non-integer slice index %s", prop)
+ }
+ return base.Elem()
+ case reflect.Map:
+ if !prop.AssignableTo(base.Key()) && !isUnknown(prop) {
+ return v.error(node.Arguments[1], "cannot use %s to get an element from %s", prop, base)
+ }
+ return base.Elem()
+ }
+ return v.error(node.Arguments[0], "type %v does not support indexing", base)
+}
+
+func (v *checker) checkFunction(f *builtin.Function, node ast.Node, arguments []ast.Node) Nature {
+ if f.Validate != nil {
+ args := make([]reflect.Type, len(arguments))
+ for i, arg := range arguments {
+ argNature := v.visit(arg)
+ if isUnknown(argNature) {
+ args[i] = anyType
+ } else {
+ args[i] = argNature.Type
+ }
+ }
+ t, err := f.Validate(args)
+ if err != nil {
+ return v.error(node, "%v", err)
+ }
+ return Nature{Type: t}
+ } else if len(f.Types) == 0 {
+ nt, err := v.checkArguments(f.Name, Nature{Type: f.Type()}, arguments, node)
+ if err != nil {
+ if v.err == nil {
+ v.err = err
+ }
+ return unknown
+ }
+ // No type was specified, so we assume the function returns any.
+ return nt
+ }
+ var lastErr *file.Error
+ for _, t := range f.Types {
+ outNature, err := v.checkArguments(f.Name, Nature{Type: t}, arguments, node)
+ if err != nil {
+ lastErr = err
+ continue
+ }
+
+ // As we found the correct function overload, we can stop the loop.
+ // Also, we need to set the correct nature of the callee so compiler,
+ // can correctly handle OpDeref opcode.
+ if callNode, ok := node.(*ast.CallNode); ok {
+ callNode.Callee.SetType(t)
+ }
+
+ return outNature
+ }
+ if lastErr != nil {
+ if v.err == nil {
+ v.err = lastErr
+ }
+ return unknown
+ }
+
+ return v.error(node, "no matching overload for %v", f.Name)
+}
+
+func (v *checker) checkArguments(
+ name string,
+ fn Nature,
+ arguments []ast.Node,
+ node ast.Node,
+) (Nature, *file.Error) {
+ if isUnknown(fn) {
+ return unknown, nil
+ }
+
+ if fn.NumOut() == 0 {
+ return unknown, &file.Error{
+ Location: node.Location(),
+ Message: fmt.Sprintf("func %v doesn't return value", name),
+ }
+ }
+ if numOut := fn.NumOut(); numOut > 2 {
+ return unknown, &file.Error{
+ Location: node.Location(),
+ Message: fmt.Sprintf("func %v returns more then two values", name),
+ }
+ }
+
+ // If func is method on an env, first argument should be a receiver,
+ // and actual arguments less than fnNumIn by one.
+ fnNumIn := fn.NumIn()
+ if fn.Method { // TODO: Move subtraction to the Nature.NumIn() and Nature.In() methods.
+ fnNumIn--
+ }
+ // Skip first argument in case of the receiver.
+ fnInOffset := 0
+ if fn.Method {
+ fnInOffset = 1
+ }
+
+ var err *file.Error
+ if fn.IsVariadic() {
+ if len(arguments) < fnNumIn-1 {
+ err = &file.Error{
+ Location: node.Location(),
+ Message: fmt.Sprintf("not enough arguments to call %v", name),
+ }
+ }
+ } else {
+ if len(arguments) > fnNumIn {
+ err = &file.Error{
+ Location: node.Location(),
+ Message: fmt.Sprintf("too many arguments to call %v", name),
+ }
+ }
+ if len(arguments) < fnNumIn {
+ err = &file.Error{
+ Location: node.Location(),
+ Message: fmt.Sprintf("not enough arguments to call %v", name),
+ }
+ }
+ }
+
+ if err != nil {
+ // If we have an error, we should still visit all arguments to
+ // type check them, as a patch can fix the error later.
+ for _, arg := range arguments {
+ _ = v.visit(arg)
+ }
+ return fn.Out(0), err
+ }
+
+ for i, arg := range arguments {
+ argNature := v.visit(arg)
+
+ var in Nature
+ if fn.IsVariadic() && i >= fnNumIn-1 {
+ // For variadic arguments fn(xs ...int), go replaces type of xs (int) with ([]int).
+ // As we compare arguments one by one, we need underling type.
+ in = fn.In(fn.NumIn() - 1).Elem()
+ } else {
+ in = fn.In(i + fnInOffset)
+ }
+
+ if isFloat(in) && isInteger(argNature) {
+ traverseAndReplaceIntegerNodesWithFloatNodes(&arguments[i], in)
+ continue
+ }
+
+ if isInteger(in) && isInteger(argNature) && argNature.Kind() != in.Kind() {
+ traverseAndReplaceIntegerNodesWithIntegerNodes(&arguments[i], in)
+ continue
+ }
+
+ if isNil(argNature) {
+ if in.Kind() == reflect.Ptr || in.Kind() == reflect.Interface {
+ continue
+ }
+ return unknown, &file.Error{
+ Location: arg.Location(),
+ Message: fmt.Sprintf("cannot use nil as argument (type %s) to call %v", in, name),
+ }
+ }
+
+ // Check if argument is assignable to the function input type.
+ // We check original type (like *time.Time), not dereferenced type,
+ // as function input type can be pointer to a struct.
+ assignable := argNature.AssignableTo(in)
+
+ // We also need to check if dereference arg type is assignable to the function input type.
+ // For example, func(int) and argument *int. In this case we will add OpDeref to the argument,
+ // so we can call the function with *int argument.
+ assignable = assignable || argNature.Deref().AssignableTo(in)
+
+ if !assignable && !isUnknown(argNature) {
+ return unknown, &file.Error{
+ Location: arg.Location(),
+ Message: fmt.Sprintf("cannot use %s as argument (type %s) to call %v ", argNature, in, name),
+ }
+ }
+ }
+
+ return fn.Out(0), nil
+}
+
+func traverseAndReplaceIntegerNodesWithFloatNodes(node *ast.Node, newNature Nature) {
+ switch (*node).(type) {
+ case *ast.IntegerNode:
+ *node = &ast.FloatNode{Value: float64((*node).(*ast.IntegerNode).Value)}
+ (*node).SetType(newNature.Type)
+ case *ast.UnaryNode:
+ unaryNode := (*node).(*ast.UnaryNode)
+ traverseAndReplaceIntegerNodesWithFloatNodes(&unaryNode.Node, newNature)
+ case *ast.BinaryNode:
+ binaryNode := (*node).(*ast.BinaryNode)
+ switch binaryNode.Operator {
+ case "+", "-", "*":
+ traverseAndReplaceIntegerNodesWithFloatNodes(&binaryNode.Left, newNature)
+ traverseAndReplaceIntegerNodesWithFloatNodes(&binaryNode.Right, newNature)
+ }
+ }
+}
+
+func traverseAndReplaceIntegerNodesWithIntegerNodes(node *ast.Node, newNature Nature) {
+ switch (*node).(type) {
+ case *ast.IntegerNode:
+ (*node).SetType(newNature.Type)
+ case *ast.UnaryNode:
+ (*node).SetType(newNature.Type)
+ unaryNode := (*node).(*ast.UnaryNode)
+ traverseAndReplaceIntegerNodesWithIntegerNodes(&unaryNode.Node, newNature)
+ case *ast.BinaryNode:
+ // TODO: Binary node return type is dependent on the type of the operands. We can't just change the type of the node.
+ binaryNode := (*node).(*ast.BinaryNode)
+ switch binaryNode.Operator {
+ case "+", "-", "*":
+ traverseAndReplaceIntegerNodesWithIntegerNodes(&binaryNode.Left, newNature)
+ traverseAndReplaceIntegerNodesWithIntegerNodes(&binaryNode.Right, newNature)
+ }
+ }
+}
+
+func (v *checker) PredicateNode(node *ast.PredicateNode) Nature {
+ nt := v.visit(node.Node)
+ var out []reflect.Type
+ if isUnknown(nt) {
+ out = append(out, anyType)
+ } else if !isNil(nt) {
+ out = append(out, nt.Type)
+ }
+ return Nature{
+ Type: reflect.FuncOf([]reflect.Type{anyType}, out, false),
+ PredicateOut: &nt,
+ }
+}
+
+func (v *checker) PointerNode(node *ast.PointerNode) Nature {
+ if len(v.predicateScopes) == 0 {
+ return v.error(node, "cannot use pointer accessor outside predicate")
+ }
+ scope := v.predicateScopes[len(v.predicateScopes)-1]
+ if node.Name == "" {
+ if isUnknown(scope.collection) {
+ return unknown
+ }
+ switch scope.collection.Kind() {
+ case reflect.Array, reflect.Slice:
+ return scope.collection.Elem()
+ }
+ return v.error(node, "cannot use %v as array", scope)
+ }
+ if scope.vars != nil {
+ if t, ok := scope.vars[node.Name]; ok {
+ return t
+ }
+ }
+ return v.error(node, "unknown pointer #%v", node.Name)
+}
+
+func (v *checker) VariableDeclaratorNode(node *ast.VariableDeclaratorNode) Nature {
+ if _, ok := v.config.Env.Get(node.Name); ok {
+ return v.error(node, "cannot redeclare %v", node.Name)
+ }
+ if _, ok := v.config.Functions[node.Name]; ok {
+ return v.error(node, "cannot redeclare function %v", node.Name)
+ }
+ if _, ok := v.config.Builtins[node.Name]; ok {
+ return v.error(node, "cannot redeclare builtin %v", node.Name)
+ }
+ if _, ok := v.lookupVariable(node.Name); ok {
+ return v.error(node, "cannot redeclare variable %v", node.Name)
+ }
+ varNature := v.visit(node.Value)
+ v.varScopes = append(v.varScopes, varScope{node.Name, varNature})
+ exprNature := v.visit(node.Expr)
+ v.varScopes = v.varScopes[:len(v.varScopes)-1]
+ return exprNature
+}
+
+func (v *checker) SequenceNode(node *ast.SequenceNode) Nature {
+ if len(node.Nodes) == 0 {
+ return v.error(node, "empty sequence expression")
+ }
+ var last Nature
+ for _, node := range node.Nodes {
+ last = v.visit(node)
+ }
+ return last
+}
+
+func (v *checker) lookupVariable(name string) (varScope, bool) {
+ for i := len(v.varScopes) - 1; i >= 0; i-- {
+ if v.varScopes[i].name == name {
+ return v.varScopes[i], true
+ }
+ }
+ return varScope{}, false
+}
+
+func (v *checker) ConditionalNode(node *ast.ConditionalNode) Nature {
+ c := v.visit(node.Cond)
+ if !isBool(c) && !isUnknown(c) {
+ return v.error(node.Cond, "non-bool expression (type %v) used as condition", c)
+ }
+
+ t1 := v.visit(node.Exp1)
+ t2 := v.visit(node.Exp2)
+
+ if isNil(t1) && !isNil(t2) {
+ return t2
+ }
+ if !isNil(t1) && isNil(t2) {
+ return t1
+ }
+ if isNil(t1) && isNil(t2) {
+ return nilNature
+ }
+ if t1.AssignableTo(t2) {
+ return t1
+ }
+ return unknown
+}
+
+func (v *checker) ArrayNode(node *ast.ArrayNode) Nature {
+ var prev Nature
+ allElementsAreSameType := true
+ for i, node := range node.Nodes {
+ curr := v.visit(node)
+ if i > 0 {
+ if curr.Kind() != prev.Kind() {
+ allElementsAreSameType = false
+ }
+ }
+ prev = curr
+ }
+ if allElementsAreSameType {
+ return arrayOf(prev)
+ }
+ return arrayNature
+}
+
+func (v *checker) MapNode(node *ast.MapNode) Nature {
+ for _, pair := range node.Pairs {
+ v.visit(pair)
+ }
+ return mapNature
+}
+
+func (v *checker) PairNode(node *ast.PairNode) Nature {
+ v.visit(node.Key)
+ v.visit(node.Value)
+ return nilNature
+}
diff --git a/vendor/github.com/expr-lang/expr/checker/info.go b/vendor/github.com/expr-lang/expr/checker/info.go
new file mode 100644
index 0000000..f1cc92e
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/checker/info.go
@@ -0,0 +1,129 @@
+package checker
+
+import (
+ "reflect"
+
+ "github.com/expr-lang/expr/ast"
+ . "github.com/expr-lang/expr/checker/nature"
+ "github.com/expr-lang/expr/vm"
+)
+
+func FieldIndex(env Nature, node ast.Node) (bool, []int, string) {
+ switch n := node.(type) {
+ case *ast.IdentifierNode:
+ if env.Kind() == reflect.Struct {
+ if field, ok := env.Get(n.Value); ok && len(field.FieldIndex) > 0 {
+ return true, field.FieldIndex, n.Value
+ }
+ }
+ case *ast.MemberNode:
+ base := n.Node.Nature()
+ base = base.Deref()
+ if base.Kind() == reflect.Struct {
+ if prop, ok := n.Property.(*ast.StringNode); ok {
+ name := prop.Value
+ if field, ok := base.FieldByName(name); ok {
+ return true, field.FieldIndex, name
+ }
+ }
+ }
+ }
+ return false, nil, ""
+}
+
+func MethodIndex(env Nature, node ast.Node) (bool, int, string) {
+ switch n := node.(type) {
+ case *ast.IdentifierNode:
+ if env.Kind() == reflect.Struct {
+ if m, ok := env.Get(n.Value); ok {
+ return m.Method, m.MethodIndex, n.Value
+ }
+ }
+ case *ast.MemberNode:
+ if name, ok := n.Property.(*ast.StringNode); ok {
+ base := n.Node.Type()
+ if base != nil && base.Kind() != reflect.Interface {
+ if m, ok := base.MethodByName(name.Value); ok {
+ return true, m.Index, name.Value
+ }
+ }
+ }
+ }
+ return false, 0, ""
+}
+
+func TypedFuncIndex(fn reflect.Type, method bool) (int, bool) {
+ if fn == nil {
+ return 0, false
+ }
+ if fn.Kind() != reflect.Func {
+ return 0, false
+ }
+ // OnCallTyped doesn't work for functions with variadic arguments.
+ if fn.IsVariadic() {
+ return 0, false
+ }
+ // OnCallTyped doesn't work named function, like `type MyFunc func() int`.
+ if fn.PkgPath() != "" { // If PkgPath() is not empty, it means that function is named.
+ return 0, false
+ }
+
+ fnNumIn := fn.NumIn()
+ fnInOffset := 0
+ if method {
+ fnNumIn--
+ fnInOffset = 1
+ }
+
+funcTypes:
+ for i := range vm.FuncTypes {
+ if i == 0 {
+ continue
+ }
+ typed := reflect.ValueOf(vm.FuncTypes[i]).Elem().Type()
+ if typed.Kind() != reflect.Func {
+ continue
+ }
+ if typed.NumOut() != fn.NumOut() {
+ continue
+ }
+ for j := 0; j < typed.NumOut(); j++ {
+ if typed.Out(j) != fn.Out(j) {
+ continue funcTypes
+ }
+ }
+ if typed.NumIn() != fnNumIn {
+ continue
+ }
+ for j := 0; j < typed.NumIn(); j++ {
+ if typed.In(j) != fn.In(j+fnInOffset) {
+ continue funcTypes
+ }
+ }
+ return i, true
+ }
+ return 0, false
+}
+
+func IsFastFunc(fn reflect.Type, method bool) bool {
+ if fn == nil {
+ return false
+ }
+ if fn.Kind() != reflect.Func {
+ return false
+ }
+ numIn := 1
+ if method {
+ numIn = 2
+ }
+ if fn.IsVariadic() &&
+ fn.NumIn() == numIn &&
+ fn.NumOut() == 1 &&
+ fn.Out(0).Kind() == reflect.Interface {
+ rest := fn.In(fn.NumIn() - 1) // function has only one param for functions and two for methods
+ if kind(rest) == reflect.Slice && rest.Elem().Kind() == reflect.Interface {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/expr-lang/expr/checker/nature/nature.go b/vendor/github.com/expr-lang/expr/checker/nature/nature.go
new file mode 100644
index 0000000..993c9fc
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/checker/nature/nature.go
@@ -0,0 +1,261 @@
+package nature
+
+import (
+ "reflect"
+
+ "github.com/expr-lang/expr/builtin"
+ "github.com/expr-lang/expr/internal/deref"
+)
+
+var (
+ unknown = Nature{}
+)
+
+type Nature struct {
+ Type reflect.Type // Type of the value. If nil, then value is unknown.
+ Func *builtin.Function // Used to pass function type from callee to CallNode.
+ ArrayOf *Nature // Elem nature of array type (usually Type is []any, but ArrayOf can be any nature).
+ PredicateOut *Nature // Out nature of predicate.
+ Fields map[string]Nature // Fields of map type.
+ DefaultMapValue *Nature // Default value of map type.
+ Strict bool // If map is types.StrictMap.
+ Nil bool // If value is nil.
+ Method bool // If value retrieved from method. Usually used to determine amount of in arguments.
+ MethodIndex int // Index of method in type.
+ FieldIndex []int // Index of field in type.
+}
+
+func (n Nature) IsAny() bool {
+ return n.Kind() == reflect.Interface && n.NumMethods() == 0
+}
+
+func (n Nature) IsUnknown() bool {
+ switch {
+ case n.Type == nil && !n.Nil:
+ return true
+ case n.IsAny():
+ return true
+ }
+ return false
+}
+
+func (n Nature) String() string {
+ if n.Type != nil {
+ return n.Type.String()
+ }
+ return "unknown"
+}
+
+func (n Nature) Deref() Nature {
+ if n.Type != nil {
+ n.Type = deref.Type(n.Type)
+ }
+ return n
+}
+
+func (n Nature) Kind() reflect.Kind {
+ if n.Type != nil {
+ return n.Type.Kind()
+ }
+ return reflect.Invalid
+}
+
+func (n Nature) Key() Nature {
+ if n.Kind() == reflect.Map {
+ return Nature{Type: n.Type.Key()}
+ }
+ return unknown
+}
+
+func (n Nature) Elem() Nature {
+ switch n.Kind() {
+ case reflect.Ptr:
+ return Nature{Type: n.Type.Elem()}
+ case reflect.Map:
+ if n.DefaultMapValue != nil {
+ return *n.DefaultMapValue
+ }
+ return Nature{Type: n.Type.Elem()}
+ case reflect.Array, reflect.Slice:
+ if n.ArrayOf != nil {
+ return *n.ArrayOf
+ }
+ return Nature{Type: n.Type.Elem()}
+ }
+ return unknown
+}
+
+func (n Nature) AssignableTo(nt Nature) bool {
+ if n.Nil {
+ // Untyped nil is assignable to any interface, but implements only the empty interface.
+ if nt.IsAny() {
+ return true
+ }
+ }
+ if n.Type == nil || nt.Type == nil {
+ return false
+ }
+ return n.Type.AssignableTo(nt.Type)
+}
+
+func (n Nature) NumMethods() int {
+ if n.Type == nil {
+ return 0
+ }
+ return n.Type.NumMethod()
+}
+
+func (n Nature) MethodByName(name string) (Nature, bool) {
+ if n.Type == nil {
+ return unknown, false
+ }
+ method, ok := n.Type.MethodByName(name)
+ if !ok {
+ return unknown, false
+ }
+
+ if n.Type.Kind() == reflect.Interface {
+ // In case of interface type method will not have a receiver,
+ // and to prevent checker decreasing numbers of in arguments
+ // return method type as not method (second argument is false).
+
+ // Also, we can not use m.Index here, because it will be
+ // different indexes for different types which implement
+ // the same interface.
+ return Nature{Type: method.Type}, true
+ } else {
+ return Nature{
+ Type: method.Type,
+ Method: true,
+ MethodIndex: method.Index,
+ }, true
+ }
+}
+
+func (n Nature) NumIn() int {
+ if n.Type == nil {
+ return 0
+ }
+ return n.Type.NumIn()
+}
+
+func (n Nature) In(i int) Nature {
+ if n.Type == nil {
+ return unknown
+ }
+ return Nature{Type: n.Type.In(i)}
+}
+
+func (n Nature) NumOut() int {
+ if n.Type == nil {
+ return 0
+ }
+ return n.Type.NumOut()
+}
+
+func (n Nature) Out(i int) Nature {
+ if n.Type == nil {
+ return unknown
+ }
+ return Nature{Type: n.Type.Out(i)}
+}
+
+func (n Nature) IsVariadic() bool {
+ if n.Type == nil {
+ return false
+ }
+ return n.Type.IsVariadic()
+}
+
+func (n Nature) FieldByName(name string) (Nature, bool) {
+ if n.Type == nil {
+ return unknown, false
+ }
+ field, ok := fetchField(n.Type, name)
+ return Nature{Type: field.Type, FieldIndex: field.Index}, ok
+}
+
+func (n Nature) PkgPath() string {
+ if n.Type == nil {
+ return ""
+ }
+ return n.Type.PkgPath()
+}
+
+func (n Nature) IsFastMap() bool {
+ if n.Type == nil {
+ return false
+ }
+ if n.Type.Kind() == reflect.Map &&
+ n.Type.Key().Kind() == reflect.String &&
+ n.Type.Elem().Kind() == reflect.Interface {
+ return true
+ }
+ return false
+}
+
+func (n Nature) Get(name string) (Nature, bool) {
+ if n.Type == nil {
+ return unknown, false
+ }
+
+ if m, ok := n.MethodByName(name); ok {
+ return m, true
+ }
+
+ t := deref.Type(n.Type)
+
+ switch t.Kind() {
+ case reflect.Struct:
+ if f, ok := fetchField(t, name); ok {
+ return Nature{
+ Type: f.Type,
+ FieldIndex: f.Index,
+ }, true
+ }
+ case reflect.Map:
+ if f, ok := n.Fields[name]; ok {
+ return f, true
+ }
+ }
+ return unknown, false
+}
+
+func (n Nature) All() map[string]Nature {
+ table := make(map[string]Nature)
+
+ if n.Type == nil {
+ return table
+ }
+
+ for i := 0; i < n.Type.NumMethod(); i++ {
+ method := n.Type.Method(i)
+ table[method.Name] = Nature{
+ Type: method.Type,
+ Method: true,
+ MethodIndex: method.Index,
+ }
+ }
+
+ t := deref.Type(n.Type)
+
+ switch t.Kind() {
+ case reflect.Struct:
+ for name, nt := range StructFields(t) {
+ if _, ok := table[name]; ok {
+ continue
+ }
+ table[name] = nt
+ }
+
+ case reflect.Map:
+ for key, nt := range n.Fields {
+ if _, ok := table[key]; ok {
+ continue
+ }
+ table[key] = nt
+ }
+ }
+
+ return table
+}
diff --git a/vendor/github.com/expr-lang/expr/checker/nature/utils.go b/vendor/github.com/expr-lang/expr/checker/nature/utils.go
new file mode 100644
index 0000000..c242f91
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/checker/nature/utils.go
@@ -0,0 +1,76 @@
+package nature
+
+import (
+ "reflect"
+
+ "github.com/expr-lang/expr/internal/deref"
+)
+
+func fieldName(field reflect.StructField) string {
+ if taggedName := field.Tag.Get("expr"); taggedName != "" {
+ return taggedName
+ }
+ return field.Name
+}
+
+func fetchField(t reflect.Type, name string) (reflect.StructField, bool) {
+ // First check all structs fields.
+ for i := 0; i < t.NumField(); i++ {
+ field := t.Field(i)
+ // Search all fields, even embedded structs.
+ if fieldName(field) == name {
+ return field, true
+ }
+ }
+
+ // Second check fields of embedded structs.
+ for i := 0; i < t.NumField(); i++ {
+ anon := t.Field(i)
+ if anon.Anonymous {
+ anonType := anon.Type
+ if anonType.Kind() == reflect.Pointer {
+ anonType = anonType.Elem()
+ }
+ if field, ok := fetchField(anonType, name); ok {
+ field.Index = append(anon.Index, field.Index...)
+ return field, true
+ }
+ }
+ }
+
+ return reflect.StructField{}, false
+}
+
+func StructFields(t reflect.Type) map[string]Nature {
+ table := make(map[string]Nature)
+
+ t = deref.Type(t)
+ if t == nil {
+ return table
+ }
+
+ switch t.Kind() {
+ case reflect.Struct:
+ for i := 0; i < t.NumField(); i++ {
+ f := t.Field(i)
+
+ if f.Anonymous {
+ for name, typ := range StructFields(f.Type) {
+ if _, ok := table[name]; ok {
+ continue
+ }
+ typ.FieldIndex = append(f.Index, typ.FieldIndex...)
+ table[name] = typ
+ }
+ }
+
+ table[fieldName(f)] = Nature{
+ Type: f.Type,
+ FieldIndex: f.Index,
+ }
+
+ }
+ }
+
+ return table
+}
diff --git a/vendor/github.com/expr-lang/expr/checker/types.go b/vendor/github.com/expr-lang/expr/checker/types.go
new file mode 100644
index 0000000..09896de
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/checker/types.go
@@ -0,0 +1,190 @@
+package checker
+
+import (
+ "reflect"
+ "time"
+
+ . "github.com/expr-lang/expr/checker/nature"
+)
+
+var (
+ unknown = Nature{}
+ nilNature = Nature{Nil: true}
+ boolNature = Nature{Type: reflect.TypeOf(true)}
+ integerNature = Nature{Type: reflect.TypeOf(0)}
+ floatNature = Nature{Type: reflect.TypeOf(float64(0))}
+ stringNature = Nature{Type: reflect.TypeOf("")}
+ arrayNature = Nature{Type: reflect.TypeOf([]any{})}
+ mapNature = Nature{Type: reflect.TypeOf(map[string]any{})}
+ timeNature = Nature{Type: reflect.TypeOf(time.Time{})}
+ durationNature = Nature{Type: reflect.TypeOf(time.Duration(0))}
+)
+
+var (
+ anyType = reflect.TypeOf(new(any)).Elem()
+ timeType = reflect.TypeOf(time.Time{})
+ durationType = reflect.TypeOf(time.Duration(0))
+ arrayType = reflect.TypeOf([]any{})
+)
+
+func arrayOf(nt Nature) Nature {
+ return Nature{
+ Type: arrayType,
+ ArrayOf: &nt,
+ }
+}
+
+func isNil(nt Nature) bool {
+ return nt.Nil
+}
+
+func combined(l, r Nature) Nature {
+ if isUnknown(l) || isUnknown(r) {
+ return unknown
+ }
+ if isFloat(l) || isFloat(r) {
+ return floatNature
+ }
+ return integerNature
+}
+
+func anyOf(nt Nature, fns ...func(Nature) bool) bool {
+ for _, fn := range fns {
+ if fn(nt) {
+ return true
+ }
+ }
+ return false
+}
+
+func or(l, r Nature, fns ...func(Nature) bool) bool {
+ if isUnknown(l) && isUnknown(r) {
+ return true
+ }
+ if isUnknown(l) && anyOf(r, fns...) {
+ return true
+ }
+ if isUnknown(r) && anyOf(l, fns...) {
+ return true
+ }
+ return false
+}
+
+func isUnknown(nt Nature) bool {
+ return nt.IsUnknown()
+}
+
+func isInteger(nt Nature) bool {
+ switch nt.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ fallthrough
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return nt.PkgPath() == ""
+ }
+ return false
+}
+
+func isFloat(nt Nature) bool {
+ switch nt.Kind() {
+ case reflect.Float32, reflect.Float64:
+ return nt.PkgPath() == ""
+ }
+ return false
+}
+
+func isNumber(nt Nature) bool {
+ return isInteger(nt) || isFloat(nt)
+}
+
+func isTime(nt Nature) bool {
+ switch nt.Type {
+ case timeType:
+ return true
+ }
+ return false
+}
+
+func isDuration(nt Nature) bool {
+ switch nt.Type {
+ case durationType:
+ return true
+ }
+ return false
+}
+
+func isBool(nt Nature) bool {
+ switch nt.Kind() {
+ case reflect.Bool:
+ return true
+ }
+ return false
+}
+
+func isString(nt Nature) bool {
+ switch nt.Kind() {
+ case reflect.String:
+ return true
+ }
+ return false
+}
+
+func isArray(nt Nature) bool {
+ switch nt.Kind() {
+ case reflect.Slice, reflect.Array:
+ return true
+ }
+ return false
+}
+
+func isMap(nt Nature) bool {
+ switch nt.Kind() {
+ case reflect.Map:
+ return true
+ }
+ return false
+}
+
+func isStruct(nt Nature) bool {
+ switch nt.Kind() {
+ case reflect.Struct:
+ return true
+ }
+ return false
+}
+
+func isFunc(nt Nature) bool {
+ switch nt.Kind() {
+ case reflect.Func:
+ return true
+ }
+ return false
+}
+
+func kind(t reflect.Type) reflect.Kind {
+ if t == nil {
+ return reflect.Invalid
+ }
+ return t.Kind()
+}
+
+func isComparable(l, r Nature) bool {
+ if isUnknown(l) || isUnknown(r) {
+ return true
+ }
+ if isNil(l) || isNil(r) {
+ return true
+ }
+ if isNumber(l) && isNumber(r) {
+ return true
+ }
+ if isDuration(l) && isDuration(r) {
+ return true
+ }
+ if isTime(l) && isTime(r) {
+ return true
+ }
+ if isArray(l) && isArray(r) {
+ return true
+ }
+ return l.AssignableTo(r)
+}
diff --git a/vendor/github.com/expr-lang/expr/compiler/compiler.go b/vendor/github.com/expr-lang/expr/compiler/compiler.go
new file mode 100644
index 0000000..90e54e5
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/compiler/compiler.go
@@ -0,0 +1,1276 @@
+package compiler
+
+import (
+ "fmt"
+ "math"
+ "reflect"
+ "regexp"
+
+ "github.com/expr-lang/expr/ast"
+ "github.com/expr-lang/expr/builtin"
+ "github.com/expr-lang/expr/checker"
+ . "github.com/expr-lang/expr/checker/nature"
+ "github.com/expr-lang/expr/conf"
+ "github.com/expr-lang/expr/file"
+ "github.com/expr-lang/expr/parser"
+ . "github.com/expr-lang/expr/vm"
+ "github.com/expr-lang/expr/vm/runtime"
+)
+
+const (
+ placeholder = 12345
+)
+
+func Compile(tree *parser.Tree, config *conf.Config) (program *Program, err error) {
+ defer func() {
+ if r := recover(); r != nil {
+ err = fmt.Errorf("%v", r)
+ }
+ }()
+
+ c := &compiler{
+ config: config,
+ locations: make([]file.Location, 0),
+ constantsIndex: make(map[any]int),
+ functionsIndex: make(map[string]int),
+ debugInfo: make(map[string]string),
+ }
+
+ c.compile(tree.Node)
+
+ if c.config != nil {
+ switch c.config.Expect {
+ case reflect.Int:
+ c.emit(OpCast, 0)
+ case reflect.Int64:
+ c.emit(OpCast, 1)
+ case reflect.Float64:
+ c.emit(OpCast, 2)
+ }
+ if c.config.Optimize {
+ c.optimize()
+ }
+ }
+
+ var span *Span
+ if len(c.spans) > 0 {
+ span = c.spans[0]
+ }
+
+ program = NewProgram(
+ tree.Source,
+ tree.Node,
+ c.locations,
+ c.variables,
+ c.constants,
+ c.bytecode,
+ c.arguments,
+ c.functions,
+ c.debugInfo,
+ span,
+ )
+ return
+}
+
+type compiler struct {
+ config *conf.Config
+ locations []file.Location
+ bytecode []Opcode
+ variables int
+ scopes []scope
+ constants []any
+ constantsIndex map[any]int
+ functions []Function
+ functionsIndex map[string]int
+ debugInfo map[string]string
+ nodes []ast.Node
+ spans []*Span
+ chains [][]int
+ arguments []int
+}
+
+type scope struct {
+ variableName string
+ index int
+}
+
+func (c *compiler) nodeParent() ast.Node {
+ if len(c.nodes) > 1 {
+ return c.nodes[len(c.nodes)-2]
+ }
+ return nil
+}
+
+func (c *compiler) emitLocation(loc file.Location, op Opcode, arg int) int {
+ c.bytecode = append(c.bytecode, op)
+ current := len(c.bytecode)
+ c.arguments = append(c.arguments, arg)
+ c.locations = append(c.locations, loc)
+ return current
+}
+
+func (c *compiler) emit(op Opcode, args ...int) int {
+ arg := 0
+ if len(args) > 1 {
+ panic("too many arguments")
+ }
+ if len(args) == 1 {
+ arg = args[0]
+ }
+ var loc file.Location
+ if len(c.nodes) > 0 {
+ loc = c.nodes[len(c.nodes)-1].Location()
+ }
+ return c.emitLocation(loc, op, arg)
+}
+
+func (c *compiler) emitPush(value any) int {
+ return c.emit(OpPush, c.addConstant(value))
+}
+
+func (c *compiler) addConstant(constant any) int {
+ indexable := true
+ hash := constant
+ switch reflect.TypeOf(constant).Kind() {
+ case reflect.Slice, reflect.Map, reflect.Struct, reflect.Func:
+ indexable = false
+ }
+ if field, ok := constant.(*runtime.Field); ok {
+ indexable = true
+ hash = fmt.Sprintf("%v", field)
+ }
+ if method, ok := constant.(*runtime.Method); ok {
+ indexable = true
+ hash = fmt.Sprintf("%v", method)
+ }
+ if indexable {
+ if p, ok := c.constantsIndex[hash]; ok {
+ return p
+ }
+ }
+ c.constants = append(c.constants, constant)
+ p := len(c.constants) - 1
+ if indexable {
+ c.constantsIndex[hash] = p
+ }
+ return p
+}
+
+func (c *compiler) addVariable(name string) int {
+ c.variables++
+ c.debugInfo[fmt.Sprintf("var_%d", c.variables-1)] = name
+ return c.variables - 1
+}
+
+// emitFunction adds builtin.Function.Func to the program.functions and emits call opcode.
+func (c *compiler) emitFunction(fn *builtin.Function, argsLen int) {
+ switch argsLen {
+ case 0:
+ c.emit(OpCall0, c.addFunction(fn.Name, fn.Func))
+ case 1:
+ c.emit(OpCall1, c.addFunction(fn.Name, fn.Func))
+ case 2:
+ c.emit(OpCall2, c.addFunction(fn.Name, fn.Func))
+ case 3:
+ c.emit(OpCall3, c.addFunction(fn.Name, fn.Func))
+ default:
+ c.emit(OpLoadFunc, c.addFunction(fn.Name, fn.Func))
+ c.emit(OpCallN, argsLen)
+ }
+}
+
+// addFunction adds builtin.Function.Func to the program.functions and returns its index.
+func (c *compiler) addFunction(name string, fn Function) int {
+ if fn == nil {
+ panic("function is nil")
+ }
+ if p, ok := c.functionsIndex[name]; ok {
+ return p
+ }
+ p := len(c.functions)
+ c.functions = append(c.functions, fn)
+ c.functionsIndex[name] = p
+ c.debugInfo[fmt.Sprintf("func_%d", p)] = name
+ return p
+}
+
+func (c *compiler) patchJump(placeholder int) {
+ offset := len(c.bytecode) - placeholder
+ c.arguments[placeholder-1] = offset
+}
+
+func (c *compiler) calcBackwardJump(to int) int {
+ return len(c.bytecode) + 1 - to
+}
+
+func (c *compiler) compile(node ast.Node) {
+ c.nodes = append(c.nodes, node)
+ defer func() {
+ c.nodes = c.nodes[:len(c.nodes)-1]
+ }()
+
+ if c.config != nil && c.config.Profile {
+ span := &Span{
+ Name: reflect.TypeOf(node).String(),
+ Expression: node.String(),
+ }
+ if len(c.spans) > 0 {
+ prev := c.spans[len(c.spans)-1]
+ prev.Children = append(prev.Children, span)
+ }
+ c.spans = append(c.spans, span)
+ defer func() {
+ if len(c.spans) > 1 {
+ c.spans = c.spans[:len(c.spans)-1]
+ }
+ }()
+
+ c.emit(OpProfileStart, c.addConstant(span))
+ defer func() {
+ c.emit(OpProfileEnd, c.addConstant(span))
+ }()
+ }
+
+ switch n := node.(type) {
+ case *ast.NilNode:
+ c.NilNode(n)
+ case *ast.IdentifierNode:
+ c.IdentifierNode(n)
+ case *ast.IntegerNode:
+ c.IntegerNode(n)
+ case *ast.FloatNode:
+ c.FloatNode(n)
+ case *ast.BoolNode:
+ c.BoolNode(n)
+ case *ast.StringNode:
+ c.StringNode(n)
+ case *ast.ConstantNode:
+ c.ConstantNode(n)
+ case *ast.UnaryNode:
+ c.UnaryNode(n)
+ case *ast.BinaryNode:
+ c.BinaryNode(n)
+ case *ast.ChainNode:
+ c.ChainNode(n)
+ case *ast.MemberNode:
+ c.MemberNode(n)
+ case *ast.SliceNode:
+ c.SliceNode(n)
+ case *ast.CallNode:
+ c.CallNode(n)
+ case *ast.BuiltinNode:
+ c.BuiltinNode(n)
+ case *ast.PredicateNode:
+ c.PredicateNode(n)
+ case *ast.PointerNode:
+ c.PointerNode(n)
+ case *ast.VariableDeclaratorNode:
+ c.VariableDeclaratorNode(n)
+ case *ast.SequenceNode:
+ c.SequenceNode(n)
+ case *ast.ConditionalNode:
+ c.ConditionalNode(n)
+ case *ast.ArrayNode:
+ c.ArrayNode(n)
+ case *ast.MapNode:
+ c.MapNode(n)
+ case *ast.PairNode:
+ c.PairNode(n)
+ default:
+ panic(fmt.Sprintf("undefined node type (%T)", node))
+ }
+}
+
+func (c *compiler) NilNode(_ *ast.NilNode) {
+ c.emit(OpNil)
+}
+
+func (c *compiler) IdentifierNode(node *ast.IdentifierNode) {
+ if index, ok := c.lookupVariable(node.Value); ok {
+ c.emit(OpLoadVar, index)
+ return
+ }
+ if node.Value == "$env" {
+ c.emit(OpLoadEnv)
+ return
+ }
+
+ var env Nature
+ if c.config != nil {
+ env = c.config.Env
+ }
+
+ if env.IsFastMap() {
+ c.emit(OpLoadFast, c.addConstant(node.Value))
+ } else if ok, index, name := checker.FieldIndex(env, node); ok {
+ c.emit(OpLoadField, c.addConstant(&runtime.Field{
+ Index: index,
+ Path: []string{name},
+ }))
+ } else if ok, index, name := checker.MethodIndex(env, node); ok {
+ c.emit(OpLoadMethod, c.addConstant(&runtime.Method{
+ Name: name,
+ Index: index,
+ }))
+ } else {
+ c.emit(OpLoadConst, c.addConstant(node.Value))
+ }
+}
+
+func (c *compiler) IntegerNode(node *ast.IntegerNode) {
+ t := node.Type()
+ if t == nil {
+ c.emitPush(node.Value)
+ return
+ }
+ switch t.Kind() {
+ case reflect.Float32:
+ c.emitPush(float32(node.Value))
+ case reflect.Float64:
+ c.emitPush(float64(node.Value))
+ case reflect.Int:
+ c.emitPush(node.Value)
+ case reflect.Int8:
+ if node.Value > math.MaxInt8 || node.Value < math.MinInt8 {
+ panic(fmt.Sprintf("constant %d overflows int8", node.Value))
+ }
+ c.emitPush(int8(node.Value))
+ case reflect.Int16:
+ if node.Value > math.MaxInt16 || node.Value < math.MinInt16 {
+ panic(fmt.Sprintf("constant %d overflows int16", node.Value))
+ }
+ c.emitPush(int16(node.Value))
+ case reflect.Int32:
+ if node.Value > math.MaxInt32 || node.Value < math.MinInt32 {
+ panic(fmt.Sprintf("constant %d overflows int32", node.Value))
+ }
+ c.emitPush(int32(node.Value))
+ case reflect.Int64:
+ c.emitPush(int64(node.Value))
+ case reflect.Uint:
+ if node.Value < 0 {
+ panic(fmt.Sprintf("constant %d overflows uint", node.Value))
+ }
+ c.emitPush(uint(node.Value))
+ case reflect.Uint8:
+ if node.Value > math.MaxUint8 || node.Value < 0 {
+ panic(fmt.Sprintf("constant %d overflows uint8", node.Value))
+ }
+ c.emitPush(uint8(node.Value))
+ case reflect.Uint16:
+ if node.Value > math.MaxUint16 || node.Value < 0 {
+ panic(fmt.Sprintf("constant %d overflows uint16", node.Value))
+ }
+ c.emitPush(uint16(node.Value))
+ case reflect.Uint32:
+ if node.Value < 0 {
+ panic(fmt.Sprintf("constant %d overflows uint32", node.Value))
+ }
+ c.emitPush(uint32(node.Value))
+ case reflect.Uint64:
+ if node.Value < 0 {
+ panic(fmt.Sprintf("constant %d overflows uint64", node.Value))
+ }
+ c.emitPush(uint64(node.Value))
+ default:
+ c.emitPush(node.Value)
+ }
+}
+
+func (c *compiler) FloatNode(node *ast.FloatNode) {
+ switch node.Type().Kind() {
+ case reflect.Float32:
+ c.emitPush(float32(node.Value))
+ case reflect.Float64:
+ c.emitPush(node.Value)
+ default:
+ c.emitPush(node.Value)
+ }
+}
+
+func (c *compiler) BoolNode(node *ast.BoolNode) {
+ if node.Value {
+ c.emit(OpTrue)
+ } else {
+ c.emit(OpFalse)
+ }
+}
+
+func (c *compiler) StringNode(node *ast.StringNode) {
+ c.emitPush(node.Value)
+}
+
+func (c *compiler) ConstantNode(node *ast.ConstantNode) {
+ if node.Value == nil {
+ c.emit(OpNil)
+ return
+ }
+ c.emitPush(node.Value)
+}
+
+func (c *compiler) UnaryNode(node *ast.UnaryNode) {
+ c.compile(node.Node)
+ c.derefInNeeded(node.Node)
+
+ switch node.Operator {
+
+ case "!", "not":
+ c.emit(OpNot)
+
+ case "+":
+ // Do nothing
+
+ case "-":
+ c.emit(OpNegate)
+
+ default:
+ panic(fmt.Sprintf("unknown operator (%v)", node.Operator))
+ }
+}
+
+func (c *compiler) BinaryNode(node *ast.BinaryNode) {
+ switch node.Operator {
+ case "==":
+ c.equalBinaryNode(node)
+
+ case "!=":
+ c.equalBinaryNode(node)
+ c.emit(OpNot)
+
+ case "or", "||":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ end := c.emit(OpJumpIfTrue, placeholder)
+ c.emit(OpPop)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.patchJump(end)
+
+ case "and", "&&":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ end := c.emit(OpJumpIfFalse, placeholder)
+ c.emit(OpPop)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.patchJump(end)
+
+ case "<":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.emit(OpLess)
+
+ case ">":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.emit(OpMore)
+
+ case "<=":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.emit(OpLessOrEqual)
+
+ case ">=":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.emit(OpMoreOrEqual)
+
+ case "+":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.emit(OpAdd)
+
+ case "-":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.emit(OpSubtract)
+
+ case "*":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.emit(OpMultiply)
+
+ case "/":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.emit(OpDivide)
+
+ case "%":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.emit(OpModulo)
+
+ case "**", "^":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.emit(OpExponent)
+
+ case "in":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.emit(OpIn)
+
+ case "matches":
+ if str, ok := node.Right.(*ast.StringNode); ok {
+ re, err := regexp.Compile(str.Value)
+ if err != nil {
+ panic(err)
+ }
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.emit(OpMatchesConst, c.addConstant(re))
+ } else {
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.emit(OpMatches)
+ }
+
+ case "contains":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.emit(OpContains)
+
+ case "startsWith":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.emit(OpStartsWith)
+
+ case "endsWith":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.emit(OpEndsWith)
+
+ case "..":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.emit(OpRange)
+
+ case "??":
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ end := c.emit(OpJumpIfNotNil, placeholder)
+ c.emit(OpPop)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+ c.patchJump(end)
+
+ default:
+ panic(fmt.Sprintf("unknown operator (%v)", node.Operator))
+
+ }
+}
+
+func (c *compiler) equalBinaryNode(node *ast.BinaryNode) {
+ l := kind(node.Left.Type())
+ r := kind(node.Right.Type())
+
+ leftIsSimple := isSimpleType(node.Left)
+ rightIsSimple := isSimpleType(node.Right)
+ leftAndRightAreSimple := leftIsSimple && rightIsSimple
+
+ c.compile(node.Left)
+ c.derefInNeeded(node.Left)
+ c.compile(node.Right)
+ c.derefInNeeded(node.Right)
+
+ if l == r && l == reflect.Int && leftAndRightAreSimple {
+ c.emit(OpEqualInt)
+ } else if l == r && l == reflect.String && leftAndRightAreSimple {
+ c.emit(OpEqualString)
+ } else {
+ c.emit(OpEqual)
+ }
+}
+
+func isSimpleType(node ast.Node) bool {
+ if node == nil {
+ return false
+ }
+ t := node.Type()
+ if t == nil {
+ return false
+ }
+ return t.PkgPath() == ""
+}
+
+func (c *compiler) ChainNode(node *ast.ChainNode) {
+ c.chains = append(c.chains, []int{})
+ c.compile(node.Node)
+ for _, ph := range c.chains[len(c.chains)-1] {
+ c.patchJump(ph) // If chain activated jump here (got nit somewhere).
+ }
+ parent := c.nodeParent()
+ if binary, ok := parent.(*ast.BinaryNode); ok && binary.Operator == "??" {
+ // If chain is used in nil coalescing operator, we can omit
+ // nil push at the end of the chain. The ?? operator will
+ // handle it.
+ } else {
+ // We need to put the nil on the stack, otherwise "typed"
+ // nil will be used as a result of the chain.
+ j := c.emit(OpJumpIfNotNil, placeholder)
+ c.emit(OpPop)
+ c.emit(OpNil)
+ c.patchJump(j)
+ }
+ c.chains = c.chains[:len(c.chains)-1]
+}
+
+func (c *compiler) MemberNode(node *ast.MemberNode) {
+ var env Nature
+ if c.config != nil {
+ env = c.config.Env
+ }
+
+ if ok, index, name := checker.MethodIndex(env, node); ok {
+ c.compile(node.Node)
+ c.emit(OpMethod, c.addConstant(&runtime.Method{
+ Name: name,
+ Index: index,
+ }))
+ return
+ }
+ op := OpFetch
+ base := node.Node
+
+ ok, index, nodeName := checker.FieldIndex(env, node)
+ path := []string{nodeName}
+
+ if ok {
+ op = OpFetchField
+ for !node.Optional {
+ if ident, isIdent := base.(*ast.IdentifierNode); isIdent {
+ if ok, identIndex, name := checker.FieldIndex(env, ident); ok {
+ index = append(identIndex, index...)
+ path = append([]string{name}, path...)
+ c.emitLocation(ident.Location(), OpLoadField, c.addConstant(
+ &runtime.Field{Index: index, Path: path},
+ ))
+ return
+ }
+ }
+
+ if member, isMember := base.(*ast.MemberNode); isMember {
+ if ok, memberIndex, name := checker.FieldIndex(env, member); ok {
+ index = append(memberIndex, index...)
+ path = append([]string{name}, path...)
+ node = member
+ base = member.Node
+ } else {
+ break
+ }
+ } else {
+ break
+ }
+ }
+ }
+
+ c.compile(base)
+ // If the field is optional, we need to jump over the fetch operation.
+ // If no ChainNode (none c.chains) is used, do not compile the optional fetch.
+ if node.Optional && len(c.chains) > 0 {
+ ph := c.emit(OpJumpIfNil, placeholder)
+ c.chains[len(c.chains)-1] = append(c.chains[len(c.chains)-1], ph)
+ }
+
+ if op == OpFetch {
+ c.compile(node.Property)
+ c.emit(OpFetch)
+ } else {
+ c.emitLocation(node.Location(), op, c.addConstant(
+ &runtime.Field{Index: index, Path: path},
+ ))
+ }
+}
+
+func (c *compiler) SliceNode(node *ast.SliceNode) {
+ c.compile(node.Node)
+ if node.To != nil {
+ c.compile(node.To)
+ } else {
+ c.emit(OpLen)
+ }
+ if node.From != nil {
+ c.compile(node.From)
+ } else {
+ c.emitPush(0)
+ }
+ c.emit(OpSlice)
+}
+
+func (c *compiler) CallNode(node *ast.CallNode) {
+ fn := node.Callee.Type()
+ if fn.Kind() == reflect.Func {
+ fnInOffset := 0
+ fnNumIn := fn.NumIn()
+ switch callee := node.Callee.(type) {
+ case *ast.MemberNode:
+ if prop, ok := callee.Property.(*ast.StringNode); ok {
+ if _, ok = callee.Node.Type().MethodByName(prop.Value); ok && callee.Node.Type().Kind() != reflect.Interface {
+ fnInOffset = 1
+ fnNumIn--
+ }
+ }
+ case *ast.IdentifierNode:
+ if t, ok := c.config.Env.MethodByName(callee.Value); ok && t.Method {
+ fnInOffset = 1
+ fnNumIn--
+ }
+ }
+ for i, arg := range node.Arguments {
+ c.compile(arg)
+
+ var in reflect.Type
+ if fn.IsVariadic() && i >= fnNumIn-1 {
+ in = fn.In(fn.NumIn() - 1).Elem()
+ } else {
+ in = fn.In(i + fnInOffset)
+ }
+
+ c.derefParam(in, arg)
+ }
+ } else {
+ for _, arg := range node.Arguments {
+ c.compile(arg)
+ }
+ }
+
+ if ident, ok := node.Callee.(*ast.IdentifierNode); ok {
+ if c.config != nil {
+ if fn, ok := c.config.Functions[ident.Value]; ok {
+ c.emitFunction(fn, len(node.Arguments))
+ return
+ }
+ }
+ }
+ c.compile(node.Callee)
+
+ isMethod, _, _ := checker.MethodIndex(c.config.Env, node.Callee)
+ if index, ok := checker.TypedFuncIndex(node.Callee.Type(), isMethod); ok {
+ c.emit(OpCallTyped, index)
+ return
+ } else if checker.IsFastFunc(node.Callee.Type(), isMethod) {
+ c.emit(OpCallFast, len(node.Arguments))
+ } else {
+ c.emit(OpCall, len(node.Arguments))
+ }
+}
+
+func (c *compiler) BuiltinNode(node *ast.BuiltinNode) {
+ switch node.Name {
+ case "all":
+ c.compile(node.Arguments[0])
+ c.derefInNeeded(node.Arguments[0])
+ c.emit(OpBegin)
+ var loopBreak int
+ c.emitLoop(func() {
+ c.compile(node.Arguments[1])
+ loopBreak = c.emit(OpJumpIfFalse, placeholder)
+ c.emit(OpPop)
+ })
+ c.emit(OpTrue)
+ c.patchJump(loopBreak)
+ c.emit(OpEnd)
+ return
+
+ case "none":
+ c.compile(node.Arguments[0])
+ c.derefInNeeded(node.Arguments[0])
+ c.emit(OpBegin)
+ var loopBreak int
+ c.emitLoop(func() {
+ c.compile(node.Arguments[1])
+ c.emit(OpNot)
+ loopBreak = c.emit(OpJumpIfFalse, placeholder)
+ c.emit(OpPop)
+ })
+ c.emit(OpTrue)
+ c.patchJump(loopBreak)
+ c.emit(OpEnd)
+ return
+
+ case "any":
+ c.compile(node.Arguments[0])
+ c.derefInNeeded(node.Arguments[0])
+ c.emit(OpBegin)
+ var loopBreak int
+ c.emitLoop(func() {
+ c.compile(node.Arguments[1])
+ loopBreak = c.emit(OpJumpIfTrue, placeholder)
+ c.emit(OpPop)
+ })
+ c.emit(OpFalse)
+ c.patchJump(loopBreak)
+ c.emit(OpEnd)
+ return
+
+ case "one":
+ c.compile(node.Arguments[0])
+ c.derefInNeeded(node.Arguments[0])
+ c.emit(OpBegin)
+ c.emitLoop(func() {
+ c.compile(node.Arguments[1])
+ c.emitCond(func() {
+ c.emit(OpIncrementCount)
+ })
+ })
+ c.emit(OpGetCount)
+ c.emitPush(1)
+ c.emit(OpEqual)
+ c.emit(OpEnd)
+ return
+
+ case "filter":
+ c.compile(node.Arguments[0])
+ c.derefInNeeded(node.Arguments[0])
+ c.emit(OpBegin)
+ c.emitLoop(func() {
+ c.compile(node.Arguments[1])
+ c.emitCond(func() {
+ c.emit(OpIncrementCount)
+ if node.Map != nil {
+ c.compile(node.Map)
+ } else {
+ c.emit(OpPointer)
+ }
+ })
+ })
+ c.emit(OpGetCount)
+ c.emit(OpEnd)
+ c.emit(OpArray)
+ return
+
+ case "map":
+ c.compile(node.Arguments[0])
+ c.derefInNeeded(node.Arguments[0])
+ c.emit(OpBegin)
+ c.emitLoop(func() {
+ c.compile(node.Arguments[1])
+ })
+ c.emit(OpGetLen)
+ c.emit(OpEnd)
+ c.emit(OpArray)
+ return
+
+ case "count":
+ c.compile(node.Arguments[0])
+ c.derefInNeeded(node.Arguments[0])
+ c.emit(OpBegin)
+ c.emitLoop(func() {
+ if len(node.Arguments) == 2 {
+ c.compile(node.Arguments[1])
+ } else {
+ c.emit(OpPointer)
+ }
+ c.emitCond(func() {
+ c.emit(OpIncrementCount)
+ })
+ })
+ c.emit(OpGetCount)
+ c.emit(OpEnd)
+ return
+
+ case "sum":
+ c.compile(node.Arguments[0])
+ c.derefInNeeded(node.Arguments[0])
+ c.emit(OpBegin)
+ c.emit(OpInt, 0)
+ c.emit(OpSetAcc)
+ c.emitLoop(func() {
+ if len(node.Arguments) == 2 {
+ c.compile(node.Arguments[1])
+ } else {
+ c.emit(OpPointer)
+ }
+ c.emit(OpGetAcc)
+ c.emit(OpAdd)
+ c.emit(OpSetAcc)
+ })
+ c.emit(OpGetAcc)
+ c.emit(OpEnd)
+ return
+
+ case "find":
+ c.compile(node.Arguments[0])
+ c.derefInNeeded(node.Arguments[0])
+ c.emit(OpBegin)
+ var loopBreak int
+ c.emitLoop(func() {
+ c.compile(node.Arguments[1])
+ noop := c.emit(OpJumpIfFalse, placeholder)
+ c.emit(OpPop)
+ if node.Map != nil {
+ c.compile(node.Map)
+ } else {
+ c.emit(OpPointer)
+ }
+ loopBreak = c.emit(OpJump, placeholder)
+ c.patchJump(noop)
+ c.emit(OpPop)
+ })
+ if node.Throws {
+ c.emit(OpPush, c.addConstant(fmt.Errorf("reflect: slice index out of range")))
+ c.emit(OpThrow)
+ } else {
+ c.emit(OpNil)
+ }
+ c.patchJump(loopBreak)
+ c.emit(OpEnd)
+ return
+
+ case "findIndex":
+ c.compile(node.Arguments[0])
+ c.derefInNeeded(node.Arguments[0])
+ c.emit(OpBegin)
+ var loopBreak int
+ c.emitLoop(func() {
+ c.compile(node.Arguments[1])
+ noop := c.emit(OpJumpIfFalse, placeholder)
+ c.emit(OpPop)
+ c.emit(OpGetIndex)
+ loopBreak = c.emit(OpJump, placeholder)
+ c.patchJump(noop)
+ c.emit(OpPop)
+ })
+ c.emit(OpNil)
+ c.patchJump(loopBreak)
+ c.emit(OpEnd)
+ return
+
+ case "findLast":
+ c.compile(node.Arguments[0])
+ c.derefInNeeded(node.Arguments[0])
+ c.emit(OpBegin)
+ var loopBreak int
+ c.emitLoopBackwards(func() {
+ c.compile(node.Arguments[1])
+ noop := c.emit(OpJumpIfFalse, placeholder)
+ c.emit(OpPop)
+ if node.Map != nil {
+ c.compile(node.Map)
+ } else {
+ c.emit(OpPointer)
+ }
+ loopBreak = c.emit(OpJump, placeholder)
+ c.patchJump(noop)
+ c.emit(OpPop)
+ })
+ if node.Throws {
+ c.emit(OpPush, c.addConstant(fmt.Errorf("reflect: slice index out of range")))
+ c.emit(OpThrow)
+ } else {
+ c.emit(OpNil)
+ }
+ c.patchJump(loopBreak)
+ c.emit(OpEnd)
+ return
+
+ case "findLastIndex":
+ c.compile(node.Arguments[0])
+ c.derefInNeeded(node.Arguments[0])
+ c.emit(OpBegin)
+ var loopBreak int
+ c.emitLoopBackwards(func() {
+ c.compile(node.Arguments[1])
+ noop := c.emit(OpJumpIfFalse, placeholder)
+ c.emit(OpPop)
+ c.emit(OpGetIndex)
+ loopBreak = c.emit(OpJump, placeholder)
+ c.patchJump(noop)
+ c.emit(OpPop)
+ })
+ c.emit(OpNil)
+ c.patchJump(loopBreak)
+ c.emit(OpEnd)
+ return
+
+ case "groupBy":
+ c.compile(node.Arguments[0])
+ c.derefInNeeded(node.Arguments[0])
+ c.emit(OpBegin)
+ c.emit(OpCreate, 1)
+ c.emit(OpSetAcc)
+ c.emitLoop(func() {
+ c.compile(node.Arguments[1])
+ c.emit(OpGroupBy)
+ })
+ c.emit(OpGetAcc)
+ c.emit(OpEnd)
+ return
+
+ case "sortBy":
+ c.compile(node.Arguments[0])
+ c.derefInNeeded(node.Arguments[0])
+ c.emit(OpBegin)
+ if len(node.Arguments) == 3 {
+ c.compile(node.Arguments[2])
+ } else {
+ c.emit(OpPush, c.addConstant("asc"))
+ }
+ c.emit(OpCreate, 2)
+ c.emit(OpSetAcc)
+ c.emitLoop(func() {
+ c.compile(node.Arguments[1])
+ c.emit(OpSortBy)
+ })
+ c.emit(OpSort)
+ c.emit(OpEnd)
+ return
+
+ case "reduce":
+ c.compile(node.Arguments[0])
+ c.derefInNeeded(node.Arguments[0])
+ c.emit(OpBegin)
+ if len(node.Arguments) == 3 {
+ c.compile(node.Arguments[2])
+ c.derefInNeeded(node.Arguments[2])
+ c.emit(OpSetAcc)
+ } else {
+ c.emit(OpPointer)
+ c.emit(OpIncrementIndex)
+ c.emit(OpSetAcc)
+ }
+ c.emitLoop(func() {
+ c.compile(node.Arguments[1])
+ c.emit(OpSetAcc)
+ })
+ c.emit(OpGetAcc)
+ c.emit(OpEnd)
+ return
+
+ }
+
+ if id, ok := builtin.Index[node.Name]; ok {
+ f := builtin.Builtins[id]
+ for i, arg := range node.Arguments {
+ c.compile(arg)
+ argType := arg.Type()
+ if argType.Kind() == reflect.Ptr || arg.Nature().IsUnknown() {
+ if f.Deref == nil {
+ // By default, builtins expect arguments to be dereferenced.
+ c.emit(OpDeref)
+ } else {
+ if f.Deref(i, argType) {
+ c.emit(OpDeref)
+ }
+ }
+ }
+ }
+
+ if f.Fast != nil {
+ c.emit(OpCallBuiltin1, id)
+ } else if f.Safe != nil {
+ c.emit(OpPush, c.addConstant(f.Safe))
+ c.emit(OpCallSafe, len(node.Arguments))
+ } else if f.Func != nil {
+ c.emitFunction(f, len(node.Arguments))
+ }
+ return
+ }
+
+ panic(fmt.Sprintf("unknown builtin %v", node.Name))
+}
+
+func (c *compiler) emitCond(body func()) {
+ noop := c.emit(OpJumpIfFalse, placeholder)
+ c.emit(OpPop)
+
+ body()
+
+ jmp := c.emit(OpJump, placeholder)
+ c.patchJump(noop)
+ c.emit(OpPop)
+ c.patchJump(jmp)
+}
+
+func (c *compiler) emitLoop(body func()) {
+ begin := len(c.bytecode)
+ end := c.emit(OpJumpIfEnd, placeholder)
+
+ body()
+
+ c.emit(OpIncrementIndex)
+ c.emit(OpJumpBackward, c.calcBackwardJump(begin))
+ c.patchJump(end)
+}
+
+func (c *compiler) emitLoopBackwards(body func()) {
+ c.emit(OpGetLen)
+ c.emit(OpInt, 1)
+ c.emit(OpSubtract)
+ c.emit(OpSetIndex)
+ begin := len(c.bytecode)
+ c.emit(OpGetIndex)
+ c.emit(OpInt, 0)
+ c.emit(OpMoreOrEqual)
+ end := c.emit(OpJumpIfFalse, placeholder)
+
+ body()
+
+ c.emit(OpDecrementIndex)
+ c.emit(OpJumpBackward, c.calcBackwardJump(begin))
+ c.patchJump(end)
+}
+
+func (c *compiler) PredicateNode(node *ast.PredicateNode) {
+ c.compile(node.Node)
+}
+
+func (c *compiler) PointerNode(node *ast.PointerNode) {
+ switch node.Name {
+ case "index":
+ c.emit(OpGetIndex)
+ case "acc":
+ c.emit(OpGetAcc)
+ case "":
+ c.emit(OpPointer)
+ default:
+ panic(fmt.Sprintf("unknown pointer %v", node.Name))
+ }
+}
+
+func (c *compiler) VariableDeclaratorNode(node *ast.VariableDeclaratorNode) {
+ c.compile(node.Value)
+ index := c.addVariable(node.Name)
+ c.emit(OpStore, index)
+ c.beginScope(node.Name, index)
+ c.compile(node.Expr)
+ c.endScope()
+}
+
+func (c *compiler) SequenceNode(node *ast.SequenceNode) {
+ for i, n := range node.Nodes {
+ c.compile(n)
+ if i < len(node.Nodes)-1 {
+ c.emit(OpPop)
+ }
+ }
+}
+
+func (c *compiler) beginScope(name string, index int) {
+ c.scopes = append(c.scopes, scope{name, index})
+}
+
+func (c *compiler) endScope() {
+ c.scopes = c.scopes[:len(c.scopes)-1]
+}
+
+func (c *compiler) lookupVariable(name string) (int, bool) {
+ for i := len(c.scopes) - 1; i >= 0; i-- {
+ if c.scopes[i].variableName == name {
+ return c.scopes[i].index, true
+ }
+ }
+ return 0, false
+}
+
+func (c *compiler) ConditionalNode(node *ast.ConditionalNode) {
+ c.compile(node.Cond)
+ otherwise := c.emit(OpJumpIfFalse, placeholder)
+
+ c.emit(OpPop)
+ c.compile(node.Exp1)
+ end := c.emit(OpJump, placeholder)
+
+ c.patchJump(otherwise)
+ c.emit(OpPop)
+ c.compile(node.Exp2)
+
+ c.patchJump(end)
+}
+
+func (c *compiler) ArrayNode(node *ast.ArrayNode) {
+ for _, node := range node.Nodes {
+ c.compile(node)
+ }
+
+ c.emitPush(len(node.Nodes))
+ c.emit(OpArray)
+}
+
+func (c *compiler) MapNode(node *ast.MapNode) {
+ for _, pair := range node.Pairs {
+ c.compile(pair)
+ }
+
+ c.emitPush(len(node.Pairs))
+ c.emit(OpMap)
+}
+
+func (c *compiler) PairNode(node *ast.PairNode) {
+ c.compile(node.Key)
+ c.compile(node.Value)
+}
+
+func (c *compiler) derefInNeeded(node ast.Node) {
+ if node.Nature().Nil {
+ return
+ }
+ switch node.Type().Kind() {
+ case reflect.Ptr, reflect.Interface:
+ c.emit(OpDeref)
+ }
+}
+
+func (c *compiler) derefParam(in reflect.Type, param ast.Node) {
+ if param.Nature().Nil {
+ return
+ }
+ if param.Type().AssignableTo(in) {
+ return
+ }
+ if in.Kind() != reflect.Ptr && param.Type().Kind() == reflect.Ptr {
+ c.emit(OpDeref)
+ }
+}
+
+func (c *compiler) optimize() {
+ for i, op := range c.bytecode {
+ switch op {
+ case OpJumpIfTrue, OpJumpIfFalse, OpJumpIfNil, OpJumpIfNotNil:
+ target := i + c.arguments[i] + 1
+ for target < len(c.bytecode) && c.bytecode[target] == op {
+ target += c.arguments[target] + 1
+ }
+ c.arguments[i] = target - i - 1
+ }
+ }
+}
+
+func kind(t reflect.Type) reflect.Kind {
+ if t == nil {
+ return reflect.Invalid
+ }
+ return t.Kind()
+}
diff --git a/vendor/github.com/expr-lang/expr/conf/config.go b/vendor/github.com/expr-lang/expr/conf/config.go
new file mode 100644
index 0000000..d629958
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/conf/config.go
@@ -0,0 +1,101 @@
+package conf
+
+import (
+ "fmt"
+ "reflect"
+
+ "github.com/expr-lang/expr/ast"
+ "github.com/expr-lang/expr/builtin"
+ "github.com/expr-lang/expr/checker/nature"
+ "github.com/expr-lang/expr/vm/runtime"
+)
+
+const (
+ // DefaultMemoryBudget represents an upper limit of memory usage
+ DefaultMemoryBudget uint = 1e6
+
+ // DefaultMaxNodes represents an upper limit of AST nodes
+ DefaultMaxNodes uint = 10000
+)
+
+type FunctionsTable map[string]*builtin.Function
+
+type Config struct {
+ EnvObject any
+ Env nature.Nature
+ Expect reflect.Kind
+ ExpectAny bool
+ Optimize bool
+ Strict bool
+ Profile bool
+ MaxNodes uint
+ MemoryBudget uint
+ ConstFns map[string]reflect.Value
+ Visitors []ast.Visitor
+ Functions FunctionsTable
+ Builtins FunctionsTable
+ Disabled map[string]bool // disabled builtins
+}
+
+// CreateNew creates new config with default values.
+func CreateNew() *Config {
+ c := &Config{
+ Optimize: true,
+ MaxNodes: DefaultMaxNodes,
+ MemoryBudget: DefaultMemoryBudget,
+ ConstFns: make(map[string]reflect.Value),
+ Functions: make(map[string]*builtin.Function),
+ Builtins: make(map[string]*builtin.Function),
+ Disabled: make(map[string]bool),
+ }
+ for _, f := range builtin.Builtins {
+ c.Builtins[f.Name] = f
+ }
+ return c
+}
+
+// New creates new config with environment.
+func New(env any) *Config {
+ c := CreateNew()
+ c.WithEnv(env)
+ return c
+}
+
+func (c *Config) WithEnv(env any) {
+ c.EnvObject = env
+ c.Env = Env(env)
+ c.Strict = c.Env.Strict
+}
+
+func (c *Config) ConstExpr(name string) {
+ if c.EnvObject == nil {
+ panic("no environment is specified for ConstExpr()")
+ }
+ fn := reflect.ValueOf(runtime.Fetch(c.EnvObject, name))
+ if fn.Kind() != reflect.Func {
+ panic(fmt.Errorf("const expression %q must be a function", name))
+ }
+ c.ConstFns[name] = fn
+}
+
+type Checker interface {
+ Check()
+}
+
+func (c *Config) Check() {
+ for _, v := range c.Visitors {
+ if c, ok := v.(Checker); ok {
+ c.Check()
+ }
+ }
+}
+
+func (c *Config) IsOverridden(name string) bool {
+ if _, ok := c.Functions[name]; ok {
+ return true
+ }
+ if _, ok := c.Env.Get(name); ok {
+ return true
+ }
+ return false
+}
diff --git a/vendor/github.com/expr-lang/expr/conf/env.go b/vendor/github.com/expr-lang/expr/conf/env.go
new file mode 100644
index 0000000..8b13df1
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/conf/env.go
@@ -0,0 +1,68 @@
+package conf
+
+import (
+ "fmt"
+ "reflect"
+
+ . "github.com/expr-lang/expr/checker/nature"
+ "github.com/expr-lang/expr/internal/deref"
+ "github.com/expr-lang/expr/types"
+)
+
+func Env(env any) Nature {
+ if env == nil {
+ return Nature{
+ Type: reflect.TypeOf(map[string]any{}),
+ Strict: true,
+ }
+ }
+
+ switch env := env.(type) {
+ case types.Map:
+ return env.Nature()
+ }
+
+ v := reflect.ValueOf(env)
+ d := deref.Value(v)
+
+ switch d.Kind() {
+ case reflect.Struct:
+ return Nature{
+ Type: v.Type(),
+ Strict: true,
+ }
+
+ case reflect.Map:
+ n := Nature{
+ Type: v.Type(),
+ Fields: make(map[string]Nature, v.Len()),
+ Strict: true,
+ }
+
+ for _, key := range v.MapKeys() {
+ elem := v.MapIndex(key)
+ if !elem.IsValid() || !elem.CanInterface() {
+ panic(fmt.Sprintf("invalid map value: %s", key))
+ }
+
+ face := elem.Interface()
+
+ switch face := face.(type) {
+ case types.Map:
+ n.Fields[key.String()] = face.Nature()
+
+ default:
+ if face == nil {
+ n.Fields[key.String()] = Nature{Nil: true}
+ continue
+ }
+ n.Fields[key.String()] = Nature{Type: reflect.TypeOf(face)}
+ }
+
+ }
+
+ return n
+ }
+
+ panic(fmt.Sprintf("unknown type %T", env))
+}
diff --git a/vendor/github.com/expr-lang/expr/expr.go b/vendor/github.com/expr-lang/expr/expr.go
new file mode 100644
index 0000000..5e60791
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/expr.go
@@ -0,0 +1,254 @@
+package expr
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+ "time"
+
+ "github.com/expr-lang/expr/ast"
+ "github.com/expr-lang/expr/builtin"
+ "github.com/expr-lang/expr/checker"
+ "github.com/expr-lang/expr/compiler"
+ "github.com/expr-lang/expr/conf"
+ "github.com/expr-lang/expr/file"
+ "github.com/expr-lang/expr/optimizer"
+ "github.com/expr-lang/expr/patcher"
+ "github.com/expr-lang/expr/vm"
+)
+
+// Option for configuring config.
+type Option func(c *conf.Config)
+
+// Env specifies expected input of env for type checks.
+// If struct is passed, all fields will be treated as variables,
+// as well as all fields of embedded structs and struct itself.
+// If map is passed, all items will be treated as variables.
+// Methods defined on this type will be available as functions.
+func Env(env any) Option {
+ return func(c *conf.Config) {
+ c.WithEnv(env)
+ }
+}
+
+// AllowUndefinedVariables allows to use undefined variables inside expressions.
+// This can be used with expr.Env option to partially define a few variables.
+func AllowUndefinedVariables() Option {
+ return func(c *conf.Config) {
+ c.Strict = false
+ }
+}
+
+// Operator allows to replace a binary operator with a function.
+func Operator(operator string, fn ...string) Option {
+ return func(c *conf.Config) {
+ p := &patcher.OperatorOverloading{
+ Operator: operator,
+ Overloads: fn,
+ Env: &c.Env,
+ Functions: c.Functions,
+ }
+ c.Visitors = append(c.Visitors, p)
+ }
+}
+
+// ConstExpr defines func expression as constant. If all argument to this function is constants,
+// then it can be replaced by result of this func call on compile step.
+func ConstExpr(fn string) Option {
+ return func(c *conf.Config) {
+ c.ConstExpr(fn)
+ }
+}
+
+// AsAny tells the compiler to expect any result.
+func AsAny() Option {
+ return func(c *conf.Config) {
+ c.ExpectAny = true
+ }
+}
+
+// AsKind tells the compiler to expect kind of the result.
+func AsKind(kind reflect.Kind) Option {
+ return func(c *conf.Config) {
+ c.Expect = kind
+ c.ExpectAny = true
+ }
+}
+
+// AsBool tells the compiler to expect a boolean result.
+func AsBool() Option {
+ return func(c *conf.Config) {
+ c.Expect = reflect.Bool
+ c.ExpectAny = true
+ }
+}
+
+// AsInt tells the compiler to expect an int result.
+func AsInt() Option {
+ return func(c *conf.Config) {
+ c.Expect = reflect.Int
+ c.ExpectAny = true
+ }
+}
+
+// AsInt64 tells the compiler to expect an int64 result.
+func AsInt64() Option {
+ return func(c *conf.Config) {
+ c.Expect = reflect.Int64
+ c.ExpectAny = true
+ }
+}
+
+// AsFloat64 tells the compiler to expect a float64 result.
+func AsFloat64() Option {
+ return func(c *conf.Config) {
+ c.Expect = reflect.Float64
+ c.ExpectAny = true
+ }
+}
+
+// WarnOnAny tells the compiler to warn if expression return any type.
+func WarnOnAny() Option {
+ return func(c *conf.Config) {
+ if c.Expect == reflect.Invalid {
+ panic("WarnOnAny() works only with combination with AsInt(), AsBool(), etc. options")
+ }
+ c.ExpectAny = false
+ }
+}
+
+// Optimize turns optimizations on or off.
+func Optimize(b bool) Option {
+ return func(c *conf.Config) {
+ c.Optimize = b
+ }
+}
+
+// Patch adds visitor to list of visitors what will be applied before compiling AST to bytecode.
+func Patch(visitor ast.Visitor) Option {
+ return func(c *conf.Config) {
+ c.Visitors = append(c.Visitors, visitor)
+ }
+}
+
+// Function adds function to list of functions what will be available in expressions.
+func Function(name string, fn func(params ...any) (any, error), types ...any) Option {
+ return func(c *conf.Config) {
+ ts := make([]reflect.Type, len(types))
+ for i, t := range types {
+ t := reflect.TypeOf(t)
+ if t.Kind() == reflect.Ptr {
+ t = t.Elem()
+ }
+ if t.Kind() != reflect.Func {
+ panic(fmt.Sprintf("expr: type of %s is not a function", name))
+ }
+ ts[i] = t
+ }
+ c.Functions[name] = &builtin.Function{
+ Name: name,
+ Func: fn,
+ Types: ts,
+ }
+ }
+}
+
+// DisableAllBuiltins disables all builtins.
+func DisableAllBuiltins() Option {
+ return func(c *conf.Config) {
+ for name := range c.Builtins {
+ c.Disabled[name] = true
+ }
+ }
+}
+
+// DisableBuiltin disables builtin function.
+func DisableBuiltin(name string) Option {
+ return func(c *conf.Config) {
+ c.Disabled[name] = true
+ }
+}
+
+// EnableBuiltin enables builtin function.
+func EnableBuiltin(name string) Option {
+ return func(c *conf.Config) {
+ delete(c.Disabled, name)
+ }
+}
+
+// WithContext passes context to all functions calls with a context.Context argument.
+func WithContext(name string) Option {
+ return Patch(patcher.WithContext{
+ Name: name,
+ })
+}
+
+// Timezone sets default timezone for date() and now() builtin functions.
+func Timezone(name string) Option {
+ tz, err := time.LoadLocation(name)
+ if err != nil {
+ panic(err)
+ }
+ return Patch(patcher.WithTimezone{
+ Location: tz,
+ })
+}
+
+// Compile parses and compiles given input expression to bytecode program.
+func Compile(input string, ops ...Option) (*vm.Program, error) {
+ config := conf.CreateNew()
+ for _, op := range ops {
+ op(config)
+ }
+ for name := range config.Disabled {
+ delete(config.Builtins, name)
+ }
+ config.Check()
+
+ tree, err := checker.ParseCheck(input, config)
+ if err != nil {
+ return nil, err
+ }
+
+ if config.Optimize {
+ err = optimizer.Optimize(&tree.Node, config)
+ if err != nil {
+ var fileError *file.Error
+ if errors.As(err, &fileError) {
+ return nil, fileError.Bind(tree.Source)
+ }
+ return nil, err
+ }
+ }
+
+ program, err := compiler.Compile(tree, config)
+ if err != nil {
+ return nil, err
+ }
+
+ return program, nil
+}
+
+// Run evaluates given bytecode program.
+func Run(program *vm.Program, env any) (any, error) {
+ return vm.Run(program, env)
+}
+
+// Eval parses, compiles and runs given input.
+func Eval(input string, env any) (any, error) {
+ if _, ok := env.(Option); ok {
+ return nil, fmt.Errorf("misused expr.Eval: second argument (env) should be passed without expr.Env")
+ }
+
+ program, err := Compile(input)
+ if err != nil {
+ return nil, err
+ }
+
+ output, err := Run(program, env)
+ if err != nil {
+ return nil, err
+ }
+
+ return output, nil
+}
diff --git a/vendor/github.com/expr-lang/expr/file/error.go b/vendor/github.com/expr-lang/expr/file/error.go
new file mode 100644
index 0000000..8ff85df
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/file/error.go
@@ -0,0 +1,81 @@
+package file
+
+import (
+ "fmt"
+ "strings"
+ "unicode/utf8"
+)
+
+type Error struct {
+ Location
+ Line int `json:"line"`
+ Column int `json:"column"`
+ Message string `json:"message"`
+ Snippet string `json:"snippet"`
+ Prev error `json:"prev"`
+}
+
+func (e *Error) Error() string {
+ return e.format()
+}
+
+func (e *Error) Bind(source Source) *Error {
+ e.Line = 1
+ for i, r := range source {
+ if i == e.From {
+ break
+ }
+ if r == '\n' {
+ e.Line++
+ e.Column = 0
+ } else {
+ e.Column++
+ }
+ }
+ if snippet, found := source.Snippet(e.Line); found {
+ snippet := strings.Replace(snippet, "\t", " ", -1)
+ srcLine := "\n | " + snippet
+ var bytes = []byte(snippet)
+ var indLine = "\n | "
+ for i := 0; i < e.Column && len(bytes) > 0; i++ {
+ _, sz := utf8.DecodeRune(bytes)
+ bytes = bytes[sz:]
+ if sz > 1 {
+ goto noind
+ } else {
+ indLine += "."
+ }
+ }
+ if _, sz := utf8.DecodeRune(bytes); sz > 1 {
+ goto noind
+ } else {
+ indLine += "^"
+ }
+ srcLine += indLine
+
+ noind:
+ e.Snippet = srcLine
+ }
+ return e
+}
+
+func (e *Error) Unwrap() error {
+ return e.Prev
+}
+
+func (e *Error) Wrap(err error) {
+ e.Prev = err
+}
+
+func (e *Error) format() string {
+ if e.Snippet == "" {
+ return e.Message
+ }
+ return fmt.Sprintf(
+ "%s (%d:%d)%s",
+ e.Message,
+ e.Line,
+ e.Column+1, // add one to the 0-based column for display
+ e.Snippet,
+ )
+}
diff --git a/vendor/github.com/expr-lang/expr/file/location.go b/vendor/github.com/expr-lang/expr/file/location.go
new file mode 100644
index 0000000..6c6bc24
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/file/location.go
@@ -0,0 +1,6 @@
+package file
+
+type Location struct {
+ From int `json:"from"`
+ To int `json:"to"`
+}
diff --git a/vendor/github.com/expr-lang/expr/file/source.go b/vendor/github.com/expr-lang/expr/file/source.go
new file mode 100644
index 0000000..8e2b2d1
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/file/source.go
@@ -0,0 +1,48 @@
+package file
+
+import (
+ "strings"
+ "unicode/utf8"
+)
+
+type Source []rune
+
+func NewSource(contents string) Source {
+ return []rune(contents)
+}
+
+func (s Source) String() string {
+ return string(s)
+}
+
+func (s Source) Snippet(line int) (string, bool) {
+ if s == nil {
+ return "", false
+ }
+ lines := strings.Split(string(s), "\n")
+ lineOffsets := make([]int, len(lines))
+ var offset int
+ for i, line := range lines {
+ offset = offset + utf8.RuneCountInString(line) + 1
+ lineOffsets[i] = offset
+ }
+ charStart, found := getLineOffset(lineOffsets, line)
+ if !found || len(s) == 0 {
+ return "", false
+ }
+ charEnd, found := getLineOffset(lineOffsets, line+1)
+ if found {
+ return string(s[charStart : charEnd-1]), true
+ }
+ return string(s[charStart:]), true
+}
+
+func getLineOffset(lineOffsets []int, line int) (int, bool) {
+ if line == 1 {
+ return 0, true
+ } else if line > 1 && line <= len(lineOffsets) {
+ offset := lineOffsets[line-2]
+ return offset, true
+ }
+ return -1, false
+}
diff --git a/vendor/github.com/expr-lang/expr/internal/deref/deref.go b/vendor/github.com/expr-lang/expr/internal/deref/deref.go
new file mode 100644
index 0000000..da3e28c
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/internal/deref/deref.go
@@ -0,0 +1,47 @@
+package deref
+
+import (
+ "fmt"
+ "reflect"
+)
+
+func Interface(p any) any {
+ if p == nil {
+ return nil
+ }
+
+ v := reflect.ValueOf(p)
+
+ for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
+ if v.IsNil() {
+ return nil
+ }
+ v = v.Elem()
+ }
+
+ if v.IsValid() {
+ return v.Interface()
+ }
+
+ panic(fmt.Sprintf("cannot dereference %v", p))
+}
+
+func Type(t reflect.Type) reflect.Type {
+ if t == nil {
+ return nil
+ }
+ for t.Kind() == reflect.Ptr {
+ t = t.Elem()
+ }
+ return t
+}
+
+func Value(v reflect.Value) reflect.Value {
+ for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
+ if v.IsNil() {
+ return v
+ }
+ v = v.Elem()
+ }
+ return v
+}
diff --git a/vendor/github.com/expr-lang/expr/optimizer/const_expr.go b/vendor/github.com/expr-lang/expr/optimizer/const_expr.go
new file mode 100644
index 0000000..1b45385
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/optimizer/const_expr.go
@@ -0,0 +1,81 @@
+package optimizer
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+
+ . "github.com/expr-lang/expr/ast"
+ "github.com/expr-lang/expr/file"
+)
+
+var errorType = reflect.TypeOf((*error)(nil)).Elem()
+
+type constExpr struct {
+ applied bool
+ err error
+ fns map[string]reflect.Value
+}
+
+func (c *constExpr) Visit(node *Node) {
+ defer func() {
+ if r := recover(); r != nil {
+ msg := fmt.Sprintf("%v", r)
+ // Make message more actual, it's a runtime error, but at compile step.
+ msg = strings.Replace(msg, "runtime error:", "compile error:", 1)
+ c.err = &file.Error{
+ Location: (*node).Location(),
+ Message: msg,
+ }
+ }
+ }()
+
+ if call, ok := (*node).(*CallNode); ok {
+ if name, ok := call.Callee.(*IdentifierNode); ok {
+ fn, ok := c.fns[name.Value]
+ if ok {
+ in := make([]reflect.Value, len(call.Arguments))
+ for i := 0; i < len(call.Arguments); i++ {
+ arg := call.Arguments[i]
+ var param any
+
+ switch a := arg.(type) {
+ case *NilNode:
+ param = nil
+ case *IntegerNode:
+ param = a.Value
+ case *FloatNode:
+ param = a.Value
+ case *BoolNode:
+ param = a.Value
+ case *StringNode:
+ param = a.Value
+ case *ConstantNode:
+ param = a.Value
+
+ default:
+ return // Const expr optimization not applicable.
+ }
+
+ if param == nil && reflect.TypeOf(param) == nil {
+ // In case of nil value and nil type use this hack,
+ // otherwise reflect.Call will panic on zero value.
+ in[i] = reflect.ValueOf(¶m).Elem()
+ } else {
+ in[i] = reflect.ValueOf(param)
+ }
+ }
+
+ out := fn.Call(in)
+ value := out[0].Interface()
+ if len(out) == 2 && out[1].Type() == errorType && !out[1].IsNil() {
+ c.err = out[1].Interface().(error)
+ return
+ }
+ constNode := &ConstantNode{Value: value}
+ patchWithType(node, constNode)
+ c.applied = true
+ }
+ }
+ }
+}
diff --git a/vendor/github.com/expr-lang/expr/optimizer/filter_first.go b/vendor/github.com/expr-lang/expr/optimizer/filter_first.go
new file mode 100644
index 0000000..b04a5cb
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/optimizer/filter_first.go
@@ -0,0 +1,38 @@
+package optimizer
+
+import (
+ . "github.com/expr-lang/expr/ast"
+)
+
+type filterFirst struct{}
+
+func (*filterFirst) Visit(node *Node) {
+ if member, ok := (*node).(*MemberNode); ok && member.Property != nil && !member.Optional {
+ if prop, ok := member.Property.(*IntegerNode); ok && prop.Value == 0 {
+ if filter, ok := member.Node.(*BuiltinNode); ok &&
+ filter.Name == "filter" &&
+ len(filter.Arguments) == 2 {
+ patchCopyType(node, &BuiltinNode{
+ Name: "find",
+ Arguments: filter.Arguments,
+ Throws: true, // to match the behavior of filter()[0]
+ Map: filter.Map,
+ })
+ }
+ }
+ }
+ if first, ok := (*node).(*BuiltinNode); ok &&
+ first.Name == "first" &&
+ len(first.Arguments) == 1 {
+ if filter, ok := first.Arguments[0].(*BuiltinNode); ok &&
+ filter.Name == "filter" &&
+ len(filter.Arguments) == 2 {
+ patchCopyType(node, &BuiltinNode{
+ Name: "find",
+ Arguments: filter.Arguments,
+ Throws: false, // as first() will return nil if not found
+ Map: filter.Map,
+ })
+ }
+ }
+}
diff --git a/vendor/github.com/expr-lang/expr/optimizer/filter_last.go b/vendor/github.com/expr-lang/expr/optimizer/filter_last.go
new file mode 100644
index 0000000..8c046bf
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/optimizer/filter_last.go
@@ -0,0 +1,38 @@
+package optimizer
+
+import (
+ . "github.com/expr-lang/expr/ast"
+)
+
+type filterLast struct{}
+
+func (*filterLast) Visit(node *Node) {
+ if member, ok := (*node).(*MemberNode); ok && member.Property != nil && !member.Optional {
+ if prop, ok := member.Property.(*IntegerNode); ok && prop.Value == -1 {
+ if filter, ok := member.Node.(*BuiltinNode); ok &&
+ filter.Name == "filter" &&
+ len(filter.Arguments) == 2 {
+ patchCopyType(node, &BuiltinNode{
+ Name: "findLast",
+ Arguments: filter.Arguments,
+ Throws: true, // to match the behavior of filter()[-1]
+ Map: filter.Map,
+ })
+ }
+ }
+ }
+ if first, ok := (*node).(*BuiltinNode); ok &&
+ first.Name == "last" &&
+ len(first.Arguments) == 1 {
+ if filter, ok := first.Arguments[0].(*BuiltinNode); ok &&
+ filter.Name == "filter" &&
+ len(filter.Arguments) == 2 {
+ patchCopyType(node, &BuiltinNode{
+ Name: "findLast",
+ Arguments: filter.Arguments,
+ Throws: false, // as last() will return nil if not found
+ Map: filter.Map,
+ })
+ }
+ }
+}
diff --git a/vendor/github.com/expr-lang/expr/optimizer/filter_len.go b/vendor/github.com/expr-lang/expr/optimizer/filter_len.go
new file mode 100644
index 0000000..c66fde9
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/optimizer/filter_len.go
@@ -0,0 +1,22 @@
+package optimizer
+
+import (
+ . "github.com/expr-lang/expr/ast"
+)
+
+type filterLen struct{}
+
+func (*filterLen) Visit(node *Node) {
+ if ln, ok := (*node).(*BuiltinNode); ok &&
+ ln.Name == "len" &&
+ len(ln.Arguments) == 1 {
+ if filter, ok := ln.Arguments[0].(*BuiltinNode); ok &&
+ filter.Name == "filter" &&
+ len(filter.Arguments) == 2 {
+ patchCopyType(node, &BuiltinNode{
+ Name: "count",
+ Arguments: filter.Arguments,
+ })
+ }
+ }
+}
diff --git a/vendor/github.com/expr-lang/expr/optimizer/filter_map.go b/vendor/github.com/expr-lang/expr/optimizer/filter_map.go
new file mode 100644
index 0000000..17659a9
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/optimizer/filter_map.go
@@ -0,0 +1,33 @@
+package optimizer
+
+import (
+ . "github.com/expr-lang/expr/ast"
+)
+
+type filterMap struct{}
+
+func (*filterMap) Visit(node *Node) {
+ if mapBuiltin, ok := (*node).(*BuiltinNode); ok &&
+ mapBuiltin.Name == "map" &&
+ len(mapBuiltin.Arguments) == 2 &&
+ Find(mapBuiltin.Arguments[1], isIndexPointer) == nil {
+ if predicate, ok := mapBuiltin.Arguments[1].(*PredicateNode); ok {
+ if filter, ok := mapBuiltin.Arguments[0].(*BuiltinNode); ok &&
+ filter.Name == "filter" &&
+ filter.Map == nil /* not already optimized */ {
+ patchCopyType(node, &BuiltinNode{
+ Name: "filter",
+ Arguments: filter.Arguments,
+ Map: predicate.Node,
+ })
+ }
+ }
+ }
+}
+
+func isIndexPointer(node Node) bool {
+ if pointer, ok := node.(*PointerNode); ok && pointer.Name == "index" {
+ return true
+ }
+ return false
+}
diff --git a/vendor/github.com/expr-lang/expr/optimizer/fold.go b/vendor/github.com/expr-lang/expr/optimizer/fold.go
new file mode 100644
index 0000000..bb40eab
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/optimizer/fold.go
@@ -0,0 +1,341 @@
+package optimizer
+
+import (
+ "math"
+
+ . "github.com/expr-lang/expr/ast"
+ "github.com/expr-lang/expr/file"
+)
+
+type fold struct {
+ applied bool
+ err *file.Error
+}
+
+func (fold *fold) Visit(node *Node) {
+ patch := func(newNode Node) {
+ fold.applied = true
+ patchWithType(node, newNode)
+ }
+ patchCopy := func(newNode Node) {
+ fold.applied = true
+ patchCopyType(node, newNode)
+ }
+
+ switch n := (*node).(type) {
+ case *UnaryNode:
+ switch n.Operator {
+ case "-":
+ if i, ok := n.Node.(*IntegerNode); ok {
+ patch(&IntegerNode{Value: -i.Value})
+ }
+ if i, ok := n.Node.(*FloatNode); ok {
+ patch(&FloatNode{Value: -i.Value})
+ }
+ case "+":
+ if i, ok := n.Node.(*IntegerNode); ok {
+ patch(&IntegerNode{Value: i.Value})
+ }
+ if i, ok := n.Node.(*FloatNode); ok {
+ patch(&FloatNode{Value: i.Value})
+ }
+ case "!", "not":
+ if a := toBool(n.Node); a != nil {
+ patch(&BoolNode{Value: !a.Value})
+ }
+ }
+
+ case *BinaryNode:
+ switch n.Operator {
+ case "+":
+ {
+ a := toInteger(n.Left)
+ b := toInteger(n.Right)
+ if a != nil && b != nil {
+ patch(&IntegerNode{Value: a.Value + b.Value})
+ }
+ }
+ {
+ a := toInteger(n.Left)
+ b := toFloat(n.Right)
+ if a != nil && b != nil {
+ patch(&FloatNode{Value: float64(a.Value) + b.Value})
+ }
+ }
+ {
+ a := toFloat(n.Left)
+ b := toInteger(n.Right)
+ if a != nil && b != nil {
+ patch(&FloatNode{Value: a.Value + float64(b.Value)})
+ }
+ }
+ {
+ a := toFloat(n.Left)
+ b := toFloat(n.Right)
+ if a != nil && b != nil {
+ patch(&FloatNode{Value: a.Value + b.Value})
+ }
+ }
+ {
+ a := toString(n.Left)
+ b := toString(n.Right)
+ if a != nil && b != nil {
+ patch(&StringNode{Value: a.Value + b.Value})
+ }
+ }
+ case "-":
+ {
+ a := toInteger(n.Left)
+ b := toInteger(n.Right)
+ if a != nil && b != nil {
+ patch(&IntegerNode{Value: a.Value - b.Value})
+ }
+ }
+ {
+ a := toInteger(n.Left)
+ b := toFloat(n.Right)
+ if a != nil && b != nil {
+ patch(&FloatNode{Value: float64(a.Value) - b.Value})
+ }
+ }
+ {
+ a := toFloat(n.Left)
+ b := toInteger(n.Right)
+ if a != nil && b != nil {
+ patch(&FloatNode{Value: a.Value - float64(b.Value)})
+ }
+ }
+ {
+ a := toFloat(n.Left)
+ b := toFloat(n.Right)
+ if a != nil && b != nil {
+ patch(&FloatNode{Value: a.Value - b.Value})
+ }
+ }
+ case "*":
+ {
+ a := toInteger(n.Left)
+ b := toInteger(n.Right)
+ if a != nil && b != nil {
+ patch(&IntegerNode{Value: a.Value * b.Value})
+ }
+ }
+ {
+ a := toInteger(n.Left)
+ b := toFloat(n.Right)
+ if a != nil && b != nil {
+ patch(&FloatNode{Value: float64(a.Value) * b.Value})
+ }
+ }
+ {
+ a := toFloat(n.Left)
+ b := toInteger(n.Right)
+ if a != nil && b != nil {
+ patch(&FloatNode{Value: a.Value * float64(b.Value)})
+ }
+ }
+ {
+ a := toFloat(n.Left)
+ b := toFloat(n.Right)
+ if a != nil && b != nil {
+ patch(&FloatNode{Value: a.Value * b.Value})
+ }
+ }
+ case "/":
+ {
+ a := toInteger(n.Left)
+ b := toInteger(n.Right)
+ if a != nil && b != nil {
+ patch(&FloatNode{Value: float64(a.Value) / float64(b.Value)})
+ }
+ }
+ {
+ a := toInteger(n.Left)
+ b := toFloat(n.Right)
+ if a != nil && b != nil {
+ patch(&FloatNode{Value: float64(a.Value) / b.Value})
+ }
+ }
+ {
+ a := toFloat(n.Left)
+ b := toInteger(n.Right)
+ if a != nil && b != nil {
+ patch(&FloatNode{Value: a.Value / float64(b.Value)})
+ }
+ }
+ {
+ a := toFloat(n.Left)
+ b := toFloat(n.Right)
+ if a != nil && b != nil {
+ patch(&FloatNode{Value: a.Value / b.Value})
+ }
+ }
+ case "%":
+ if a, ok := n.Left.(*IntegerNode); ok {
+ if b, ok := n.Right.(*IntegerNode); ok {
+ if b.Value == 0 {
+ fold.err = &file.Error{
+ Location: (*node).Location(),
+ Message: "integer divide by zero",
+ }
+ return
+ }
+ patch(&IntegerNode{Value: a.Value % b.Value})
+ }
+ }
+ case "**", "^":
+ {
+ a := toInteger(n.Left)
+ b := toInteger(n.Right)
+ if a != nil && b != nil {
+ patch(&FloatNode{Value: math.Pow(float64(a.Value), float64(b.Value))})
+ }
+ }
+ {
+ a := toInteger(n.Left)
+ b := toFloat(n.Right)
+ if a != nil && b != nil {
+ patch(&FloatNode{Value: math.Pow(float64(a.Value), b.Value)})
+ }
+ }
+ {
+ a := toFloat(n.Left)
+ b := toInteger(n.Right)
+ if a != nil && b != nil {
+ patch(&FloatNode{Value: math.Pow(a.Value, float64(b.Value))})
+ }
+ }
+ {
+ a := toFloat(n.Left)
+ b := toFloat(n.Right)
+ if a != nil && b != nil {
+ patch(&FloatNode{Value: math.Pow(a.Value, b.Value)})
+ }
+ }
+ case "and", "&&":
+ a := toBool(n.Left)
+ b := toBool(n.Right)
+
+ if a != nil && a.Value { // true and x
+ patchCopy(n.Right)
+ } else if b != nil && b.Value { // x and true
+ patchCopy(n.Left)
+ } else if (a != nil && !a.Value) || (b != nil && !b.Value) { // "x and false" or "false and x"
+ patch(&BoolNode{Value: false})
+ }
+ case "or", "||":
+ a := toBool(n.Left)
+ b := toBool(n.Right)
+
+ if a != nil && !a.Value { // false or x
+ patchCopy(n.Right)
+ } else if b != nil && !b.Value { // x or false
+ patchCopy(n.Left)
+ } else if (a != nil && a.Value) || (b != nil && b.Value) { // "x or true" or "true or x"
+ patch(&BoolNode{Value: true})
+ }
+ case "==":
+ {
+ a := toInteger(n.Left)
+ b := toInteger(n.Right)
+ if a != nil && b != nil {
+ patch(&BoolNode{Value: a.Value == b.Value})
+ }
+ }
+ {
+ a := toString(n.Left)
+ b := toString(n.Right)
+ if a != nil && b != nil {
+ patch(&BoolNode{Value: a.Value == b.Value})
+ }
+ }
+ {
+ a := toBool(n.Left)
+ b := toBool(n.Right)
+ if a != nil && b != nil {
+ patch(&BoolNode{Value: a.Value == b.Value})
+ }
+ }
+ }
+
+ case *ArrayNode:
+ if len(n.Nodes) > 0 {
+ for _, a := range n.Nodes {
+ switch a.(type) {
+ case *IntegerNode, *FloatNode, *StringNode, *BoolNode:
+ continue
+ default:
+ return
+ }
+ }
+ value := make([]any, len(n.Nodes))
+ for i, a := range n.Nodes {
+ switch b := a.(type) {
+ case *IntegerNode:
+ value[i] = b.Value
+ case *FloatNode:
+ value[i] = b.Value
+ case *StringNode:
+ value[i] = b.Value
+ case *BoolNode:
+ value[i] = b.Value
+ }
+ }
+ patch(&ConstantNode{Value: value})
+ }
+
+ case *BuiltinNode:
+ // TODO: Move this to a separate visitor filter_filter.go
+ switch n.Name {
+ case "filter":
+ if len(n.Arguments) != 2 {
+ return
+ }
+ if base, ok := n.Arguments[0].(*BuiltinNode); ok && base.Name == "filter" {
+ patchCopy(&BuiltinNode{
+ Name: "filter",
+ Arguments: []Node{
+ base.Arguments[0],
+ &BinaryNode{
+ Operator: "&&",
+ Left: base.Arguments[1].(*PredicateNode).Node,
+ Right: n.Arguments[1].(*PredicateNode).Node,
+ },
+ },
+ })
+ }
+ }
+ }
+}
+
+func toString(n Node) *StringNode {
+ switch a := n.(type) {
+ case *StringNode:
+ return a
+ }
+ return nil
+}
+
+func toInteger(n Node) *IntegerNode {
+ switch a := n.(type) {
+ case *IntegerNode:
+ return a
+ }
+ return nil
+}
+
+func toFloat(n Node) *FloatNode {
+ switch a := n.(type) {
+ case *FloatNode:
+ return a
+ }
+ return nil
+}
+
+func toBool(n Node) *BoolNode {
+ switch a := n.(type) {
+ case *BoolNode:
+ return a
+ }
+ return nil
+}
diff --git a/vendor/github.com/expr-lang/expr/optimizer/in_array.go b/vendor/github.com/expr-lang/expr/optimizer/in_array.go
new file mode 100644
index 0000000..e91320c
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/optimizer/in_array.go
@@ -0,0 +1,68 @@
+package optimizer
+
+import (
+ "reflect"
+
+ . "github.com/expr-lang/expr/ast"
+)
+
+type inArray struct{}
+
+func (*inArray) Visit(node *Node) {
+ switch n := (*node).(type) {
+ case *BinaryNode:
+ if n.Operator == "in" {
+ if array, ok := n.Right.(*ArrayNode); ok {
+ if len(array.Nodes) > 0 {
+ t := n.Left.Type()
+ if t == nil || t.Kind() != reflect.Int {
+ // This optimization can be only performed if left side is int type,
+ // as runtime.in func uses reflect.Map.MapIndex and keys of map must,
+ // be same as checked value type.
+ goto string
+ }
+
+ for _, a := range array.Nodes {
+ if _, ok := a.(*IntegerNode); !ok {
+ goto string
+ }
+ }
+ {
+ value := make(map[int]struct{})
+ for _, a := range array.Nodes {
+ value[a.(*IntegerNode).Value] = struct{}{}
+ }
+ m := &ConstantNode{Value: value}
+ m.SetType(reflect.TypeOf(value))
+ patchCopyType(node, &BinaryNode{
+ Operator: n.Operator,
+ Left: n.Left,
+ Right: m,
+ })
+ }
+
+ string:
+ for _, a := range array.Nodes {
+ if _, ok := a.(*StringNode); !ok {
+ return
+ }
+ }
+ {
+ value := make(map[string]struct{})
+ for _, a := range array.Nodes {
+ value[a.(*StringNode).Value] = struct{}{}
+ }
+ m := &ConstantNode{Value: value}
+ m.SetType(reflect.TypeOf(value))
+ patchCopyType(node, &BinaryNode{
+ Operator: n.Operator,
+ Left: n.Left,
+ Right: m,
+ })
+ }
+
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/github.com/expr-lang/expr/optimizer/in_range.go b/vendor/github.com/expr-lang/expr/optimizer/in_range.go
new file mode 100644
index 0000000..ed2f557
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/optimizer/in_range.go
@@ -0,0 +1,43 @@
+package optimizer
+
+import (
+ "reflect"
+
+ . "github.com/expr-lang/expr/ast"
+)
+
+type inRange struct{}
+
+func (*inRange) Visit(node *Node) {
+ switch n := (*node).(type) {
+ case *BinaryNode:
+ if n.Operator == "in" {
+ t := n.Left.Type()
+ if t == nil {
+ return
+ }
+ if t.Kind() != reflect.Int {
+ return
+ }
+ if rangeOp, ok := n.Right.(*BinaryNode); ok && rangeOp.Operator == ".." {
+ if from, ok := rangeOp.Left.(*IntegerNode); ok {
+ if to, ok := rangeOp.Right.(*IntegerNode); ok {
+ patchCopyType(node, &BinaryNode{
+ Operator: "and",
+ Left: &BinaryNode{
+ Operator: ">=",
+ Left: n.Left,
+ Right: from,
+ },
+ Right: &BinaryNode{
+ Operator: "<=",
+ Left: n.Left,
+ Right: to,
+ },
+ })
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/github.com/expr-lang/expr/optimizer/optimizer.go b/vendor/github.com/expr-lang/expr/optimizer/optimizer.go
new file mode 100644
index 0000000..9a9677c
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/optimizer/optimizer.go
@@ -0,0 +1,79 @@
+package optimizer
+
+import (
+ "fmt"
+ "reflect"
+
+ . "github.com/expr-lang/expr/ast"
+ "github.com/expr-lang/expr/conf"
+)
+
+func Optimize(node *Node, config *conf.Config) error {
+ Walk(node, &inArray{})
+ for limit := 1000; limit >= 0; limit-- {
+ fold := &fold{}
+ Walk(node, fold)
+ if fold.err != nil {
+ return fold.err
+ }
+ if !fold.applied {
+ break
+ }
+ }
+ if config != nil && len(config.ConstFns) > 0 {
+ for limit := 100; limit >= 0; limit-- {
+ constExpr := &constExpr{
+ fns: config.ConstFns,
+ }
+ Walk(node, constExpr)
+ if constExpr.err != nil {
+ return constExpr.err
+ }
+ if !constExpr.applied {
+ break
+ }
+ }
+ }
+ Walk(node, &inRange{})
+ Walk(node, &filterMap{})
+ Walk(node, &filterLen{})
+ Walk(node, &filterLast{})
+ Walk(node, &filterFirst{})
+ Walk(node, &predicateCombination{})
+ Walk(node, &sumArray{})
+ Walk(node, &sumMap{})
+ return nil
+}
+
+var (
+ boolType = reflect.TypeOf(true)
+ integerType = reflect.TypeOf(0)
+ floatType = reflect.TypeOf(float64(0))
+ stringType = reflect.TypeOf("")
+)
+
+func patchWithType(node *Node, newNode Node) {
+ switch n := newNode.(type) {
+ case *BoolNode:
+ newNode.SetType(boolType)
+ case *IntegerNode:
+ newNode.SetType(integerType)
+ case *FloatNode:
+ newNode.SetType(floatType)
+ case *StringNode:
+ newNode.SetType(stringType)
+ case *ConstantNode:
+ newNode.SetType(reflect.TypeOf(n.Value))
+ case *BinaryNode:
+ newNode.SetType(n.Type())
+ default:
+ panic(fmt.Sprintf("unknown type %T", newNode))
+ }
+ Patch(node, newNode)
+}
+
+func patchCopyType(node *Node, newNode Node) {
+ t := (*node).Type()
+ newNode.SetType(t)
+ Patch(node, newNode)
+}
diff --git a/vendor/github.com/expr-lang/expr/optimizer/predicate_combination.go b/vendor/github.com/expr-lang/expr/optimizer/predicate_combination.go
new file mode 100644
index 0000000..65f88e3
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/optimizer/predicate_combination.go
@@ -0,0 +1,61 @@
+package optimizer
+
+import (
+ . "github.com/expr-lang/expr/ast"
+ "github.com/expr-lang/expr/parser/operator"
+)
+
+/*
+predicateCombination is a visitor that combines multiple predicate calls into a single call.
+For example, the following expression:
+
+ all(x, x > 1) && all(x, x < 10) -> all(x, x > 1 && x < 10)
+ any(x, x > 1) || any(x, x < 10) -> any(x, x > 1 || x < 10)
+ none(x, x > 1) && none(x, x < 10) -> none(x, x > 1 || x < 10)
+*/
+type predicateCombination struct{}
+
+func (v *predicateCombination) Visit(node *Node) {
+ if op, ok := (*node).(*BinaryNode); ok && operator.IsBoolean(op.Operator) {
+ if left, ok := op.Left.(*BuiltinNode); ok {
+ if combinedOp, ok := combinedOperator(left.Name, op.Operator); ok {
+ if right, ok := op.Right.(*BuiltinNode); ok && right.Name == left.Name {
+ if left.Arguments[0].Type() == right.Arguments[0].Type() && left.Arguments[0].String() == right.Arguments[0].String() {
+ predicate := &PredicateNode{
+ Node: &BinaryNode{
+ Operator: combinedOp,
+ Left: left.Arguments[1].(*PredicateNode).Node,
+ Right: right.Arguments[1].(*PredicateNode).Node,
+ },
+ }
+ v.Visit(&predicate.Node)
+ patchCopyType(node, &BuiltinNode{
+ Name: left.Name,
+ Arguments: []Node{
+ left.Arguments[0],
+ predicate,
+ },
+ })
+ }
+ }
+ }
+ }
+ }
+}
+
+func combinedOperator(fn, op string) (string, bool) {
+ switch {
+ case fn == "all" && (op == "and" || op == "&&"):
+ return op, true
+ case fn == "any" && (op == "or" || op == "||"):
+ return op, true
+ case fn == "none" && (op == "and" || op == "&&"):
+ switch op {
+ case "and":
+ return "or", true
+ case "&&":
+ return "||", true
+ }
+ }
+ return "", false
+}
diff --git a/vendor/github.com/expr-lang/expr/optimizer/sum_array.go b/vendor/github.com/expr-lang/expr/optimizer/sum_array.go
new file mode 100644
index 0000000..3c96795
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/optimizer/sum_array.go
@@ -0,0 +1,37 @@
+package optimizer
+
+import (
+ "fmt"
+
+ . "github.com/expr-lang/expr/ast"
+)
+
+type sumArray struct{}
+
+func (*sumArray) Visit(node *Node) {
+ if sumBuiltin, ok := (*node).(*BuiltinNode); ok &&
+ sumBuiltin.Name == "sum" &&
+ len(sumBuiltin.Arguments) == 1 {
+ if array, ok := sumBuiltin.Arguments[0].(*ArrayNode); ok &&
+ len(array.Nodes) >= 2 {
+ patchCopyType(node, sumArrayFold(array))
+ }
+ }
+}
+
+func sumArrayFold(array *ArrayNode) *BinaryNode {
+ if len(array.Nodes) > 2 {
+ return &BinaryNode{
+ Operator: "+",
+ Left: array.Nodes[0],
+ Right: sumArrayFold(&ArrayNode{Nodes: array.Nodes[1:]}),
+ }
+ } else if len(array.Nodes) == 2 {
+ return &BinaryNode{
+ Operator: "+",
+ Left: array.Nodes[0],
+ Right: array.Nodes[1],
+ }
+ }
+ panic(fmt.Errorf("sumArrayFold: invalid array length %d", len(array.Nodes)))
+}
diff --git a/vendor/github.com/expr-lang/expr/optimizer/sum_map.go b/vendor/github.com/expr-lang/expr/optimizer/sum_map.go
new file mode 100644
index 0000000..6de97d3
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/optimizer/sum_map.go
@@ -0,0 +1,25 @@
+package optimizer
+
+import (
+ . "github.com/expr-lang/expr/ast"
+)
+
+type sumMap struct{}
+
+func (*sumMap) Visit(node *Node) {
+ if sumBuiltin, ok := (*node).(*BuiltinNode); ok &&
+ sumBuiltin.Name == "sum" &&
+ len(sumBuiltin.Arguments) == 1 {
+ if mapBuiltin, ok := sumBuiltin.Arguments[0].(*BuiltinNode); ok &&
+ mapBuiltin.Name == "map" &&
+ len(mapBuiltin.Arguments) == 2 {
+ patchCopyType(node, &BuiltinNode{
+ Name: "sum",
+ Arguments: []Node{
+ mapBuiltin.Arguments[0],
+ mapBuiltin.Arguments[1],
+ },
+ })
+ }
+ }
+}
diff --git a/vendor/github.com/expr-lang/expr/parser/lexer/lexer.go b/vendor/github.com/expr-lang/expr/parser/lexer/lexer.go
new file mode 100644
index 0000000..e6b06c0
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/parser/lexer/lexer.go
@@ -0,0 +1,230 @@
+package lexer
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/expr-lang/expr/file"
+)
+
+func Lex(source file.Source) ([]Token, error) {
+ l := &lexer{
+ source: source,
+ tokens: make([]Token, 0),
+ start: 0,
+ end: 0,
+ }
+ l.commit()
+
+ for state := root; state != nil; {
+ state = state(l)
+ }
+
+ if l.err != nil {
+ return nil, l.err.Bind(source)
+ }
+
+ return l.tokens, nil
+}
+
+type lexer struct {
+ source file.Source
+ tokens []Token
+ start, end int
+ err *file.Error
+}
+
+const eof rune = -1
+
+func (l *lexer) commit() {
+ l.start = l.end
+}
+
+func (l *lexer) next() rune {
+ if l.end >= len(l.source) {
+ l.end++
+ return eof
+ }
+ r := l.source[l.end]
+ l.end++
+ return r
+}
+
+func (l *lexer) peek() rune {
+ r := l.next()
+ l.backup()
+ return r
+}
+
+func (l *lexer) backup() {
+ l.end--
+}
+
+func (l *lexer) emit(t Kind) {
+ l.emitValue(t, l.word())
+}
+
+func (l *lexer) emitValue(t Kind, value string) {
+ l.tokens = append(l.tokens, Token{
+ Location: file.Location{From: l.start, To: l.end},
+ Kind: t,
+ Value: value,
+ })
+ l.commit()
+}
+
+func (l *lexer) emitEOF() {
+ from := l.end - 2
+ if from < 0 {
+ from = 0
+ }
+ to := l.end - 1
+ if to < 0 {
+ to = 0
+ }
+ l.tokens = append(l.tokens, Token{
+ Location: file.Location{From: from, To: to},
+ Kind: EOF,
+ })
+ l.commit()
+}
+
+func (l *lexer) skip() {
+ l.commit()
+}
+
+func (l *lexer) word() string {
+ // TODO: boundary check is NOT needed here, but for some reason CI fuzz tests are failing.
+ if l.start > len(l.source) || l.end > len(l.source) {
+ return "__invalid__"
+ }
+ return string(l.source[l.start:l.end])
+}
+
+func (l *lexer) accept(valid string) bool {
+ if strings.ContainsRune(valid, l.next()) {
+ return true
+ }
+ l.backup()
+ return false
+}
+
+func (l *lexer) acceptRun(valid string) {
+ for strings.ContainsRune(valid, l.next()) {
+ }
+ l.backup()
+}
+
+func (l *lexer) skipSpaces() {
+ r := l.peek()
+ for ; r == ' '; r = l.peek() {
+ l.next()
+ }
+ l.skip()
+}
+
+func (l *lexer) acceptWord(word string) bool {
+ pos := l.end
+
+ l.skipSpaces()
+
+ for _, ch := range word {
+ if l.next() != ch {
+ l.end = pos
+ return false
+ }
+ }
+ if r := l.peek(); r != ' ' && r != eof {
+ l.end = pos
+ return false
+ }
+
+ return true
+}
+
+func (l *lexer) error(format string, args ...any) stateFn {
+ if l.err == nil { // show first error
+ l.err = &file.Error{
+ Location: file.Location{
+ From: l.end - 1,
+ To: l.end,
+ },
+ Message: fmt.Sprintf(format, args...),
+ }
+ }
+ return nil
+}
+
+func digitVal(ch rune) int {
+ switch {
+ case '0' <= ch && ch <= '9':
+ return int(ch - '0')
+ case 'a' <= lower(ch) && lower(ch) <= 'f':
+ return int(lower(ch) - 'a' + 10)
+ }
+ return 16 // larger than any legal digit val
+}
+
+func lower(ch rune) rune { return ('a' - 'A') | ch } // returns lower-case ch iff ch is ASCII letter
+
+func (l *lexer) scanDigits(ch rune, base, n int) rune {
+ for n > 0 && digitVal(ch) < base {
+ ch = l.next()
+ n--
+ }
+ if n > 0 {
+ l.error("invalid char escape")
+ }
+ return ch
+}
+
+func (l *lexer) scanEscape(quote rune) rune {
+ ch := l.next() // read character after '/'
+ switch ch {
+ case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', quote:
+ // nothing to do
+ ch = l.next()
+ case '0', '1', '2', '3', '4', '5', '6', '7':
+ ch = l.scanDigits(ch, 8, 3)
+ case 'x':
+ ch = l.scanDigits(l.next(), 16, 2)
+ case 'u':
+ ch = l.scanDigits(l.next(), 16, 4)
+ case 'U':
+ ch = l.scanDigits(l.next(), 16, 8)
+ default:
+ l.error("invalid char escape")
+ }
+ return ch
+}
+
+func (l *lexer) scanString(quote rune) (n int) {
+ ch := l.next() // read character after quote
+ for ch != quote {
+ if ch == '\n' || ch == eof {
+ l.error("literal not terminated")
+ return
+ }
+ if ch == '\\' {
+ ch = l.scanEscape(quote)
+ } else {
+ ch = l.next()
+ }
+ n++
+ }
+ return
+}
+
+func (l *lexer) scanRawString(quote rune) (n int) {
+ ch := l.next() // read character after back tick
+ for ch != quote {
+ if ch == eof {
+ l.error("literal not terminated")
+ return
+ }
+ ch = l.next()
+ n++
+ }
+ l.emitValue(String, string(l.source[l.start+1:l.end-1]))
+ return
+}
diff --git a/vendor/github.com/expr-lang/expr/parser/lexer/state.go b/vendor/github.com/expr-lang/expr/parser/lexer/state.go
new file mode 100644
index 0000000..c694a2c
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/parser/lexer/state.go
@@ -0,0 +1,226 @@
+package lexer
+
+import (
+ "strings"
+
+ "github.com/expr-lang/expr/parser/utils"
+)
+
+type stateFn func(*lexer) stateFn
+
+func root(l *lexer) stateFn {
+ switch r := l.next(); {
+ case r == eof:
+ l.emitEOF()
+ return nil
+ case utils.IsSpace(r):
+ l.skip()
+ return root
+ case r == '\'' || r == '"':
+ l.scanString(r)
+ str, err := unescape(l.word())
+ if err != nil {
+ l.error("%v", err)
+ }
+ l.emitValue(String, str)
+ case r == '`':
+ l.scanRawString(r)
+ case '0' <= r && r <= '9':
+ l.backup()
+ return number
+ case r == '?':
+ return questionMark
+ case r == '/':
+ return slash
+ case r == '#':
+ return pointer
+ case r == '|':
+ l.accept("|")
+ l.emit(Operator)
+ case r == ':':
+ l.accept(":")
+ l.emit(Operator)
+ case strings.ContainsRune("([{", r):
+ l.emit(Bracket)
+ case strings.ContainsRune(")]}", r):
+ l.emit(Bracket)
+ case strings.ContainsRune(",;%+-^", r): // single rune operator
+ l.emit(Operator)
+ case strings.ContainsRune("&!=*<>", r): // possible double rune operator
+ l.accept("&=*")
+ l.emit(Operator)
+ case r == '.':
+ l.backup()
+ return dot
+ case utils.IsAlphaNumeric(r):
+ l.backup()
+ return identifier
+ default:
+ return l.error("unrecognized character: %#U", r)
+ }
+ return root
+}
+
+func number(l *lexer) stateFn {
+ if !l.scanNumber() {
+ return l.error("bad number syntax: %q", l.word())
+ }
+ l.emit(Number)
+ return root
+}
+
+func (l *lexer) scanNumber() bool {
+ digits := "0123456789_"
+ // Is it hex?
+ if l.accept("0") {
+ // Note: Leading 0 does not mean octal in floats.
+ if l.accept("xX") {
+ digits = "0123456789abcdefABCDEF_"
+ } else if l.accept("oO") {
+ digits = "01234567_"
+ } else if l.accept("bB") {
+ digits = "01_"
+ }
+ }
+ l.acceptRun(digits)
+ end := l.end
+ if l.accept(".") {
+ // Lookup for .. operator: if after dot there is another dot (1..2), it maybe a range operator.
+ if l.peek() == '.' {
+ // We can't backup() here, as it would require two backups,
+ // and backup() func supports only one for now. So, save and
+ // restore it here.
+ l.end = end
+ return true
+ }
+ l.acceptRun(digits)
+ }
+ if l.accept("eE") {
+ l.accept("+-")
+ l.acceptRun(digits)
+ }
+ // Next thing mustn't be alphanumeric.
+ if utils.IsAlphaNumeric(l.peek()) {
+ l.next()
+ return false
+ }
+ return true
+}
+
+func dot(l *lexer) stateFn {
+ l.next()
+ if l.accept("0123456789") {
+ l.backup()
+ return number
+ }
+ l.accept(".")
+ l.emit(Operator)
+ return root
+}
+
+func identifier(l *lexer) stateFn {
+loop:
+ for {
+ switch r := l.next(); {
+ case utils.IsAlphaNumeric(r):
+ // absorb
+ default:
+ l.backup()
+ switch l.word() {
+ case "not":
+ return not
+ case "in", "or", "and", "matches", "contains", "startsWith", "endsWith", "let", "if", "else":
+ l.emit(Operator)
+ default:
+ l.emit(Identifier)
+ }
+ break loop
+ }
+ }
+ return root
+}
+
+func not(l *lexer) stateFn {
+ l.emit(Operator)
+
+ l.skipSpaces()
+
+ end := l.end
+
+ // Get the next word.
+ for {
+ r := l.next()
+ if utils.IsAlphaNumeric(r) {
+ // absorb
+ } else {
+ l.backup()
+ break
+ }
+ }
+
+ switch l.word() {
+ case "in", "matches", "contains", "startsWith", "endsWith":
+ l.emit(Operator)
+ default:
+ l.end = end
+ }
+ return root
+}
+
+func questionMark(l *lexer) stateFn {
+ l.accept(".?")
+ l.emit(Operator)
+ return root
+}
+
+func slash(l *lexer) stateFn {
+ if l.accept("/") {
+ return singleLineComment
+ }
+ if l.accept("*") {
+ return multiLineComment
+ }
+ l.emit(Operator)
+ return root
+}
+
+func singleLineComment(l *lexer) stateFn {
+ for {
+ r := l.next()
+ if r == eof || r == '\n' {
+ break
+ }
+ }
+ l.skip()
+ return root
+}
+
+func multiLineComment(l *lexer) stateFn {
+ for {
+ r := l.next()
+ if r == eof {
+ return l.error("unclosed comment")
+ }
+ if r == '*' && l.accept("/") {
+ break
+ }
+ }
+ l.skip()
+ return root
+}
+
+func pointer(l *lexer) stateFn {
+ l.accept("#")
+ l.emit(Operator)
+ for {
+ switch r := l.next(); {
+ case utils.IsAlphaNumeric(r): // absorb
+ default:
+ l.backup()
+ if l.word() != "" {
+ l.emit(Identifier)
+ }
+ return root
+ }
+ }
+}
diff --git a/vendor/github.com/expr-lang/expr/parser/lexer/token.go b/vendor/github.com/expr-lang/expr/parser/lexer/token.go
new file mode 100644
index 0000000..459fa69
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/parser/lexer/token.go
@@ -0,0 +1,47 @@
+package lexer
+
+import (
+ "fmt"
+
+ "github.com/expr-lang/expr/file"
+)
+
+type Kind string
+
+const (
+ Identifier Kind = "Identifier"
+ Number Kind = "Number"
+ String Kind = "String"
+ Operator Kind = "Operator"
+ Bracket Kind = "Bracket"
+ EOF Kind = "EOF"
+)
+
+type Token struct {
+ file.Location
+ Kind Kind
+ Value string
+}
+
+func (t Token) String() string {
+ if t.Value == "" {
+ return string(t.Kind)
+ }
+ return fmt.Sprintf("%s(%#v)", t.Kind, t.Value)
+}
+
+func (t Token) Is(kind Kind, values ...string) bool {
+ if len(values) == 0 {
+ return kind == t.Kind
+ }
+
+ for _, v := range values {
+ if v == t.Value {
+ goto found
+ }
+ }
+ return false
+
+found:
+ return kind == t.Kind
+}
diff --git a/vendor/github.com/expr-lang/expr/parser/lexer/utils.go b/vendor/github.com/expr-lang/expr/parser/lexer/utils.go
new file mode 100644
index 0000000..5c9e6b5
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/parser/lexer/utils.go
@@ -0,0 +1,186 @@
+package lexer
+
+import (
+ "fmt"
+ "math"
+ "strings"
+ "unicode/utf8"
+)
+
+var (
+ newlineNormalizer = strings.NewReplacer("\r\n", "\n", "\r", "\n")
+)
+
+// Unescape takes a quoted string, unquotes, and unescapes it.
+func unescape(value string) (string, error) {
+ // All strings normalize newlines to the \n representation.
+ value = newlineNormalizer.Replace(value)
+ n := len(value)
+
+ // Nothing to unescape / decode.
+ if n < 2 {
+ return value, fmt.Errorf("unable to unescape string")
+ }
+
+ // Quoted string of some form, must have same first and last char.
+ if value[0] != value[n-1] || (value[0] != '"' && value[0] != '\'') {
+ return value, fmt.Errorf("unable to unescape string")
+ }
+
+ value = value[1 : n-1]
+
+ // The string contains escape characters.
+ // The following logic is adapted from `strconv/quote.go`
+ var runeTmp [utf8.UTFMax]byte
+ size := 3 * uint64(n) / 2
+ if size >= math.MaxInt {
+ return "", fmt.Errorf("too large string")
+ }
+ buf := make([]byte, 0, size)
+ for len(value) > 0 {
+ c, multibyte, rest, err := unescapeChar(value)
+ if err != nil {
+ return "", err
+ }
+ value = rest
+ if c < utf8.RuneSelf || !multibyte {
+ buf = append(buf, byte(c))
+ } else {
+ n := utf8.EncodeRune(runeTmp[:], c)
+ buf = append(buf, runeTmp[:n]...)
+ }
+ }
+ return string(buf), nil
+}
+
+// unescapeChar takes a string input and returns the following info:
+//
+// value - the escaped unicode rune at the front of the string.
+// multibyte - whether the rune value might require multiple bytes to represent.
+// tail - the remainder of the input string.
+// err - error value, if the character could not be unescaped.
+//
+// When multibyte is true the return value may still fit within a single byte,
+// but a multibyte conversion is attempted which is more expensive than when the
+// value is known to fit within one byte.
+func unescapeChar(s string) (value rune, multibyte bool, tail string, err error) {
+ // 1. Character is not an escape sequence.
+ switch c := s[0]; {
+ case c >= utf8.RuneSelf:
+ r, size := utf8.DecodeRuneInString(s)
+ return r, true, s[size:], nil
+ case c != '\\':
+ return rune(s[0]), false, s[1:], nil
+ }
+
+ // 2. Last character is the start of an escape sequence.
+ if len(s) <= 1 {
+ err = fmt.Errorf("unable to unescape string, found '\\' as last character")
+ return
+ }
+
+ c := s[1]
+ s = s[2:]
+ // 3. Common escape sequences shared with Google SQL
+ switch c {
+ case 'a':
+ value = '\a'
+ case 'b':
+ value = '\b'
+ case 'f':
+ value = '\f'
+ case 'n':
+ value = '\n'
+ case 'r':
+ value = '\r'
+ case 't':
+ value = '\t'
+ case 'v':
+ value = '\v'
+ case '\\':
+ value = '\\'
+ case '\'':
+ value = '\''
+ case '"':
+ value = '"'
+ case '`':
+ value = '`'
+ case '?':
+ value = '?'
+
+ // 4. Unicode escape sequences, reproduced from `strconv/quote.go`
+ case 'x', 'X', 'u', 'U':
+ n := 0
+ switch c {
+ case 'x', 'X':
+ n = 2
+ case 'u':
+ n = 4
+ case 'U':
+ n = 8
+ }
+ var v rune
+ if len(s) < n {
+ err = fmt.Errorf("unable to unescape string")
+ return
+ }
+ for j := 0; j < n; j++ {
+ x, ok := unhex(s[j])
+ if !ok {
+ err = fmt.Errorf("unable to unescape string")
+ return
+ }
+ v = v<<4 | x
+ }
+ s = s[n:]
+ if v > utf8.MaxRune {
+ err = fmt.Errorf("unable to unescape string")
+ return
+ }
+ value = v
+ multibyte = true
+
+ // 5. Octal escape sequences, must be three digits \[0-3][0-7][0-7]
+ case '0', '1', '2', '3':
+ if len(s) < 2 {
+ err = fmt.Errorf("unable to unescape octal sequence in string")
+ return
+ }
+ v := rune(c - '0')
+ for j := 0; j < 2; j++ {
+ x := s[j]
+ if x < '0' || x > '7' {
+ err = fmt.Errorf("unable to unescape octal sequence in string")
+ return
+ }
+ v = v*8 + rune(x-'0')
+ }
+ if v > utf8.MaxRune {
+ err = fmt.Errorf("unable to unescape string")
+ return
+ }
+ value = v
+ s = s[2:]
+ multibyte = true
+
+ // Unknown escape sequence.
+ default:
+ err = fmt.Errorf("unable to unescape string")
+ }
+
+ tail = s
+ return
+}
+
+func unhex(b byte) (rune, bool) {
+ c := rune(b)
+ switch {
+ case '0' <= c && c <= '9':
+ return c - '0', true
+ case 'a' <= c && c <= 'f':
+ return c - 'a' + 10, true
+ case 'A' <= c && c <= 'F':
+ return c - 'A' + 10, true
+ }
+ return 0, false
+}
diff --git a/vendor/github.com/expr-lang/expr/parser/operator/operator.go b/vendor/github.com/expr-lang/expr/parser/operator/operator.go
new file mode 100644
index 0000000..4eeaf80
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/parser/operator/operator.go
@@ -0,0 +1,69 @@
+package operator
+
+type Associativity int
+
+const (
+ Left Associativity = iota + 1
+ Right
+)
+
+type Operator struct {
+ Precedence int
+ Associativity Associativity
+}
+
+func Less(a, b string) bool {
+ return Binary[a].Precedence < Binary[b].Precedence
+}
+
+func IsBoolean(op string) bool {
+ return op == "and" || op == "or" || op == "&&" || op == "||"
+}
+
+func AllowedNegateSuffix(op string) bool {
+ switch op {
+ case "contains", "matches", "startsWith", "endsWith", "in":
+ return true
+ default:
+ return false
+ }
+}
+
+var Unary = map[string]Operator{
+ "not": {50, Left},
+ "!": {50, Left},
+ "-": {90, Left},
+ "+": {90, Left},
+}
+
+var Binary = map[string]Operator{
+ "|": {0, Left},
+ "or": {10, Left},
+ "||": {10, Left},
+ "and": {15, Left},
+ "&&": {15, Left},
+ "==": {20, Left},
+ "!=": {20, Left},
+ "<": {20, Left},
+ ">": {20, Left},
+ ">=": {20, Left},
+ "<=": {20, Left},
+ "in": {20, Left},
+ "matches": {20, Left},
+ "contains": {20, Left},
+ "startsWith": {20, Left},
+ "endsWith": {20, Left},
+ "..": {25, Left},
+ "+": {30, Left},
+ "-": {30, Left},
+ "*": {60, Left},
+ "/": {60, Left},
+ "%": {60, Left},
+ "**": {100, Right},
+ "^": {100, Right},
+ "??": {500, Left},
+}
+
+func IsComparison(op string) bool {
+ return op == "<" || op == ">" || op == ">=" || op == "<="
+}
diff --git a/vendor/github.com/expr-lang/expr/parser/parser.go b/vendor/github.com/expr-lang/expr/parser/parser.go
new file mode 100644
index 0000000..5ba16d2
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/parser/parser.go
@@ -0,0 +1,883 @@
+package parser
+
+import (
+ "fmt"
+ "math"
+ "strconv"
+ "strings"
+
+ . "github.com/expr-lang/expr/ast"
+ "github.com/expr-lang/expr/builtin"
+ "github.com/expr-lang/expr/conf"
+ "github.com/expr-lang/expr/file"
+ . "github.com/expr-lang/expr/parser/lexer"
+ "github.com/expr-lang/expr/parser/operator"
+ "github.com/expr-lang/expr/parser/utils"
+)
+
+type arg byte
+
+const (
+ expr arg = 1 << iota
+ predicate
+)
+
+const optional arg = 1 << 7
+
+var predicates = map[string]struct {
+ args []arg
+}{
+ "all": {[]arg{expr, predicate}},
+ "none": {[]arg{expr, predicate}},
+ "any": {[]arg{expr, predicate}},
+ "one": {[]arg{expr, predicate}},
+ "filter": {[]arg{expr, predicate}},
+ "map": {[]arg{expr, predicate}},
+ "count": {[]arg{expr, predicate | optional}},
+ "sum": {[]arg{expr, predicate | optional}},
+ "find": {[]arg{expr, predicate}},
+ "findIndex": {[]arg{expr, predicate}},
+ "findLast": {[]arg{expr, predicate}},
+ "findLastIndex": {[]arg{expr, predicate}},
+ "groupBy": {[]arg{expr, predicate}},
+ "sortBy": {[]arg{expr, predicate, expr | optional}},
+ "reduce": {[]arg{expr, predicate, expr | optional}},
+}
+
+type parser struct {
+ tokens []Token
+ current Token
+ pos int
+ err *file.Error
+ config *conf.Config
+ depth int // predicate call depth
+ nodeCount uint // tracks number of AST nodes created
+}
+
+func (p *parser) checkNodeLimit() error {
+ p.nodeCount++
+ if p.config.MaxNodes > 0 && p.nodeCount > p.config.MaxNodes {
+ p.error("compilation failed: expression exceeds maximum allowed nodes")
+ return nil
+ }
+ return nil
+}
+
+func (p *parser) createNode(n Node, loc file.Location) Node {
+ if err := p.checkNodeLimit(); err != nil {
+ return nil
+ }
+ if n == nil || p.err != nil {
+ return nil
+ }
+ n.SetLocation(loc)
+ return n
+}
+
+func (p *parser) createMemberNode(n *MemberNode, loc file.Location) *MemberNode {
+ if err := p.checkNodeLimit(); err != nil {
+ return nil
+ }
+ if n == nil || p.err != nil {
+ return nil
+ }
+ n.SetLocation(loc)
+ return n
+}
+
+type Tree struct {
+ Node Node
+ Source file.Source
+}
+
+func Parse(input string) (*Tree, error) {
+ return ParseWithConfig(input, &conf.Config{
+ Disabled: map[string]bool{},
+ })
+}
+
+func ParseWithConfig(input string, config *conf.Config) (*Tree, error) {
+ source := file.NewSource(input)
+
+ tokens, err := Lex(source)
+ if err != nil {
+ return nil, err
+ }
+
+ p := &parser{
+ tokens: tokens,
+ current: tokens[0],
+ config: config,
+ }
+
+ node := p.parseSequenceExpression()
+
+ if !p.current.Is(EOF) {
+ p.error("unexpected token %v", p.current)
+ }
+
+ tree := &Tree{
+ Node: node,
+ Source: source,
+ }
+
+ if p.err != nil {
+ return tree, p.err.Bind(source)
+ }
+
+ return tree, nil
+}
+
+func (p *parser) error(format string, args ...any) {
+ p.errorAt(p.current, format, args...)
+}
+
+func (p *parser) errorAt(token Token, format string, args ...any) {
+ if p.err == nil { // show first error
+ p.err = &file.Error{
+ Location: token.Location,
+ Message: fmt.Sprintf(format, args...),
+ }
+ }
+}
+
+func (p *parser) next() {
+ p.pos++
+ if p.pos >= len(p.tokens) {
+ p.error("unexpected end of expression")
+ return
+ }
+ p.current = p.tokens[p.pos]
+}
+
+func (p *parser) expect(kind Kind, values ...string) {
+ if p.current.Is(kind, values...) {
+ p.next()
+ return
+ }
+ p.error("unexpected token %v", p.current)
+}
+
+// parse functions
+
+func (p *parser) parseSequenceExpression() Node {
+ nodes := []Node{p.parseExpression(0)}
+
+ for p.current.Is(Operator, ";") && p.err == nil {
+ p.next()
+ // If a trailing semicolon is present, break out.
+ if p.current.Is(EOF) {
+ break
+ }
+ nodes = append(nodes, p.parseExpression(0))
+ }
+
+ if len(nodes) == 1 {
+ return nodes[0]
+ }
+
+ return p.createNode(&SequenceNode{
+ Nodes: nodes,
+ }, nodes[0].Location())
+}
+
+func (p *parser) parseExpression(precedence int) Node {
+ if p.err != nil {
+ return nil
+ }
+
+ if precedence == 0 && p.current.Is(Operator, "let") {
+ return p.parseVariableDeclaration()
+ }
+
+ if precedence == 0 && p.current.Is(Operator, "if") {
+ return p.parseConditionalIf()
+ }
+
+ nodeLeft := p.parsePrimary()
+
+ prevOperator := ""
+ opToken := p.current
+ for opToken.Is(Operator) && p.err == nil {
+ negate := opToken.Is(Operator, "not")
+ var notToken Token
+
+ // Handle "not *" operator, like "not in" or "not contains".
+ if negate {
+ currentPos := p.pos
+ p.next()
+ if operator.AllowedNegateSuffix(p.current.Value) {
+ if op, ok := operator.Binary[p.current.Value]; ok && op.Precedence >= precedence {
+ notToken = p.current
+ opToken = p.current
+ } else {
+ p.pos = currentPos
+ p.current = opToken
+ break
+ }
+ } else {
+ p.error("unexpected token %v", p.current)
+ break
+ }
+ }
+
+ if op, ok := operator.Binary[opToken.Value]; ok && op.Precedence >= precedence {
+ p.next()
+
+ if opToken.Value == "|" {
+ identToken := p.current
+ p.expect(Identifier)
+ nodeLeft = p.parseCall(identToken, []Node{nodeLeft}, true)
+ goto next
+ }
+
+ if prevOperator == "??" && opToken.Value != "??" && !opToken.Is(Bracket, "(") {
+ p.errorAt(opToken, "Operator (%v) and coalesce expressions (??) cannot be mixed. Wrap either by parentheses.", opToken.Value)
+ break
+ }
+
+ if operator.IsComparison(opToken.Value) {
+ nodeLeft = p.parseComparison(nodeLeft, opToken, op.Precedence)
+ goto next
+ }
+
+ var nodeRight Node
+ if op.Associativity == operator.Left {
+ nodeRight = p.parseExpression(op.Precedence + 1)
+ } else {
+ nodeRight = p.parseExpression(op.Precedence)
+ }
+
+ nodeLeft = p.createNode(&BinaryNode{
+ Operator: opToken.Value,
+ Left: nodeLeft,
+ Right: nodeRight,
+ }, opToken.Location)
+ if nodeLeft == nil {
+ return nil
+ }
+
+ if negate {
+ nodeLeft = p.createNode(&UnaryNode{
+ Operator: "not",
+ Node: nodeLeft,
+ }, notToken.Location)
+ if nodeLeft == nil {
+ return nil
+ }
+ }
+
+ goto next
+ }
+ break
+
+ next:
+ prevOperator = opToken.Value
+ opToken = p.current
+ }
+
+ if precedence == 0 {
+ nodeLeft = p.parseConditional(nodeLeft)
+ }
+
+ return nodeLeft
+}
+
+func (p *parser) parseVariableDeclaration() Node {
+ p.expect(Operator, "let")
+ variableName := p.current
+ p.expect(Identifier)
+ p.expect(Operator, "=")
+ value := p.parseExpression(0)
+ p.expect(Operator, ";")
+ node := p.parseSequenceExpression()
+ return p.createNode(&VariableDeclaratorNode{
+ Name: variableName.Value,
+ Value: value,
+ Expr: node,
+ }, variableName.Location)
+}
+
+func (p *parser) parseConditionalIf() Node {
+ p.next()
+ nodeCondition := p.parseExpression(0)
+ p.expect(Bracket, "{")
+ expr1 := p.parseSequenceExpression()
+ p.expect(Bracket, "}")
+ p.expect(Operator, "else")
+ p.expect(Bracket, "{")
+ expr2 := p.parseSequenceExpression()
+ p.expect(Bracket, "}")
+
+ return &ConditionalNode{
+ Cond: nodeCondition,
+ Exp1: expr1,
+ Exp2: expr2,
+ }
+
+}
+
+func (p *parser) parseConditional(node Node) Node {
+ var expr1, expr2 Node
+ for p.current.Is(Operator, "?") && p.err == nil {
+ p.next()
+
+ if !p.current.Is(Operator, ":") {
+ expr1 = p.parseSequenceExpression()
+ p.expect(Operator, ":")
+ expr2 = p.parseSequenceExpression()
+ } else {
+ p.next()
+ expr1 = node
+ expr2 = p.parseSequenceExpression()
+ }
+
+ node = p.createNode(&ConditionalNode{
+ Cond: node,
+ Exp1: expr1,
+ Exp2: expr2,
+ }, p.current.Location)
+ if node == nil {
+ return nil
+ }
+ }
+ return node
+}
+
+func (p *parser) parsePrimary() Node {
+ token := p.current
+
+ if token.Is(Operator) {
+ if op, ok := operator.Unary[token.Value]; ok {
+ p.next()
+ expr := p.parseExpression(op.Precedence)
+ node := p.createNode(&UnaryNode{
+ Operator: token.Value,
+ Node: expr,
+ }, token.Location)
+ if node == nil {
+ return nil
+ }
+ return p.parsePostfixExpression(node)
+ }
+ }
+
+ if token.Is(Bracket, "(") {
+ p.next()
+ expr := p.parseSequenceExpression()
+ p.expect(Bracket, ")") // "an opened parenthesis is not properly closed"
+ return p.parsePostfixExpression(expr)
+ }
+
+ if p.depth > 0 {
+ if token.Is(Operator, "#") || token.Is(Operator, ".") {
+ name := ""
+ if token.Is(Operator, "#") {
+ p.next()
+ if p.current.Is(Identifier) {
+ name = p.current.Value
+ p.next()
+ }
+ }
+ node := p.createNode(&PointerNode{Name: name}, token.Location)
+ if node == nil {
+ return nil
+ }
+ return p.parsePostfixExpression(node)
+ }
+ }
+
+ if token.Is(Operator, "::") {
+ p.next()
+ token = p.current
+ p.expect(Identifier)
+ return p.parsePostfixExpression(p.parseCall(token, []Node{}, false))
+ }
+
+ return p.parseSecondary()
+}
+
+func (p *parser) parseSecondary() Node {
+ var node Node
+ token := p.current
+
+ switch token.Kind {
+
+ case Identifier:
+ p.next()
+ switch token.Value {
+ case "true":
+ node = p.createNode(&BoolNode{Value: true}, token.Location)
+ if node == nil {
+ return nil
+ }
+ return node
+ case "false":
+ node = p.createNode(&BoolNode{Value: false}, token.Location)
+ if node == nil {
+ return nil
+ }
+ return node
+ case "nil":
+ node = p.createNode(&NilNode{}, token.Location)
+ if node == nil {
+ return nil
+ }
+ return node
+ default:
+ if p.current.Is(Bracket, "(") {
+ node = p.parseCall(token, []Node{}, true)
+ } else {
+ node = p.createNode(&IdentifierNode{Value: token.Value}, token.Location)
+ if node == nil {
+ return nil
+ }
+ }
+ }
+
+ case Number:
+ p.next()
+ value := strings.Replace(token.Value, "_", "", -1)
+ var node Node
+ valueLower := strings.ToLower(value)
+ switch {
+ case strings.HasPrefix(valueLower, "0x"):
+ number, err := strconv.ParseInt(value, 0, 64)
+ if err != nil {
+ p.error("invalid hex literal: %v", err)
+ }
+ node = p.toIntegerNode(number)
+ case strings.ContainsAny(valueLower, ".e"):
+ number, err := strconv.ParseFloat(value, 64)
+ if err != nil {
+ p.error("invalid float literal: %v", err)
+ }
+ node = p.toFloatNode(number)
+ case strings.HasPrefix(valueLower, "0b"):
+ number, err := strconv.ParseInt(value, 0, 64)
+ if err != nil {
+ p.error("invalid binary literal: %v", err)
+ }
+ node = p.toIntegerNode(number)
+ case strings.HasPrefix(valueLower, "0o"):
+ number, err := strconv.ParseInt(value, 0, 64)
+ if err != nil {
+ p.error("invalid octal literal: %v", err)
+ }
+ node = p.toIntegerNode(number)
+ default:
+ number, err := strconv.ParseInt(value, 10, 64)
+ if err != nil {
+ p.error("invalid integer literal: %v", err)
+ }
+ node = p.toIntegerNode(number)
+ }
+ if node != nil {
+ node.SetLocation(token.Location)
+ }
+ return node
+ case String:
+ p.next()
+ node = p.createNode(&StringNode{Value: token.Value}, token.Location)
+ if node == nil {
+ return nil
+ }
+
+ default:
+ if token.Is(Bracket, "[") {
+ node = p.parseArrayExpression(token)
+ } else if token.Is(Bracket, "{") {
+ node = p.parseMapExpression(token)
+ } else {
+ p.error("unexpected token %v", token)
+ }
+ }
+
+ return p.parsePostfixExpression(node)
+}
+
+func (p *parser) toIntegerNode(number int64) Node {
+ if number > math.MaxInt {
+ p.error("integer literal is too large")
+ return nil
+ }
+ return p.createNode(&IntegerNode{Value: int(number)}, p.current.Location)
+}
+
+func (p *parser) toFloatNode(number float64) Node {
+ if number > math.MaxFloat64 {
+ p.error("float literal is too large")
+ return nil
+ }
+ return p.createNode(&FloatNode{Value: number}, p.current.Location)
+}
+
+func (p *parser) parseCall(token Token, arguments []Node, checkOverrides bool) Node {
+ var node Node
+
+ isOverridden := p.config.IsOverridden(token.Value)
+ isOverridden = isOverridden && checkOverrides
+
+ if b, ok := predicates[token.Value]; ok && !isOverridden {
+ p.expect(Bracket, "(")
+
+ // In case of the pipe operator, the first argument is the left-hand side
+ // of the operator, so we do not parse it as an argument inside brackets.
+ args := b.args[len(arguments):]
+
+ for i, arg := range args {
+ if arg&optional == optional {
+ if p.current.Is(Bracket, ")") {
+ break
+ }
+ } else {
+ if p.current.Is(Bracket, ")") {
+ p.error("expected at least %d arguments", len(args))
+ }
+ }
+
+ if i > 0 {
+ p.expect(Operator, ",")
+ }
+ var node Node
+ switch {
+ case arg&expr == expr:
+ node = p.parseExpression(0)
+ case arg&predicate == predicate:
+ node = p.parsePredicate()
+ }
+ arguments = append(arguments, node)
+ }
+
+ // skip last comma
+ if p.current.Is(Operator, ",") {
+ p.next()
+ }
+ p.expect(Bracket, ")")
+
+ node = p.createNode(&BuiltinNode{
+ Name: token.Value,
+ Arguments: arguments,
+ }, token.Location)
+ if node == nil {
+ return nil
+ }
+ } else if _, ok := builtin.Index[token.Value]; ok && !p.config.Disabled[token.Value] && !isOverridden {
+ node = p.createNode(&BuiltinNode{
+ Name: token.Value,
+ Arguments: p.parseArguments(arguments),
+ }, token.Location)
+ if node == nil {
+ return nil
+ }
+
+ } else {
+ callee := p.createNode(&IdentifierNode{Value: token.Value}, token.Location)
+ if callee == nil {
+ return nil
+ }
+ node = p.createNode(&CallNode{
+ Callee: callee,
+ Arguments: p.parseArguments(arguments),
+ }, token.Location)
+ if node == nil {
+ return nil
+ }
+ }
+ return node
+}
+
+func (p *parser) parseArguments(arguments []Node) []Node {
+ // If pipe operator is used, the first argument is the left-hand side
+ // of the operator, so we do not parse it as an argument inside brackets.
+ offset := len(arguments)
+
+ p.expect(Bracket, "(")
+ for !p.current.Is(Bracket, ")") && p.err == nil {
+ if len(arguments) > offset {
+ p.expect(Operator, ",")
+ }
+ if p.current.Is(Bracket, ")") {
+ break
+ }
+ node := p.parseExpression(0)
+ arguments = append(arguments, node)
+ }
+ p.expect(Bracket, ")")
+
+ return arguments
+}
+
+func (p *parser) parsePredicate() Node {
+ startToken := p.current
+ withBrackets := false
+ if p.current.Is(Bracket, "{") {
+ p.next()
+ withBrackets = true
+ }
+
+ p.depth++
+ var node Node
+ if withBrackets {
+ node = p.parseSequenceExpression()
+ } else {
+ node = p.parseExpression(0)
+ if p.current.Is(Operator, ";") {
+ p.error("wrap predicate with brackets { and }")
+ }
+ }
+ p.depth--
+
+ if withBrackets {
+ p.expect(Bracket, "}")
+ }
+ predicateNode := p.createNode(&PredicateNode{
+ Node: node,
+ }, startToken.Location)
+ if predicateNode == nil {
+ return nil
+ }
+ return predicateNode
+}
+
+func (p *parser) parseArrayExpression(token Token) Node {
+ nodes := make([]Node, 0)
+
+ p.expect(Bracket, "[")
+ for !p.current.Is(Bracket, "]") && p.err == nil {
+ if len(nodes) > 0 {
+ p.expect(Operator, ",")
+ if p.current.Is(Bracket, "]") {
+ goto end
+ }
+ }
+ node := p.parseExpression(0)
+ nodes = append(nodes, node)
+ }
+end:
+ p.expect(Bracket, "]")
+
+ node := p.createNode(&ArrayNode{Nodes: nodes}, token.Location)
+ if node == nil {
+ return nil
+ }
+ return node
+}
+
+func (p *parser) parseMapExpression(token Token) Node {
+ p.expect(Bracket, "{")
+
+ nodes := make([]Node, 0)
+ for !p.current.Is(Bracket, "}") && p.err == nil {
+ if len(nodes) > 0 {
+ p.expect(Operator, ",")
+ if p.current.Is(Bracket, "}") {
+ goto end
+ }
+ if p.current.Is(Operator, ",") {
+ p.error("unexpected token %v", p.current)
+ }
+ }
+
+ var key Node
+ // Map key can be one of:
+ // * number
+ // * string
+ // * identifier, which is equivalent to a string
+ // * expression, which must be enclosed in parentheses -- (1 + 2)
+ if p.current.Is(Number) || p.current.Is(String) || p.current.Is(Identifier) {
+ key = p.createNode(&StringNode{Value: p.current.Value}, p.current.Location)
+ if key == nil {
+ return nil
+ }
+ p.next()
+ } else if p.current.Is(Bracket, "(") {
+ key = p.parseExpression(0)
+ } else {
+ p.error("a map key must be a quoted string, a number, a identifier, or an expression enclosed in parentheses (unexpected token %v)", p.current)
+ }
+
+ p.expect(Operator, ":")
+
+ node := p.parseExpression(0)
+ pair := p.createNode(&PairNode{Key: key, Value: node}, token.Location)
+ if pair == nil {
+ return nil
+ }
+ nodes = append(nodes, pair)
+ }
+
+end:
+ p.expect(Bracket, "}")
+
+ node := p.createNode(&MapNode{Pairs: nodes}, token.Location)
+ if node == nil {
+ return nil
+ }
+ return node
+}
+
+func (p *parser) parsePostfixExpression(node Node) Node {
+ postfixToken := p.current
+ for (postfixToken.Is(Operator) || postfixToken.Is(Bracket)) && p.err == nil {
+ optional := postfixToken.Value == "?."
+ parseToken:
+ if postfixToken.Value == "." || postfixToken.Value == "?." {
+ p.next()
+
+ propertyToken := p.current
+ if optional && propertyToken.Is(Bracket, "[") {
+ postfixToken = propertyToken
+ goto parseToken
+ }
+ p.next()
+
+ if propertyToken.Kind != Identifier &&
+ // Operators like "not" and "matches" are valid methods or property names.
+ (propertyToken.Kind != Operator || !utils.IsValidIdentifier(propertyToken.Value)) {
+ p.error("expected name")
+ }
+
+ property := p.createNode(&StringNode{Value: propertyToken.Value}, propertyToken.Location)
+ if property == nil {
+ return nil
+ }
+
+ chainNode, isChain := node.(*ChainNode)
+ optional := postfixToken.Value == "?."
+
+ if isChain {
+ node = chainNode.Node
+ }
+
+ memberNode := p.createMemberNode(&MemberNode{
+ Node: node,
+ Property: property,
+ Optional: optional,
+ }, propertyToken.Location)
+ if memberNode == nil {
+ return nil
+ }
+
+ if p.current.Is(Bracket, "(") {
+ memberNode.Method = true
+ node = p.createNode(&CallNode{
+ Callee: memberNode,
+ Arguments: p.parseArguments([]Node{}),
+ }, propertyToken.Location)
+ if node == nil {
+ return nil
+ }
+ } else {
+ node = memberNode
+ }
+
+ if isChain || optional {
+ node = p.createNode(&ChainNode{Node: node}, propertyToken.Location)
+ if node == nil {
+ return nil
+ }
+ }
+
+ } else if postfixToken.Value == "[" {
+ p.next()
+ var from, to Node
+
+ if p.current.Is(Operator, ":") { // slice without from [:1]
+ p.next()
+
+ if !p.current.Is(Bracket, "]") { // slice without from and to [:]
+ to = p.parseExpression(0)
+ }
+
+ node = p.createNode(&SliceNode{
+ Node: node,
+ To: to,
+ }, postfixToken.Location)
+ if node == nil {
+ return nil
+ }
+ p.expect(Bracket, "]")
+
+ } else {
+
+ from = p.parseExpression(0)
+
+ if p.current.Is(Operator, ":") {
+ p.next()
+
+ if !p.current.Is(Bracket, "]") { // slice without to [1:]
+ to = p.parseExpression(0)
+ }
+
+ node = p.createNode(&SliceNode{
+ Node: node,
+ From: from,
+ To: to,
+ }, postfixToken.Location)
+ if node == nil {
+ return nil
+ }
+ p.expect(Bracket, "]")
+
+ } else {
+ // Slice operator [:] was not found,
+ // it should be just an index node.
+ node = p.createNode(&MemberNode{
+ Node: node,
+ Property: from,
+ Optional: optional,
+ }, postfixToken.Location)
+ if node == nil {
+ return nil
+ }
+ if optional {
+ node = p.createNode(&ChainNode{Node: node}, postfixToken.Location)
+ if node == nil {
+ return nil
+ }
+ }
+ p.expect(Bracket, "]")
+ }
+ }
+ } else {
+ break
+ }
+ postfixToken = p.current
+ }
+ return node
+}
+func (p *parser) parseComparison(left Node, token Token, precedence int) Node {
+ var rootNode Node
+ for {
+ comparator := p.parseExpression(precedence + 1)
+ cmpNode := p.createNode(&BinaryNode{
+ Operator: token.Value,
+ Left: left,
+ Right: comparator,
+ }, token.Location)
+ if cmpNode == nil {
+ return nil
+ }
+ if rootNode == nil {
+ rootNode = cmpNode
+ } else {
+ rootNode = p.createNode(&BinaryNode{
+ Operator: "&&",
+ Left: rootNode,
+ Right: cmpNode,
+ }, token.Location)
+ if rootNode == nil {
+ return nil
+ }
+ }
+
+ left = comparator
+ token = p.current
+ if !(token.Is(Operator) && operator.IsComparison(token.Value) && p.err == nil) {
+ break
+ }
+ p.next()
+ }
+ return rootNode
+}
diff --git a/vendor/github.com/expr-lang/expr/parser/utils/utils.go b/vendor/github.com/expr-lang/expr/parser/utils/utils.go
new file mode 100644
index 0000000..947f9a4
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/parser/utils/utils.go
@@ -0,0 +1,34 @@
+package utils
+
+import (
+ "unicode"
+ "unicode/utf8"
+)
+
+func IsValidIdentifier(str string) bool {
+ if len(str) == 0 {
+ return false
+ }
+ h, w := utf8.DecodeRuneInString(str)
+ if !IsAlphabetic(h) {
+ return false
+ }
+ for _, r := range str[w:] {
+ if !IsAlphaNumeric(r) {
+ return false
+ }
+ }
+ return true
+}
+
+func IsSpace(r rune) bool {
+ return unicode.IsSpace(r)
+}
+
+func IsAlphaNumeric(r rune) bool {
+ return IsAlphabetic(r) || unicode.IsDigit(r)
+}
+
+func IsAlphabetic(r rune) bool {
+ return r == '_' || r == '$' || unicode.IsLetter(r)
+}
diff --git a/vendor/github.com/expr-lang/expr/patcher/operator_override.go b/vendor/github.com/expr-lang/expr/patcher/operator_override.go
new file mode 100644
index 0000000..308cbdb
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/patcher/operator_override.go
@@ -0,0 +1,147 @@
+package patcher
+
+import (
+ "fmt"
+ "reflect"
+
+ "github.com/expr-lang/expr/ast"
+ "github.com/expr-lang/expr/builtin"
+ "github.com/expr-lang/expr/checker/nature"
+ "github.com/expr-lang/expr/conf"
+)
+
+type OperatorOverloading struct {
+ Operator string // Operator token to overload.
+ Overloads []string // List of function names to replace operator with.
+ Env *nature.Nature // Env type.
+ Functions conf.FunctionsTable // Env functions.
+ applied bool // Flag to indicate if any changes were made to the tree.
+}
+
+func (p *OperatorOverloading) Visit(node *ast.Node) {
+ binaryNode, ok := (*node).(*ast.BinaryNode)
+ if !ok {
+ return
+ }
+
+ if binaryNode.Operator != p.Operator {
+ return
+ }
+
+ leftType := binaryNode.Left.Type()
+ rightType := binaryNode.Right.Type()
+
+ ret, fn, ok := p.FindSuitableOperatorOverload(leftType, rightType)
+ if ok {
+ newNode := &ast.CallNode{
+ Callee: &ast.IdentifierNode{Value: fn},
+ Arguments: []ast.Node{binaryNode.Left, binaryNode.Right},
+ }
+ newNode.SetType(ret)
+ ast.Patch(node, newNode)
+ p.applied = true
+ }
+}
+
+// Tracking must be reset before every walk over the AST tree
+func (p *OperatorOverloading) Reset() {
+ p.applied = false
+}
+
+func (p *OperatorOverloading) ShouldRepeat() bool {
+ return p.applied
+}
+
+func (p *OperatorOverloading) FindSuitableOperatorOverload(l, r reflect.Type) (reflect.Type, string, bool) {
+ t, fn, ok := p.findSuitableOperatorOverloadInFunctions(l, r)
+ if !ok {
+ t, fn, ok = p.findSuitableOperatorOverloadInTypes(l, r)
+ }
+ return t, fn, ok
+}
+
+func (p *OperatorOverloading) findSuitableOperatorOverloadInTypes(l, r reflect.Type) (reflect.Type, string, bool) {
+ for _, fn := range p.Overloads {
+ fnType, ok := p.Env.Get(fn)
+ if !ok {
+ continue
+ }
+ firstInIndex := 0
+ if fnType.Method {
+ firstInIndex = 1 // As first argument to method is receiver.
+ }
+ ret, done := checkTypeSuits(fnType.Type, l, r, firstInIndex)
+ if done {
+ return ret, fn, true
+ }
+ }
+ return nil, "", false
+}
+
+func (p *OperatorOverloading) findSuitableOperatorOverloadInFunctions(l, r reflect.Type) (reflect.Type, string, bool) {
+ for _, fn := range p.Overloads {
+ fnType, ok := p.Functions[fn]
+ if !ok {
+ continue
+ }
+ firstInIndex := 0
+ for _, overload := range fnType.Types {
+ ret, done := checkTypeSuits(overload, l, r, firstInIndex)
+ if done {
+ return ret, fn, true
+ }
+ }
+ }
+ return nil, "", false
+}
+
+func checkTypeSuits(t reflect.Type, l reflect.Type, r reflect.Type, firstInIndex int) (reflect.Type, bool) {
+ firstArgType := t.In(firstInIndex)
+ secondArgType := t.In(firstInIndex + 1)
+
+ firstArgumentFit := l == firstArgType || (firstArgType.Kind() == reflect.Interface && (l == nil || l.Implements(firstArgType)))
+ secondArgumentFit := r == secondArgType || (secondArgType.Kind() == reflect.Interface && (r == nil || r.Implements(secondArgType)))
+ if firstArgumentFit && secondArgumentFit {
+ return t.Out(0), true
+ }
+ return nil, false
+}
+
+func (p *OperatorOverloading) Check() {
+ for _, fn := range p.Overloads {
+ fnType, foundType := p.Env.Get(fn)
+ fnFunc, foundFunc := p.Functions[fn]
+ if !foundFunc && (!foundType || fnType.Type.Kind() != reflect.Func) {
+ panic(fmt.Errorf("function %s for %s operator does not exist in the environment", fn, p.Operator))
+ }
+
+ if foundType {
+ checkType(fnType, fn, p.Operator)
+ }
+
+ if foundFunc {
+ checkFunc(fnFunc, fn, p.Operator)
+ }
+ }
+}
+
+func checkType(fnType nature.Nature, fn string, operator string) {
+ requiredNumIn := 2
+ if fnType.Method {
+ requiredNumIn = 3 // As first argument of method is receiver.
+ }
+ if fnType.Type.NumIn() != requiredNumIn || fnType.Type.NumOut() != 1 {
+ panic(fmt.Errorf("function %s for %s operator does not have a correct signature", fn, operator))
+ }
+}
+
+func checkFunc(fn *builtin.Function, name string, operator string) {
+ if len(fn.Types) == 0 {
+ panic(fmt.Errorf("function %q for %q operator misses types", name, operator))
+ }
+ for _, t := range fn.Types {
+ if t.NumIn() != 2 || t.NumOut() != 1 {
+ panic(fmt.Errorf("function %q for %q operator does not have a correct signature", name, operator))
+ }
+ }
+}
diff --git a/vendor/github.com/expr-lang/expr/patcher/with_context.go b/vendor/github.com/expr-lang/expr/patcher/with_context.go
new file mode 100644
index 0000000..f9861a2
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/patcher/with_context.go
@@ -0,0 +1,45 @@
+package patcher
+
+import (
+ "reflect"
+
+ "github.com/expr-lang/expr/ast"
+)
+
+// WithContext adds WithContext.Name argument to all functions calls with a context.Context argument.
+type WithContext struct {
+ Name string
+}
+
+// Visit adds WithContext.Name argument to all functions calls with a context.Context argument.
+func (w WithContext) Visit(node *ast.Node) {
+ switch call := (*node).(type) {
+ case *ast.CallNode:
+ fn := call.Callee.Type()
+ if fn == nil {
+ return
+ }
+ if fn.Kind() != reflect.Func {
+ return
+ }
+ switch fn.NumIn() {
+ case 0:
+ return
+ case 1:
+ if fn.In(0).String() != "context.Context" {
+ return
+ }
+ default:
+ if fn.In(0).String() != "context.Context" &&
+ fn.In(1).String() != "context.Context" {
+ return
+ }
+ }
+ ast.Patch(node, &ast.CallNode{
+ Callee: call.Callee,
+ Arguments: append([]ast.Node{
+ &ast.IdentifierNode{Value: w.Name},
+ }, call.Arguments...),
+ })
+ }
+}
diff --git a/vendor/github.com/expr-lang/expr/patcher/with_timezone.go b/vendor/github.com/expr-lang/expr/patcher/with_timezone.go
new file mode 100644
index 0000000..83eb28e
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/patcher/with_timezone.go
@@ -0,0 +1,25 @@
+package patcher
+
+import (
+ "time"
+
+ "github.com/expr-lang/expr/ast"
+)
+
+// WithTimezone passes Location to date() and now() functions.
+type WithTimezone struct {
+ Location *time.Location
+}
+
+func (t WithTimezone) Visit(node *ast.Node) {
+ if btin, ok := (*node).(*ast.BuiltinNode); ok {
+ switch btin.Name {
+ case "date", "now":
+ loc := &ast.ConstantNode{Value: t.Location}
+ ast.Patch(node, &ast.BuiltinNode{
+ Name: btin.Name,
+ Arguments: append([]ast.Node{loc}, btin.Arguments...),
+ })
+ }
+ }
+}
diff --git a/vendor/github.com/expr-lang/expr/types/types.go b/vendor/github.com/expr-lang/expr/types/types.go
new file mode 100644
index 0000000..bb1cbe5
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/types/types.go
@@ -0,0 +1,181 @@
+package types
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+
+ . "github.com/expr-lang/expr/checker/nature"
+)
+
+// Type is a type that can be used to represent a value.
+type Type interface {
+ Nature() Nature
+ Equal(Type) bool
+ String() string
+}
+
+var (
+ Int = TypeOf(0)
+ Int8 = TypeOf(int8(0))
+ Int16 = TypeOf(int16(0))
+ Int32 = TypeOf(int32(0))
+ Int64 = TypeOf(int64(0))
+ Uint = TypeOf(uint(0))
+ Uint8 = TypeOf(uint8(0))
+ Uint16 = TypeOf(uint16(0))
+ Uint32 = TypeOf(uint32(0))
+ Uint64 = TypeOf(uint64(0))
+ Float = TypeOf(float32(0))
+ Float64 = TypeOf(float64(0))
+ String = TypeOf("")
+ Bool = TypeOf(true)
+ Nil = nilType{}
+ Any = anyType{}
+)
+
+func TypeOf(v any) Type {
+ if v == nil {
+ return Nil
+ }
+ return rtype{t: reflect.TypeOf(v)}
+}
+
+type anyType struct{}
+
+func (anyType) Nature() Nature {
+ return Nature{Type: nil}
+}
+
+func (anyType) Equal(t Type) bool {
+ return true
+}
+
+func (anyType) String() string {
+ return "any"
+}
+
+type nilType struct{}
+
+func (nilType) Nature() Nature {
+ return Nature{Nil: true}
+}
+
+func (nilType) Equal(t Type) bool {
+ if t == Any {
+ return true
+ }
+ return t == Nil
+}
+
+func (nilType) String() string {
+ return "nil"
+}
+
+type rtype struct {
+ t reflect.Type
+}
+
+func (r rtype) Nature() Nature {
+ return Nature{Type: r.t}
+}
+
+func (r rtype) Equal(t Type) bool {
+ if t == Any {
+ return true
+ }
+ if rt, ok := t.(rtype); ok {
+ return r.t.String() == rt.t.String()
+ }
+ return false
+}
+
+func (r rtype) String() string {
+ return r.t.String()
+}
+
+// Map represents a map[string]any type with defined keys.
+type Map map[string]Type
+
+const Extra = "[[__extra_keys__]]"
+
+func (m Map) Nature() Nature {
+ nt := Nature{
+ Type: reflect.TypeOf(map[string]any{}),
+ Fields: make(map[string]Nature, len(m)),
+ Strict: true,
+ }
+ for k, v := range m {
+ if k == Extra {
+ nt.Strict = false
+ natureOfDefaultValue := v.Nature()
+ nt.DefaultMapValue = &natureOfDefaultValue
+ continue
+ }
+ nt.Fields[k] = v.Nature()
+ }
+ return nt
+}
+
+func (m Map) Equal(t Type) bool {
+ if t == Any {
+ return true
+ }
+ mt, ok := t.(Map)
+ if !ok {
+ return false
+ }
+ if len(m) != len(mt) {
+ return false
+ }
+ for k, v := range m {
+ if !v.Equal(mt[k]) {
+ return false
+ }
+ }
+ return true
+}
+
+func (m Map) String() string {
+ pairs := make([]string, 0, len(m))
+ for k, v := range m {
+ pairs = append(pairs, fmt.Sprintf("%s: %s", k, v.String()))
+ }
+ return fmt.Sprintf("Map{%s}", strings.Join(pairs, ", "))
+}
+
+// Array returns a type that represents an array of the given type.
+func Array(of Type) Type {
+ return array{of}
+}
+
+type array struct {
+ of Type
+}
+
+func (a array) Nature() Nature {
+ of := a.of.Nature()
+ return Nature{
+ Type: reflect.TypeOf([]any{}),
+ Fields: make(map[string]Nature, 1),
+ ArrayOf: &of,
+ }
+}
+
+func (a array) Equal(t Type) bool {
+ if t == Any {
+ return true
+ }
+ at, ok := t.(array)
+ if !ok {
+ return false
+ }
+ if a.of.Equal(at.of) {
+ return true
+ }
+ return false
+}
+
+func (a array) String() string {
+ return fmt.Sprintf("Array{%s}", a.of.String())
+}
diff --git a/vendor/github.com/expr-lang/expr/vm/debug.go b/vendor/github.com/expr-lang/expr/vm/debug.go
new file mode 100644
index 0000000..470bf90
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/vm/debug.go
@@ -0,0 +1,6 @@
+//go:build expr_debug
+// +build expr_debug
+
+package vm
+
+const debug = true
diff --git a/vendor/github.com/expr-lang/expr/vm/debug_off.go b/vendor/github.com/expr-lang/expr/vm/debug_off.go
new file mode 100644
index 0000000..8a9e965
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/vm/debug_off.go
@@ -0,0 +1,6 @@
+//go:build !expr_debug
+// +build !expr_debug
+
+package vm
+
+const debug = false
diff --git a/vendor/github.com/expr-lang/expr/vm/func_types[generated].go b/vendor/github.com/expr-lang/expr/vm/func_types[generated].go
new file mode 100644
index 0000000..610b415
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/vm/func_types[generated].go
@@ -0,0 +1,370 @@
+// Code generated by vm/func_types/main.go. DO NOT EDIT.
+
+package vm
+
+import (
+ "fmt"
+ "time"
+)
+
+var FuncTypes = []any{
+ 1: new(func() time.Duration),
+ 2: new(func() time.Month),
+ 3: new(func() time.Time),
+ 4: new(func() time.Weekday),
+ 5: new(func() []interface{}),
+ 6: new(func() []uint8),
+ 7: new(func() interface{}),
+ 8: new(func() bool),
+ 9: new(func() uint8),
+ 10: new(func() float32),
+ 11: new(func() float64),
+ 12: new(func() int),
+ 13: new(func() int16),
+ 14: new(func() int32),
+ 15: new(func() int64),
+ 16: new(func() int8),
+ 17: new(func() map[string]interface{}),
+ 18: new(func() int32),
+ 19: new(func() string),
+ 20: new(func() uint),
+ 21: new(func() uint16),
+ 22: new(func() uint32),
+ 23: new(func() uint64),
+ 24: new(func() uint8),
+ 25: new(func(time.Duration) time.Duration),
+ 26: new(func(time.Duration) time.Time),
+ 27: new(func(time.Time) time.Duration),
+ 28: new(func(time.Time) bool),
+ 29: new(func([]interface{}) []interface{}),
+ 30: new(func([]interface{}) interface{}),
+ 31: new(func([]interface{}) map[string]interface{}),
+ 32: new(func([]interface{}, string) string),
+ 33: new(func([]uint8) string),
+ 34: new(func([]string, string) string),
+ 35: new(func(interface{}) []interface{}),
+ 36: new(func(interface{}) interface{}),
+ 37: new(func(interface{}) bool),
+ 38: new(func(interface{}) float64),
+ 39: new(func(interface{}) int),
+ 40: new(func(interface{}) map[string]interface{}),
+ 41: new(func(interface{}) string),
+ 42: new(func(interface{}, interface{}) []interface{}),
+ 43: new(func(interface{}, interface{}) interface{}),
+ 44: new(func(interface{}, interface{}) bool),
+ 45: new(func(interface{}, interface{}) string),
+ 46: new(func(bool) bool),
+ 47: new(func(bool) float64),
+ 48: new(func(bool) int),
+ 49: new(func(bool) string),
+ 50: new(func(bool, bool) bool),
+ 51: new(func(float32) float64),
+ 52: new(func(float64) bool),
+ 53: new(func(float64) float32),
+ 54: new(func(float64) float64),
+ 55: new(func(float64) int),
+ 56: new(func(float64) string),
+ 57: new(func(float64, float64) bool),
+ 58: new(func(int) bool),
+ 59: new(func(int) float64),
+ 60: new(func(int) int),
+ 61: new(func(int) string),
+ 62: new(func(int, int) bool),
+ 63: new(func(int, int) int),
+ 64: new(func(int, int) string),
+ 65: new(func(int16) int32),
+ 66: new(func(int32) float64),
+ 67: new(func(int32) int),
+ 68: new(func(int32) int64),
+ 69: new(func(int64) time.Time),
+ 70: new(func(int8) int),
+ 71: new(func(int8) int16),
+ 72: new(func(string) []uint8),
+ 73: new(func(string) []string),
+ 74: new(func(string) bool),
+ 75: new(func(string) float64),
+ 76: new(func(string) int),
+ 77: new(func(string) string),
+ 78: new(func(string, uint8) int),
+ 79: new(func(string, int) int),
+ 80: new(func(string, int32) int),
+ 81: new(func(string, string) bool),
+ 82: new(func(string, string) string),
+ 83: new(func(uint) float64),
+ 84: new(func(uint) int),
+ 85: new(func(uint) uint),
+ 86: new(func(uint16) uint),
+ 87: new(func(uint32) uint64),
+ 88: new(func(uint64) float64),
+ 89: new(func(uint64) int64),
+ 90: new(func(uint8) uint8),
+}
+
+func (vm *VM) call(fn any, kind int) any {
+ switch kind {
+ case 1:
+ return fn.(func() time.Duration)()
+ case 2:
+ return fn.(func() time.Month)()
+ case 3:
+ return fn.(func() time.Time)()
+ case 4:
+ return fn.(func() time.Weekday)()
+ case 5:
+ return fn.(func() []interface{})()
+ case 6:
+ return fn.(func() []uint8)()
+ case 7:
+ return fn.(func() interface{})()
+ case 8:
+ return fn.(func() bool)()
+ case 9:
+ return fn.(func() uint8)()
+ case 10:
+ return fn.(func() float32)()
+ case 11:
+ return fn.(func() float64)()
+ case 12:
+ return fn.(func() int)()
+ case 13:
+ return fn.(func() int16)()
+ case 14:
+ return fn.(func() int32)()
+ case 15:
+ return fn.(func() int64)()
+ case 16:
+ return fn.(func() int8)()
+ case 17:
+ return fn.(func() map[string]interface{})()
+ case 18:
+ return fn.(func() int32)()
+ case 19:
+ return fn.(func() string)()
+ case 20:
+ return fn.(func() uint)()
+ case 21:
+ return fn.(func() uint16)()
+ case 22:
+ return fn.(func() uint32)()
+ case 23:
+ return fn.(func() uint64)()
+ case 24:
+ return fn.(func() uint8)()
+ case 25:
+ arg1 := vm.pop().(time.Duration)
+ return fn.(func(time.Duration) time.Duration)(arg1)
+ case 26:
+ arg1 := vm.pop().(time.Duration)
+ return fn.(func(time.Duration) time.Time)(arg1)
+ case 27:
+ arg1 := vm.pop().(time.Time)
+ return fn.(func(time.Time) time.Duration)(arg1)
+ case 28:
+ arg1 := vm.pop().(time.Time)
+ return fn.(func(time.Time) bool)(arg1)
+ case 29:
+ arg1 := vm.pop().([]interface{})
+ return fn.(func([]interface{}) []interface{})(arg1)
+ case 30:
+ arg1 := vm.pop().([]interface{})
+ return fn.(func([]interface{}) interface{})(arg1)
+ case 31:
+ arg1 := vm.pop().([]interface{})
+ return fn.(func([]interface{}) map[string]interface{})(arg1)
+ case 32:
+ arg2 := vm.pop().(string)
+ arg1 := vm.pop().([]interface{})
+ return fn.(func([]interface{}, string) string)(arg1, arg2)
+ case 33:
+ arg1 := vm.pop().([]uint8)
+ return fn.(func([]uint8) string)(arg1)
+ case 34:
+ arg2 := vm.pop().(string)
+ arg1 := vm.pop().([]string)
+ return fn.(func([]string, string) string)(arg1, arg2)
+ case 35:
+ arg1 := vm.pop()
+ return fn.(func(interface{}) []interface{})(arg1)
+ case 36:
+ arg1 := vm.pop()
+ return fn.(func(interface{}) interface{})(arg1)
+ case 37:
+ arg1 := vm.pop()
+ return fn.(func(interface{}) bool)(arg1)
+ case 38:
+ arg1 := vm.pop()
+ return fn.(func(interface{}) float64)(arg1)
+ case 39:
+ arg1 := vm.pop()
+ return fn.(func(interface{}) int)(arg1)
+ case 40:
+ arg1 := vm.pop()
+ return fn.(func(interface{}) map[string]interface{})(arg1)
+ case 41:
+ arg1 := vm.pop()
+ return fn.(func(interface{}) string)(arg1)
+ case 42:
+ arg2 := vm.pop()
+ arg1 := vm.pop()
+ return fn.(func(interface{}, interface{}) []interface{})(arg1, arg2)
+ case 43:
+ arg2 := vm.pop()
+ arg1 := vm.pop()
+ return fn.(func(interface{}, interface{}) interface{})(arg1, arg2)
+ case 44:
+ arg2 := vm.pop()
+ arg1 := vm.pop()
+ return fn.(func(interface{}, interface{}) bool)(arg1, arg2)
+ case 45:
+ arg2 := vm.pop()
+ arg1 := vm.pop()
+ return fn.(func(interface{}, interface{}) string)(arg1, arg2)
+ case 46:
+ arg1 := vm.pop().(bool)
+ return fn.(func(bool) bool)(arg1)
+ case 47:
+ arg1 := vm.pop().(bool)
+ return fn.(func(bool) float64)(arg1)
+ case 48:
+ arg1 := vm.pop().(bool)
+ return fn.(func(bool) int)(arg1)
+ case 49:
+ arg1 := vm.pop().(bool)
+ return fn.(func(bool) string)(arg1)
+ case 50:
+ arg2 := vm.pop().(bool)
+ arg1 := vm.pop().(bool)
+ return fn.(func(bool, bool) bool)(arg1, arg2)
+ case 51:
+ arg1 := vm.pop().(float32)
+ return fn.(func(float32) float64)(arg1)
+ case 52:
+ arg1 := vm.pop().(float64)
+ return fn.(func(float64) bool)(arg1)
+ case 53:
+ arg1 := vm.pop().(float64)
+ return fn.(func(float64) float32)(arg1)
+ case 54:
+ arg1 := vm.pop().(float64)
+ return fn.(func(float64) float64)(arg1)
+ case 55:
+ arg1 := vm.pop().(float64)
+ return fn.(func(float64) int)(arg1)
+ case 56:
+ arg1 := vm.pop().(float64)
+ return fn.(func(float64) string)(arg1)
+ case 57:
+ arg2 := vm.pop().(float64)
+ arg1 := vm.pop().(float64)
+ return fn.(func(float64, float64) bool)(arg1, arg2)
+ case 58:
+ arg1 := vm.pop().(int)
+ return fn.(func(int) bool)(arg1)
+ case 59:
+ arg1 := vm.pop().(int)
+ return fn.(func(int) float64)(arg1)
+ case 60:
+ arg1 := vm.pop().(int)
+ return fn.(func(int) int)(arg1)
+ case 61:
+ arg1 := vm.pop().(int)
+ return fn.(func(int) string)(arg1)
+ case 62:
+ arg2 := vm.pop().(int)
+ arg1 := vm.pop().(int)
+ return fn.(func(int, int) bool)(arg1, arg2)
+ case 63:
+ arg2 := vm.pop().(int)
+ arg1 := vm.pop().(int)
+ return fn.(func(int, int) int)(arg1, arg2)
+ case 64:
+ arg2 := vm.pop().(int)
+ arg1 := vm.pop().(int)
+ return fn.(func(int, int) string)(arg1, arg2)
+ case 65:
+ arg1 := vm.pop().(int16)
+ return fn.(func(int16) int32)(arg1)
+ case 66:
+ arg1 := vm.pop().(int32)
+ return fn.(func(int32) float64)(arg1)
+ case 67:
+ arg1 := vm.pop().(int32)
+ return fn.(func(int32) int)(arg1)
+ case 68:
+ arg1 := vm.pop().(int32)
+ return fn.(func(int32) int64)(arg1)
+ case 69:
+ arg1 := vm.pop().(int64)
+ return fn.(func(int64) time.Time)(arg1)
+ case 70:
+ arg1 := vm.pop().(int8)
+ return fn.(func(int8) int)(arg1)
+ case 71:
+ arg1 := vm.pop().(int8)
+ return fn.(func(int8) int16)(arg1)
+ case 72:
+ arg1 := vm.pop().(string)
+ return fn.(func(string) []uint8)(arg1)
+ case 73:
+ arg1 := vm.pop().(string)
+ return fn.(func(string) []string)(arg1)
+ case 74:
+ arg1 := vm.pop().(string)
+ return fn.(func(string) bool)(arg1)
+ case 75:
+ arg1 := vm.pop().(string)
+ return fn.(func(string) float64)(arg1)
+ case 76:
+ arg1 := vm.pop().(string)
+ return fn.(func(string) int)(arg1)
+ case 77:
+ arg1 := vm.pop().(string)
+ return fn.(func(string) string)(arg1)
+ case 78:
+ arg2 := vm.pop().(uint8)
+ arg1 := vm.pop().(string)
+ return fn.(func(string, uint8) int)(arg1, arg2)
+ case 79:
+ arg2 := vm.pop().(int)
+ arg1 := vm.pop().(string)
+ return fn.(func(string, int) int)(arg1, arg2)
+ case 80:
+ arg2 := vm.pop().(int32)
+ arg1 := vm.pop().(string)
+ return fn.(func(string, int32) int)(arg1, arg2)
+ case 81:
+ arg2 := vm.pop().(string)
+ arg1 := vm.pop().(string)
+ return fn.(func(string, string) bool)(arg1, arg2)
+ case 82:
+ arg2 := vm.pop().(string)
+ arg1 := vm.pop().(string)
+ return fn.(func(string, string) string)(arg1, arg2)
+ case 83:
+ arg1 := vm.pop().(uint)
+ return fn.(func(uint) float64)(arg1)
+ case 84:
+ arg1 := vm.pop().(uint)
+ return fn.(func(uint) int)(arg1)
+ case 85:
+ arg1 := vm.pop().(uint)
+ return fn.(func(uint) uint)(arg1)
+ case 86:
+ arg1 := vm.pop().(uint16)
+ return fn.(func(uint16) uint)(arg1)
+ case 87:
+ arg1 := vm.pop().(uint32)
+ return fn.(func(uint32) uint64)(arg1)
+ case 88:
+ arg1 := vm.pop().(uint64)
+ return fn.(func(uint64) float64)(arg1)
+ case 89:
+ arg1 := vm.pop().(uint64)
+ return fn.(func(uint64) int64)(arg1)
+ case 90:
+ arg1 := vm.pop().(uint8)
+ return fn.(func(uint8) uint8)(arg1)
+
+ }
+ panic(fmt.Sprintf("unknown function kind (%v)", kind))
+}
diff --git a/vendor/github.com/expr-lang/expr/vm/opcodes.go b/vendor/github.com/expr-lang/expr/vm/opcodes.go
new file mode 100644
index 0000000..84d751d
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/vm/opcodes.go
@@ -0,0 +1,88 @@
+package vm
+
+type Opcode byte
+
+const (
+ OpInvalid Opcode = iota
+ OpPush
+ OpInt
+ OpPop
+ OpStore
+ OpLoadVar
+ OpLoadConst
+ OpLoadField
+ OpLoadFast
+ OpLoadMethod
+ OpLoadFunc
+ OpLoadEnv
+ OpFetch
+ OpFetchField
+ OpMethod
+ OpTrue
+ OpFalse
+ OpNil
+ OpNegate
+ OpNot
+ OpEqual
+ OpEqualInt
+ OpEqualString
+ OpJump
+ OpJumpIfTrue
+ OpJumpIfFalse
+ OpJumpIfNil
+ OpJumpIfNotNil
+ OpJumpIfEnd
+ OpJumpBackward
+ OpIn
+ OpLess
+ OpMore
+ OpLessOrEqual
+ OpMoreOrEqual
+ OpAdd
+ OpSubtract
+ OpMultiply
+ OpDivide
+ OpModulo
+ OpExponent
+ OpRange
+ OpMatches
+ OpMatchesConst
+ OpContains
+ OpStartsWith
+ OpEndsWith
+ OpSlice
+ OpCall
+ OpCall0
+ OpCall1
+ OpCall2
+ OpCall3
+ OpCallN
+ OpCallFast
+ OpCallSafe
+ OpCallTyped
+ OpCallBuiltin1
+ OpArray
+ OpMap
+ OpLen
+ OpCast
+ OpDeref
+ OpIncrementIndex
+ OpDecrementIndex
+ OpIncrementCount
+ OpGetIndex
+ OpGetCount
+ OpGetLen
+ OpGetAcc
+ OpSetAcc
+ OpSetIndex
+ OpPointer
+ OpThrow
+ OpCreate
+ OpGroupBy
+ OpSortBy
+ OpSort
+ OpProfileStart
+ OpProfileEnd
+ OpBegin
+ OpEnd // This opcode must be at the end of this list.
+)
diff --git a/vendor/github.com/expr-lang/expr/vm/program.go b/vendor/github.com/expr-lang/expr/vm/program.go
new file mode 100644
index 0000000..15ce26f
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/vm/program.go
@@ -0,0 +1,382 @@
+package vm
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "reflect"
+ "regexp"
+ "strings"
+ "text/tabwriter"
+
+ "github.com/expr-lang/expr/ast"
+ "github.com/expr-lang/expr/builtin"
+ "github.com/expr-lang/expr/file"
+ "github.com/expr-lang/expr/vm/runtime"
+)
+
+// Program represents a compiled expression.
+type Program struct {
+ Bytecode []Opcode
+ Arguments []int
+ Constants []any
+
+ source file.Source
+ node ast.Node
+ locations []file.Location
+ variables int
+ functions []Function
+ debugInfo map[string]string
+ span *Span
+}
+
+// NewProgram returns a new Program. It's used by the compiler.
+func NewProgram(
+ source file.Source,
+ node ast.Node,
+ locations []file.Location,
+ variables int,
+ constants []any,
+ bytecode []Opcode,
+ arguments []int,
+ functions []Function,
+ debugInfo map[string]string,
+ span *Span,
+) *Program {
+ return &Program{
+ source: source,
+ node: node,
+ locations: locations,
+ variables: variables,
+ Constants: constants,
+ Bytecode: bytecode,
+ Arguments: arguments,
+ functions: functions,
+ debugInfo: debugInfo,
+ span: span,
+ }
+}
+
+// Source returns origin file.Source.
+func (program *Program) Source() file.Source {
+ return program.source
+}
+
+// Node returns origin ast.Node.
+func (program *Program) Node() ast.Node {
+ return program.node
+}
+
+// Locations returns a slice of bytecode's locations.
+func (program *Program) Locations() []file.Location {
+ return program.locations
+}
+
+// Disassemble returns opcodes as a string.
+func (program *Program) Disassemble() string {
+ var buf bytes.Buffer
+ w := tabwriter.NewWriter(&buf, 0, 0, 2, ' ', 0)
+ program.DisassembleWriter(w)
+ _ = w.Flush()
+ return buf.String()
+}
+
+// DisassembleWriter takes a writer and writes opcodes to it.
+func (program *Program) DisassembleWriter(w io.Writer) {
+ ip := 0
+ for ip < len(program.Bytecode) {
+ pp := ip
+ op := program.Bytecode[ip]
+ arg := program.Arguments[ip]
+ ip += 1
+
+ code := func(label string) {
+ _, _ = fmt.Fprintf(w, "%v\t%v\n", pp, label)
+ }
+ jump := func(label string) {
+ _, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\t(%v)\n", pp, label, arg, ip+arg)
+ }
+ jumpBack := func(label string) {
+ _, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\t(%v)\n", pp, label, arg, ip-arg)
+ }
+ argument := func(label string) {
+ _, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\n", pp, label, arg)
+ }
+ argumentWithInfo := func(label string, prefix string) {
+ _, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\t%v\n", pp, label, arg, program.debugInfo[fmt.Sprintf("%s_%d", prefix, arg)])
+ }
+ constant := func(label string) {
+ var c any
+ if arg < len(program.Constants) {
+ c = program.Constants[arg]
+ } else {
+ c = "out of range"
+ }
+ if r, ok := c.(*regexp.Regexp); ok {
+ c = r.String()
+ }
+ if field, ok := c.(*runtime.Field); ok {
+ c = fmt.Sprintf("{%v %v}", strings.Join(field.Path, "."), field.Index)
+ }
+ if method, ok := c.(*runtime.Method); ok {
+ c = fmt.Sprintf("{%v %v}", method.Name, method.Index)
+ }
+ _, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\t%v\n", pp, label, arg, c)
+ }
+ builtinArg := func(label string) {
+ _, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\t%v\n", pp, label, arg, builtin.Builtins[arg].Name)
+ }
+
+ switch op {
+ case OpInvalid:
+ code("OpInvalid")
+
+ case OpPush:
+ constant("OpPush")
+
+ case OpInt:
+ argument("OpInt")
+
+ case OpPop:
+ code("OpPop")
+
+ case OpStore:
+ argumentWithInfo("OpStore", "var")
+
+ case OpLoadVar:
+ argumentWithInfo("OpLoadVar", "var")
+
+ case OpLoadConst:
+ constant("OpLoadConst")
+
+ case OpLoadField:
+ constant("OpLoadField")
+
+ case OpLoadFast:
+ constant("OpLoadFast")
+
+ case OpLoadMethod:
+ constant("OpLoadMethod")
+
+ case OpLoadFunc:
+ argumentWithInfo("OpLoadFunc", "func")
+
+ case OpLoadEnv:
+ code("OpLoadEnv")
+
+ case OpFetch:
+ code("OpFetch")
+
+ case OpFetchField:
+ constant("OpFetchField")
+
+ case OpMethod:
+ constant("OpMethod")
+
+ case OpTrue:
+ code("OpTrue")
+
+ case OpFalse:
+ code("OpFalse")
+
+ case OpNil:
+ code("OpNil")
+
+ case OpNegate:
+ code("OpNegate")
+
+ case OpNot:
+ code("OpNot")
+
+ case OpEqual:
+ code("OpEqual")
+
+ case OpEqualInt:
+ code("OpEqualInt")
+
+ case OpEqualString:
+ code("OpEqualString")
+
+ case OpJump:
+ jump("OpJump")
+
+ case OpJumpIfTrue:
+ jump("OpJumpIfTrue")
+
+ case OpJumpIfFalse:
+ jump("OpJumpIfFalse")
+
+ case OpJumpIfNil:
+ jump("OpJumpIfNil")
+
+ case OpJumpIfNotNil:
+ jump("OpJumpIfNotNil")
+
+ case OpJumpIfEnd:
+ jump("OpJumpIfEnd")
+
+ case OpJumpBackward:
+ jumpBack("OpJumpBackward")
+
+ case OpIn:
+ code("OpIn")
+
+ case OpLess:
+ code("OpLess")
+
+ case OpMore:
+ code("OpMore")
+
+ case OpLessOrEqual:
+ code("OpLessOrEqual")
+
+ case OpMoreOrEqual:
+ code("OpMoreOrEqual")
+
+ case OpAdd:
+ code("OpAdd")
+
+ case OpSubtract:
+ code("OpSubtract")
+
+ case OpMultiply:
+ code("OpMultiply")
+
+ case OpDivide:
+ code("OpDivide")
+
+ case OpModulo:
+ code("OpModulo")
+
+ case OpExponent:
+ code("OpExponent")
+
+ case OpRange:
+ code("OpRange")
+
+ case OpMatches:
+ code("OpMatches")
+
+ case OpMatchesConst:
+ constant("OpMatchesConst")
+
+ case OpContains:
+ code("OpContains")
+
+ case OpStartsWith:
+ code("OpStartsWith")
+
+ case OpEndsWith:
+ code("OpEndsWith")
+
+ case OpSlice:
+ code("OpSlice")
+
+ case OpCall:
+ argument("OpCall")
+
+ case OpCall0:
+ argumentWithInfo("OpCall0", "func")
+
+ case OpCall1:
+ argumentWithInfo("OpCall1", "func")
+
+ case OpCall2:
+ argumentWithInfo("OpCall2", "func")
+
+ case OpCall3:
+ argumentWithInfo("OpCall3", "func")
+
+ case OpCallN:
+ argument("OpCallN")
+
+ case OpCallFast:
+ argument("OpCallFast")
+
+ case OpCallSafe:
+ argument("OpCallSafe")
+
+ case OpCallTyped:
+ signature := reflect.TypeOf(FuncTypes[arg]).Elem().String()
+ _, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\t%v\n", pp, "OpCallTyped", arg, signature)
+
+ case OpCallBuiltin1:
+ builtinArg("OpCallBuiltin1")
+
+ case OpArray:
+ code("OpArray")
+
+ case OpMap:
+ code("OpMap")
+
+ case OpLen:
+ code("OpLen")
+
+ case OpCast:
+ argument("OpCast")
+
+ case OpDeref:
+ code("OpDeref")
+
+ case OpIncrementIndex:
+ code("OpIncrementIndex")
+
+ case OpDecrementIndex:
+ code("OpDecrementIndex")
+
+ case OpIncrementCount:
+ code("OpIncrementCount")
+
+ case OpGetIndex:
+ code("OpGetIndex")
+
+ case OpGetCount:
+ code("OpGetCount")
+
+ case OpGetLen:
+ code("OpGetLen")
+
+ case OpGetAcc:
+ code("OpGetAcc")
+
+ case OpSetAcc:
+ code("OpSetAcc")
+
+ case OpSetIndex:
+ code("OpSetIndex")
+
+ case OpPointer:
+ code("OpPointer")
+
+ case OpThrow:
+ code("OpThrow")
+
+ case OpCreate:
+ argument("OpCreate")
+
+ case OpGroupBy:
+ code("OpGroupBy")
+
+ case OpSortBy:
+ code("OpSortBy")
+
+ case OpSort:
+ code("OpSort")
+
+ case OpProfileStart:
+ code("OpProfileStart")
+
+ case OpProfileEnd:
+ code("OpProfileEnd")
+
+ case OpBegin:
+ code("OpBegin")
+
+ case OpEnd:
+ code("OpEnd")
+
+ default:
+ _, _ = fmt.Fprintf(w, "%v\t%#x (unknown)\n", ip, op)
+ }
+ }
+}
diff --git a/vendor/github.com/expr-lang/expr/vm/runtime/helpers[generated].go b/vendor/github.com/expr-lang/expr/vm/runtime/helpers[generated].go
new file mode 100644
index 0000000..d950f11
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/vm/runtime/helpers[generated].go
@@ -0,0 +1,3718 @@
+// Code generated by vm/runtime/helpers/main.go. DO NOT EDIT.
+
+package runtime
+
+import (
+ "fmt"
+ "reflect"
+ "time"
+)
+
+func Equal(a, b interface{}) bool {
+ switch x := a.(type) {
+ case uint:
+ switch y := b.(type) {
+ case uint:
+ return int(x) == int(y)
+ case uint8:
+ return int(x) == int(y)
+ case uint16:
+ return int(x) == int(y)
+ case uint32:
+ return int(x) == int(y)
+ case uint64:
+ return int(x) == int(y)
+ case int:
+ return int(x) == int(y)
+ case int8:
+ return int(x) == int(y)
+ case int16:
+ return int(x) == int(y)
+ case int32:
+ return int(x) == int(y)
+ case int64:
+ return int(x) == int(y)
+ case float32:
+ return float64(x) == float64(y)
+ case float64:
+ return float64(x) == float64(y)
+ }
+ case uint8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) == int(y)
+ case uint8:
+ return int(x) == int(y)
+ case uint16:
+ return int(x) == int(y)
+ case uint32:
+ return int(x) == int(y)
+ case uint64:
+ return int(x) == int(y)
+ case int:
+ return int(x) == int(y)
+ case int8:
+ return int(x) == int(y)
+ case int16:
+ return int(x) == int(y)
+ case int32:
+ return int(x) == int(y)
+ case int64:
+ return int(x) == int(y)
+ case float32:
+ return float64(x) == float64(y)
+ case float64:
+ return float64(x) == float64(y)
+ }
+ case uint16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) == int(y)
+ case uint8:
+ return int(x) == int(y)
+ case uint16:
+ return int(x) == int(y)
+ case uint32:
+ return int(x) == int(y)
+ case uint64:
+ return int(x) == int(y)
+ case int:
+ return int(x) == int(y)
+ case int8:
+ return int(x) == int(y)
+ case int16:
+ return int(x) == int(y)
+ case int32:
+ return int(x) == int(y)
+ case int64:
+ return int(x) == int(y)
+ case float32:
+ return float64(x) == float64(y)
+ case float64:
+ return float64(x) == float64(y)
+ }
+ case uint32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) == int(y)
+ case uint8:
+ return int(x) == int(y)
+ case uint16:
+ return int(x) == int(y)
+ case uint32:
+ return int(x) == int(y)
+ case uint64:
+ return int(x) == int(y)
+ case int:
+ return int(x) == int(y)
+ case int8:
+ return int(x) == int(y)
+ case int16:
+ return int(x) == int(y)
+ case int32:
+ return int(x) == int(y)
+ case int64:
+ return int(x) == int(y)
+ case float32:
+ return float64(x) == float64(y)
+ case float64:
+ return float64(x) == float64(y)
+ }
+ case uint64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) == int(y)
+ case uint8:
+ return int(x) == int(y)
+ case uint16:
+ return int(x) == int(y)
+ case uint32:
+ return int(x) == int(y)
+ case uint64:
+ return int(x) == int(y)
+ case int:
+ return int(x) == int(y)
+ case int8:
+ return int(x) == int(y)
+ case int16:
+ return int(x) == int(y)
+ case int32:
+ return int(x) == int(y)
+ case int64:
+ return int(x) == int(y)
+ case float32:
+ return float64(x) == float64(y)
+ case float64:
+ return float64(x) == float64(y)
+ }
+ case int:
+ switch y := b.(type) {
+ case uint:
+ return int(x) == int(y)
+ case uint8:
+ return int(x) == int(y)
+ case uint16:
+ return int(x) == int(y)
+ case uint32:
+ return int(x) == int(y)
+ case uint64:
+ return int(x) == int(y)
+ case int:
+ return int(x) == int(y)
+ case int8:
+ return int(x) == int(y)
+ case int16:
+ return int(x) == int(y)
+ case int32:
+ return int(x) == int(y)
+ case int64:
+ return int(x) == int(y)
+ case float32:
+ return float64(x) == float64(y)
+ case float64:
+ return float64(x) == float64(y)
+ }
+ case int8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) == int(y)
+ case uint8:
+ return int(x) == int(y)
+ case uint16:
+ return int(x) == int(y)
+ case uint32:
+ return int(x) == int(y)
+ case uint64:
+ return int(x) == int(y)
+ case int:
+ return int(x) == int(y)
+ case int8:
+ return int(x) == int(y)
+ case int16:
+ return int(x) == int(y)
+ case int32:
+ return int(x) == int(y)
+ case int64:
+ return int(x) == int(y)
+ case float32:
+ return float64(x) == float64(y)
+ case float64:
+ return float64(x) == float64(y)
+ }
+ case int16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) == int(y)
+ case uint8:
+ return int(x) == int(y)
+ case uint16:
+ return int(x) == int(y)
+ case uint32:
+ return int(x) == int(y)
+ case uint64:
+ return int(x) == int(y)
+ case int:
+ return int(x) == int(y)
+ case int8:
+ return int(x) == int(y)
+ case int16:
+ return int(x) == int(y)
+ case int32:
+ return int(x) == int(y)
+ case int64:
+ return int(x) == int(y)
+ case float32:
+ return float64(x) == float64(y)
+ case float64:
+ return float64(x) == float64(y)
+ }
+ case int32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) == int(y)
+ case uint8:
+ return int(x) == int(y)
+ case uint16:
+ return int(x) == int(y)
+ case uint32:
+ return int(x) == int(y)
+ case uint64:
+ return int(x) == int(y)
+ case int:
+ return int(x) == int(y)
+ case int8:
+ return int(x) == int(y)
+ case int16:
+ return int(x) == int(y)
+ case int32:
+ return int(x) == int(y)
+ case int64:
+ return int(x) == int(y)
+ case float32:
+ return float64(x) == float64(y)
+ case float64:
+ return float64(x) == float64(y)
+ }
+ case int64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) == int(y)
+ case uint8:
+ return int(x) == int(y)
+ case uint16:
+ return int(x) == int(y)
+ case uint32:
+ return int(x) == int(y)
+ case uint64:
+ return int(x) == int(y)
+ case int:
+ return int(x) == int(y)
+ case int8:
+ return int(x) == int(y)
+ case int16:
+ return int(x) == int(y)
+ case int32:
+ return int(x) == int(y)
+ case int64:
+ return int(x) == int(y)
+ case float32:
+ return float64(x) == float64(y)
+ case float64:
+ return float64(x) == float64(y)
+ }
+ case float32:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) == float64(y)
+ case uint8:
+ return float64(x) == float64(y)
+ case uint16:
+ return float64(x) == float64(y)
+ case uint32:
+ return float64(x) == float64(y)
+ case uint64:
+ return float64(x) == float64(y)
+ case int:
+ return float64(x) == float64(y)
+ case int8:
+ return float64(x) == float64(y)
+ case int16:
+ return float64(x) == float64(y)
+ case int32:
+ return float64(x) == float64(y)
+ case int64:
+ return float64(x) == float64(y)
+ case float32:
+ return float64(x) == float64(y)
+ case float64:
+ return float64(x) == float64(y)
+ }
+ case float64:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) == float64(y)
+ case uint8:
+ return float64(x) == float64(y)
+ case uint16:
+ return float64(x) == float64(y)
+ case uint32:
+ return float64(x) == float64(y)
+ case uint64:
+ return float64(x) == float64(y)
+ case int:
+ return float64(x) == float64(y)
+ case int8:
+ return float64(x) == float64(y)
+ case int16:
+ return float64(x) == float64(y)
+ case int32:
+ return float64(x) == float64(y)
+ case int64:
+ return float64(x) == float64(y)
+ case float32:
+ return float64(x) == float64(y)
+ case float64:
+ return float64(x) == float64(y)
+ }
+ case []any:
+ switch y := b.(type) {
+ case []string:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if !Equal(x[i], y[i]) {
+ return false
+ }
+ }
+ return true
+ case []uint:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if !Equal(x[i], y[i]) {
+ return false
+ }
+ }
+ return true
+ case []uint8:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if !Equal(x[i], y[i]) {
+ return false
+ }
+ }
+ return true
+ case []uint16:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if !Equal(x[i], y[i]) {
+ return false
+ }
+ }
+ return true
+ case []uint32:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if !Equal(x[i], y[i]) {
+ return false
+ }
+ }
+ return true
+ case []uint64:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if !Equal(x[i], y[i]) {
+ return false
+ }
+ }
+ return true
+ case []int:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if !Equal(x[i], y[i]) {
+ return false
+ }
+ }
+ return true
+ case []int8:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if !Equal(x[i], y[i]) {
+ return false
+ }
+ }
+ return true
+ case []int16:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if !Equal(x[i], y[i]) {
+ return false
+ }
+ }
+ return true
+ case []int32:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if !Equal(x[i], y[i]) {
+ return false
+ }
+ }
+ return true
+ case []int64:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if !Equal(x[i], y[i]) {
+ return false
+ }
+ }
+ return true
+ case []float32:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if !Equal(x[i], y[i]) {
+ return false
+ }
+ }
+ return true
+ case []float64:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if !Equal(x[i], y[i]) {
+ return false
+ }
+ }
+ return true
+ case []any:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if !Equal(x[i], y[i]) {
+ return false
+ }
+ }
+ return true
+ }
+ case []string:
+ switch y := b.(type) {
+ case []any:
+ return Equal(y, x)
+ case []string:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if x[i] != y[i] {
+ return false
+ }
+ }
+ return true
+ }
+ case []uint:
+ switch y := b.(type) {
+ case []any:
+ return Equal(y, x)
+ case []uint:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if x[i] != y[i] {
+ return false
+ }
+ }
+ return true
+ }
+ case []uint8:
+ switch y := b.(type) {
+ case []any:
+ return Equal(y, x)
+ case []uint8:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if x[i] != y[i] {
+ return false
+ }
+ }
+ return true
+ }
+ case []uint16:
+ switch y := b.(type) {
+ case []any:
+ return Equal(y, x)
+ case []uint16:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if x[i] != y[i] {
+ return false
+ }
+ }
+ return true
+ }
+ case []uint32:
+ switch y := b.(type) {
+ case []any:
+ return Equal(y, x)
+ case []uint32:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if x[i] != y[i] {
+ return false
+ }
+ }
+ return true
+ }
+ case []uint64:
+ switch y := b.(type) {
+ case []any:
+ return Equal(y, x)
+ case []uint64:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if x[i] != y[i] {
+ return false
+ }
+ }
+ return true
+ }
+ case []int:
+ switch y := b.(type) {
+ case []any:
+ return Equal(y, x)
+ case []int:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if x[i] != y[i] {
+ return false
+ }
+ }
+ return true
+ }
+ case []int8:
+ switch y := b.(type) {
+ case []any:
+ return Equal(y, x)
+ case []int8:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if x[i] != y[i] {
+ return false
+ }
+ }
+ return true
+ }
+ case []int16:
+ switch y := b.(type) {
+ case []any:
+ return Equal(y, x)
+ case []int16:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if x[i] != y[i] {
+ return false
+ }
+ }
+ return true
+ }
+ case []int32:
+ switch y := b.(type) {
+ case []any:
+ return Equal(y, x)
+ case []int32:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if x[i] != y[i] {
+ return false
+ }
+ }
+ return true
+ }
+ case []int64:
+ switch y := b.(type) {
+ case []any:
+ return Equal(y, x)
+ case []int64:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if x[i] != y[i] {
+ return false
+ }
+ }
+ return true
+ }
+ case []float32:
+ switch y := b.(type) {
+ case []any:
+ return Equal(y, x)
+ case []float32:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if x[i] != y[i] {
+ return false
+ }
+ }
+ return true
+ }
+ case []float64:
+ switch y := b.(type) {
+ case []any:
+ return Equal(y, x)
+ case []float64:
+ if len(x) != len(y) {
+ return false
+ }
+ for i := range x {
+ if x[i] != y[i] {
+ return false
+ }
+ }
+ return true
+ }
+ case string:
+ switch y := b.(type) {
+ case string:
+ return x == y
+ }
+ case time.Time:
+ switch y := b.(type) {
+ case time.Time:
+ return x.Equal(y)
+ }
+ case time.Duration:
+ switch y := b.(type) {
+ case time.Duration:
+ return x == y
+ }
+ case bool:
+ switch y := b.(type) {
+ case bool:
+ return x == y
+ }
+ }
+ if IsNil(a) && IsNil(b) {
+ return true
+ }
+ return reflect.DeepEqual(a, b)
+}
+
+func Less(a, b interface{}) bool {
+ switch x := a.(type) {
+ case uint:
+ switch y := b.(type) {
+ case uint:
+ return int(x) < int(y)
+ case uint8:
+ return int(x) < int(y)
+ case uint16:
+ return int(x) < int(y)
+ case uint32:
+ return int(x) < int(y)
+ case uint64:
+ return int(x) < int(y)
+ case int:
+ return int(x) < int(y)
+ case int8:
+ return int(x) < int(y)
+ case int16:
+ return int(x) < int(y)
+ case int32:
+ return int(x) < int(y)
+ case int64:
+ return int(x) < int(y)
+ case float32:
+ return float64(x) < float64(y)
+ case float64:
+ return float64(x) < float64(y)
+ }
+ case uint8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) < int(y)
+ case uint8:
+ return int(x) < int(y)
+ case uint16:
+ return int(x) < int(y)
+ case uint32:
+ return int(x) < int(y)
+ case uint64:
+ return int(x) < int(y)
+ case int:
+ return int(x) < int(y)
+ case int8:
+ return int(x) < int(y)
+ case int16:
+ return int(x) < int(y)
+ case int32:
+ return int(x) < int(y)
+ case int64:
+ return int(x) < int(y)
+ case float32:
+ return float64(x) < float64(y)
+ case float64:
+ return float64(x) < float64(y)
+ }
+ case uint16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) < int(y)
+ case uint8:
+ return int(x) < int(y)
+ case uint16:
+ return int(x) < int(y)
+ case uint32:
+ return int(x) < int(y)
+ case uint64:
+ return int(x) < int(y)
+ case int:
+ return int(x) < int(y)
+ case int8:
+ return int(x) < int(y)
+ case int16:
+ return int(x) < int(y)
+ case int32:
+ return int(x) < int(y)
+ case int64:
+ return int(x) < int(y)
+ case float32:
+ return float64(x) < float64(y)
+ case float64:
+ return float64(x) < float64(y)
+ }
+ case uint32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) < int(y)
+ case uint8:
+ return int(x) < int(y)
+ case uint16:
+ return int(x) < int(y)
+ case uint32:
+ return int(x) < int(y)
+ case uint64:
+ return int(x) < int(y)
+ case int:
+ return int(x) < int(y)
+ case int8:
+ return int(x) < int(y)
+ case int16:
+ return int(x) < int(y)
+ case int32:
+ return int(x) < int(y)
+ case int64:
+ return int(x) < int(y)
+ case float32:
+ return float64(x) < float64(y)
+ case float64:
+ return float64(x) < float64(y)
+ }
+ case uint64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) < int(y)
+ case uint8:
+ return int(x) < int(y)
+ case uint16:
+ return int(x) < int(y)
+ case uint32:
+ return int(x) < int(y)
+ case uint64:
+ return int(x) < int(y)
+ case int:
+ return int(x) < int(y)
+ case int8:
+ return int(x) < int(y)
+ case int16:
+ return int(x) < int(y)
+ case int32:
+ return int(x) < int(y)
+ case int64:
+ return int(x) < int(y)
+ case float32:
+ return float64(x) < float64(y)
+ case float64:
+ return float64(x) < float64(y)
+ }
+ case int:
+ switch y := b.(type) {
+ case uint:
+ return int(x) < int(y)
+ case uint8:
+ return int(x) < int(y)
+ case uint16:
+ return int(x) < int(y)
+ case uint32:
+ return int(x) < int(y)
+ case uint64:
+ return int(x) < int(y)
+ case int:
+ return int(x) < int(y)
+ case int8:
+ return int(x) < int(y)
+ case int16:
+ return int(x) < int(y)
+ case int32:
+ return int(x) < int(y)
+ case int64:
+ return int(x) < int(y)
+ case float32:
+ return float64(x) < float64(y)
+ case float64:
+ return float64(x) < float64(y)
+ }
+ case int8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) < int(y)
+ case uint8:
+ return int(x) < int(y)
+ case uint16:
+ return int(x) < int(y)
+ case uint32:
+ return int(x) < int(y)
+ case uint64:
+ return int(x) < int(y)
+ case int:
+ return int(x) < int(y)
+ case int8:
+ return int(x) < int(y)
+ case int16:
+ return int(x) < int(y)
+ case int32:
+ return int(x) < int(y)
+ case int64:
+ return int(x) < int(y)
+ case float32:
+ return float64(x) < float64(y)
+ case float64:
+ return float64(x) < float64(y)
+ }
+ case int16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) < int(y)
+ case uint8:
+ return int(x) < int(y)
+ case uint16:
+ return int(x) < int(y)
+ case uint32:
+ return int(x) < int(y)
+ case uint64:
+ return int(x) < int(y)
+ case int:
+ return int(x) < int(y)
+ case int8:
+ return int(x) < int(y)
+ case int16:
+ return int(x) < int(y)
+ case int32:
+ return int(x) < int(y)
+ case int64:
+ return int(x) < int(y)
+ case float32:
+ return float64(x) < float64(y)
+ case float64:
+ return float64(x) < float64(y)
+ }
+ case int32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) < int(y)
+ case uint8:
+ return int(x) < int(y)
+ case uint16:
+ return int(x) < int(y)
+ case uint32:
+ return int(x) < int(y)
+ case uint64:
+ return int(x) < int(y)
+ case int:
+ return int(x) < int(y)
+ case int8:
+ return int(x) < int(y)
+ case int16:
+ return int(x) < int(y)
+ case int32:
+ return int(x) < int(y)
+ case int64:
+ return int(x) < int(y)
+ case float32:
+ return float64(x) < float64(y)
+ case float64:
+ return float64(x) < float64(y)
+ }
+ case int64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) < int(y)
+ case uint8:
+ return int(x) < int(y)
+ case uint16:
+ return int(x) < int(y)
+ case uint32:
+ return int(x) < int(y)
+ case uint64:
+ return int(x) < int(y)
+ case int:
+ return int(x) < int(y)
+ case int8:
+ return int(x) < int(y)
+ case int16:
+ return int(x) < int(y)
+ case int32:
+ return int(x) < int(y)
+ case int64:
+ return int(x) < int(y)
+ case float32:
+ return float64(x) < float64(y)
+ case float64:
+ return float64(x) < float64(y)
+ }
+ case float32:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) < float64(y)
+ case uint8:
+ return float64(x) < float64(y)
+ case uint16:
+ return float64(x) < float64(y)
+ case uint32:
+ return float64(x) < float64(y)
+ case uint64:
+ return float64(x) < float64(y)
+ case int:
+ return float64(x) < float64(y)
+ case int8:
+ return float64(x) < float64(y)
+ case int16:
+ return float64(x) < float64(y)
+ case int32:
+ return float64(x) < float64(y)
+ case int64:
+ return float64(x) < float64(y)
+ case float32:
+ return float64(x) < float64(y)
+ case float64:
+ return float64(x) < float64(y)
+ }
+ case float64:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) < float64(y)
+ case uint8:
+ return float64(x) < float64(y)
+ case uint16:
+ return float64(x) < float64(y)
+ case uint32:
+ return float64(x) < float64(y)
+ case uint64:
+ return float64(x) < float64(y)
+ case int:
+ return float64(x) < float64(y)
+ case int8:
+ return float64(x) < float64(y)
+ case int16:
+ return float64(x) < float64(y)
+ case int32:
+ return float64(x) < float64(y)
+ case int64:
+ return float64(x) < float64(y)
+ case float32:
+ return float64(x) < float64(y)
+ case float64:
+ return float64(x) < float64(y)
+ }
+ case string:
+ switch y := b.(type) {
+ case string:
+ return x < y
+ }
+ case time.Time:
+ switch y := b.(type) {
+ case time.Time:
+ return x.Before(y)
+ }
+ case time.Duration:
+ switch y := b.(type) {
+ case time.Duration:
+ return x < y
+ }
+ }
+ panic(fmt.Sprintf("invalid operation: %T < %T", a, b))
+}
+
+func More(a, b interface{}) bool {
+ switch x := a.(type) {
+ case uint:
+ switch y := b.(type) {
+ case uint:
+ return int(x) > int(y)
+ case uint8:
+ return int(x) > int(y)
+ case uint16:
+ return int(x) > int(y)
+ case uint32:
+ return int(x) > int(y)
+ case uint64:
+ return int(x) > int(y)
+ case int:
+ return int(x) > int(y)
+ case int8:
+ return int(x) > int(y)
+ case int16:
+ return int(x) > int(y)
+ case int32:
+ return int(x) > int(y)
+ case int64:
+ return int(x) > int(y)
+ case float32:
+ return float64(x) > float64(y)
+ case float64:
+ return float64(x) > float64(y)
+ }
+ case uint8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) > int(y)
+ case uint8:
+ return int(x) > int(y)
+ case uint16:
+ return int(x) > int(y)
+ case uint32:
+ return int(x) > int(y)
+ case uint64:
+ return int(x) > int(y)
+ case int:
+ return int(x) > int(y)
+ case int8:
+ return int(x) > int(y)
+ case int16:
+ return int(x) > int(y)
+ case int32:
+ return int(x) > int(y)
+ case int64:
+ return int(x) > int(y)
+ case float32:
+ return float64(x) > float64(y)
+ case float64:
+ return float64(x) > float64(y)
+ }
+ case uint16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) > int(y)
+ case uint8:
+ return int(x) > int(y)
+ case uint16:
+ return int(x) > int(y)
+ case uint32:
+ return int(x) > int(y)
+ case uint64:
+ return int(x) > int(y)
+ case int:
+ return int(x) > int(y)
+ case int8:
+ return int(x) > int(y)
+ case int16:
+ return int(x) > int(y)
+ case int32:
+ return int(x) > int(y)
+ case int64:
+ return int(x) > int(y)
+ case float32:
+ return float64(x) > float64(y)
+ case float64:
+ return float64(x) > float64(y)
+ }
+ case uint32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) > int(y)
+ case uint8:
+ return int(x) > int(y)
+ case uint16:
+ return int(x) > int(y)
+ case uint32:
+ return int(x) > int(y)
+ case uint64:
+ return int(x) > int(y)
+ case int:
+ return int(x) > int(y)
+ case int8:
+ return int(x) > int(y)
+ case int16:
+ return int(x) > int(y)
+ case int32:
+ return int(x) > int(y)
+ case int64:
+ return int(x) > int(y)
+ case float32:
+ return float64(x) > float64(y)
+ case float64:
+ return float64(x) > float64(y)
+ }
+ case uint64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) > int(y)
+ case uint8:
+ return int(x) > int(y)
+ case uint16:
+ return int(x) > int(y)
+ case uint32:
+ return int(x) > int(y)
+ case uint64:
+ return int(x) > int(y)
+ case int:
+ return int(x) > int(y)
+ case int8:
+ return int(x) > int(y)
+ case int16:
+ return int(x) > int(y)
+ case int32:
+ return int(x) > int(y)
+ case int64:
+ return int(x) > int(y)
+ case float32:
+ return float64(x) > float64(y)
+ case float64:
+ return float64(x) > float64(y)
+ }
+ case int:
+ switch y := b.(type) {
+ case uint:
+ return int(x) > int(y)
+ case uint8:
+ return int(x) > int(y)
+ case uint16:
+ return int(x) > int(y)
+ case uint32:
+ return int(x) > int(y)
+ case uint64:
+ return int(x) > int(y)
+ case int:
+ return int(x) > int(y)
+ case int8:
+ return int(x) > int(y)
+ case int16:
+ return int(x) > int(y)
+ case int32:
+ return int(x) > int(y)
+ case int64:
+ return int(x) > int(y)
+ case float32:
+ return float64(x) > float64(y)
+ case float64:
+ return float64(x) > float64(y)
+ }
+ case int8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) > int(y)
+ case uint8:
+ return int(x) > int(y)
+ case uint16:
+ return int(x) > int(y)
+ case uint32:
+ return int(x) > int(y)
+ case uint64:
+ return int(x) > int(y)
+ case int:
+ return int(x) > int(y)
+ case int8:
+ return int(x) > int(y)
+ case int16:
+ return int(x) > int(y)
+ case int32:
+ return int(x) > int(y)
+ case int64:
+ return int(x) > int(y)
+ case float32:
+ return float64(x) > float64(y)
+ case float64:
+ return float64(x) > float64(y)
+ }
+ case int16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) > int(y)
+ case uint8:
+ return int(x) > int(y)
+ case uint16:
+ return int(x) > int(y)
+ case uint32:
+ return int(x) > int(y)
+ case uint64:
+ return int(x) > int(y)
+ case int:
+ return int(x) > int(y)
+ case int8:
+ return int(x) > int(y)
+ case int16:
+ return int(x) > int(y)
+ case int32:
+ return int(x) > int(y)
+ case int64:
+ return int(x) > int(y)
+ case float32:
+ return float64(x) > float64(y)
+ case float64:
+ return float64(x) > float64(y)
+ }
+ case int32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) > int(y)
+ case uint8:
+ return int(x) > int(y)
+ case uint16:
+ return int(x) > int(y)
+ case uint32:
+ return int(x) > int(y)
+ case uint64:
+ return int(x) > int(y)
+ case int:
+ return int(x) > int(y)
+ case int8:
+ return int(x) > int(y)
+ case int16:
+ return int(x) > int(y)
+ case int32:
+ return int(x) > int(y)
+ case int64:
+ return int(x) > int(y)
+ case float32:
+ return float64(x) > float64(y)
+ case float64:
+ return float64(x) > float64(y)
+ }
+ case int64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) > int(y)
+ case uint8:
+ return int(x) > int(y)
+ case uint16:
+ return int(x) > int(y)
+ case uint32:
+ return int(x) > int(y)
+ case uint64:
+ return int(x) > int(y)
+ case int:
+ return int(x) > int(y)
+ case int8:
+ return int(x) > int(y)
+ case int16:
+ return int(x) > int(y)
+ case int32:
+ return int(x) > int(y)
+ case int64:
+ return int(x) > int(y)
+ case float32:
+ return float64(x) > float64(y)
+ case float64:
+ return float64(x) > float64(y)
+ }
+ case float32:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) > float64(y)
+ case uint8:
+ return float64(x) > float64(y)
+ case uint16:
+ return float64(x) > float64(y)
+ case uint32:
+ return float64(x) > float64(y)
+ case uint64:
+ return float64(x) > float64(y)
+ case int:
+ return float64(x) > float64(y)
+ case int8:
+ return float64(x) > float64(y)
+ case int16:
+ return float64(x) > float64(y)
+ case int32:
+ return float64(x) > float64(y)
+ case int64:
+ return float64(x) > float64(y)
+ case float32:
+ return float64(x) > float64(y)
+ case float64:
+ return float64(x) > float64(y)
+ }
+ case float64:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) > float64(y)
+ case uint8:
+ return float64(x) > float64(y)
+ case uint16:
+ return float64(x) > float64(y)
+ case uint32:
+ return float64(x) > float64(y)
+ case uint64:
+ return float64(x) > float64(y)
+ case int:
+ return float64(x) > float64(y)
+ case int8:
+ return float64(x) > float64(y)
+ case int16:
+ return float64(x) > float64(y)
+ case int32:
+ return float64(x) > float64(y)
+ case int64:
+ return float64(x) > float64(y)
+ case float32:
+ return float64(x) > float64(y)
+ case float64:
+ return float64(x) > float64(y)
+ }
+ case string:
+ switch y := b.(type) {
+ case string:
+ return x > y
+ }
+ case time.Time:
+ switch y := b.(type) {
+ case time.Time:
+ return x.After(y)
+ }
+ case time.Duration:
+ switch y := b.(type) {
+ case time.Duration:
+ return x > y
+ }
+ }
+ panic(fmt.Sprintf("invalid operation: %T > %T", a, b))
+}
+
+func LessOrEqual(a, b interface{}) bool {
+ switch x := a.(type) {
+ case uint:
+ switch y := b.(type) {
+ case uint:
+ return int(x) <= int(y)
+ case uint8:
+ return int(x) <= int(y)
+ case uint16:
+ return int(x) <= int(y)
+ case uint32:
+ return int(x) <= int(y)
+ case uint64:
+ return int(x) <= int(y)
+ case int:
+ return int(x) <= int(y)
+ case int8:
+ return int(x) <= int(y)
+ case int16:
+ return int(x) <= int(y)
+ case int32:
+ return int(x) <= int(y)
+ case int64:
+ return int(x) <= int(y)
+ case float32:
+ return float64(x) <= float64(y)
+ case float64:
+ return float64(x) <= float64(y)
+ }
+ case uint8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) <= int(y)
+ case uint8:
+ return int(x) <= int(y)
+ case uint16:
+ return int(x) <= int(y)
+ case uint32:
+ return int(x) <= int(y)
+ case uint64:
+ return int(x) <= int(y)
+ case int:
+ return int(x) <= int(y)
+ case int8:
+ return int(x) <= int(y)
+ case int16:
+ return int(x) <= int(y)
+ case int32:
+ return int(x) <= int(y)
+ case int64:
+ return int(x) <= int(y)
+ case float32:
+ return float64(x) <= float64(y)
+ case float64:
+ return float64(x) <= float64(y)
+ }
+ case uint16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) <= int(y)
+ case uint8:
+ return int(x) <= int(y)
+ case uint16:
+ return int(x) <= int(y)
+ case uint32:
+ return int(x) <= int(y)
+ case uint64:
+ return int(x) <= int(y)
+ case int:
+ return int(x) <= int(y)
+ case int8:
+ return int(x) <= int(y)
+ case int16:
+ return int(x) <= int(y)
+ case int32:
+ return int(x) <= int(y)
+ case int64:
+ return int(x) <= int(y)
+ case float32:
+ return float64(x) <= float64(y)
+ case float64:
+ return float64(x) <= float64(y)
+ }
+ case uint32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) <= int(y)
+ case uint8:
+ return int(x) <= int(y)
+ case uint16:
+ return int(x) <= int(y)
+ case uint32:
+ return int(x) <= int(y)
+ case uint64:
+ return int(x) <= int(y)
+ case int:
+ return int(x) <= int(y)
+ case int8:
+ return int(x) <= int(y)
+ case int16:
+ return int(x) <= int(y)
+ case int32:
+ return int(x) <= int(y)
+ case int64:
+ return int(x) <= int(y)
+ case float32:
+ return float64(x) <= float64(y)
+ case float64:
+ return float64(x) <= float64(y)
+ }
+ case uint64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) <= int(y)
+ case uint8:
+ return int(x) <= int(y)
+ case uint16:
+ return int(x) <= int(y)
+ case uint32:
+ return int(x) <= int(y)
+ case uint64:
+ return int(x) <= int(y)
+ case int:
+ return int(x) <= int(y)
+ case int8:
+ return int(x) <= int(y)
+ case int16:
+ return int(x) <= int(y)
+ case int32:
+ return int(x) <= int(y)
+ case int64:
+ return int(x) <= int(y)
+ case float32:
+ return float64(x) <= float64(y)
+ case float64:
+ return float64(x) <= float64(y)
+ }
+ case int:
+ switch y := b.(type) {
+ case uint:
+ return int(x) <= int(y)
+ case uint8:
+ return int(x) <= int(y)
+ case uint16:
+ return int(x) <= int(y)
+ case uint32:
+ return int(x) <= int(y)
+ case uint64:
+ return int(x) <= int(y)
+ case int:
+ return int(x) <= int(y)
+ case int8:
+ return int(x) <= int(y)
+ case int16:
+ return int(x) <= int(y)
+ case int32:
+ return int(x) <= int(y)
+ case int64:
+ return int(x) <= int(y)
+ case float32:
+ return float64(x) <= float64(y)
+ case float64:
+ return float64(x) <= float64(y)
+ }
+ case int8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) <= int(y)
+ case uint8:
+ return int(x) <= int(y)
+ case uint16:
+ return int(x) <= int(y)
+ case uint32:
+ return int(x) <= int(y)
+ case uint64:
+ return int(x) <= int(y)
+ case int:
+ return int(x) <= int(y)
+ case int8:
+ return int(x) <= int(y)
+ case int16:
+ return int(x) <= int(y)
+ case int32:
+ return int(x) <= int(y)
+ case int64:
+ return int(x) <= int(y)
+ case float32:
+ return float64(x) <= float64(y)
+ case float64:
+ return float64(x) <= float64(y)
+ }
+ case int16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) <= int(y)
+ case uint8:
+ return int(x) <= int(y)
+ case uint16:
+ return int(x) <= int(y)
+ case uint32:
+ return int(x) <= int(y)
+ case uint64:
+ return int(x) <= int(y)
+ case int:
+ return int(x) <= int(y)
+ case int8:
+ return int(x) <= int(y)
+ case int16:
+ return int(x) <= int(y)
+ case int32:
+ return int(x) <= int(y)
+ case int64:
+ return int(x) <= int(y)
+ case float32:
+ return float64(x) <= float64(y)
+ case float64:
+ return float64(x) <= float64(y)
+ }
+ case int32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) <= int(y)
+ case uint8:
+ return int(x) <= int(y)
+ case uint16:
+ return int(x) <= int(y)
+ case uint32:
+ return int(x) <= int(y)
+ case uint64:
+ return int(x) <= int(y)
+ case int:
+ return int(x) <= int(y)
+ case int8:
+ return int(x) <= int(y)
+ case int16:
+ return int(x) <= int(y)
+ case int32:
+ return int(x) <= int(y)
+ case int64:
+ return int(x) <= int(y)
+ case float32:
+ return float64(x) <= float64(y)
+ case float64:
+ return float64(x) <= float64(y)
+ }
+ case int64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) <= int(y)
+ case uint8:
+ return int(x) <= int(y)
+ case uint16:
+ return int(x) <= int(y)
+ case uint32:
+ return int(x) <= int(y)
+ case uint64:
+ return int(x) <= int(y)
+ case int:
+ return int(x) <= int(y)
+ case int8:
+ return int(x) <= int(y)
+ case int16:
+ return int(x) <= int(y)
+ case int32:
+ return int(x) <= int(y)
+ case int64:
+ return int(x) <= int(y)
+ case float32:
+ return float64(x) <= float64(y)
+ case float64:
+ return float64(x) <= float64(y)
+ }
+ case float32:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) <= float64(y)
+ case uint8:
+ return float64(x) <= float64(y)
+ case uint16:
+ return float64(x) <= float64(y)
+ case uint32:
+ return float64(x) <= float64(y)
+ case uint64:
+ return float64(x) <= float64(y)
+ case int:
+ return float64(x) <= float64(y)
+ case int8:
+ return float64(x) <= float64(y)
+ case int16:
+ return float64(x) <= float64(y)
+ case int32:
+ return float64(x) <= float64(y)
+ case int64:
+ return float64(x) <= float64(y)
+ case float32:
+ return float64(x) <= float64(y)
+ case float64:
+ return float64(x) <= float64(y)
+ }
+ case float64:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) <= float64(y)
+ case uint8:
+ return float64(x) <= float64(y)
+ case uint16:
+ return float64(x) <= float64(y)
+ case uint32:
+ return float64(x) <= float64(y)
+ case uint64:
+ return float64(x) <= float64(y)
+ case int:
+ return float64(x) <= float64(y)
+ case int8:
+ return float64(x) <= float64(y)
+ case int16:
+ return float64(x) <= float64(y)
+ case int32:
+ return float64(x) <= float64(y)
+ case int64:
+ return float64(x) <= float64(y)
+ case float32:
+ return float64(x) <= float64(y)
+ case float64:
+ return float64(x) <= float64(y)
+ }
+ case string:
+ switch y := b.(type) {
+ case string:
+ return x <= y
+ }
+ case time.Time:
+ switch y := b.(type) {
+ case time.Time:
+ return x.Before(y) || x.Equal(y)
+ }
+ case time.Duration:
+ switch y := b.(type) {
+ case time.Duration:
+ return x <= y
+ }
+ }
+ panic(fmt.Sprintf("invalid operation: %T <= %T", a, b))
+}
+
+func MoreOrEqual(a, b interface{}) bool {
+ switch x := a.(type) {
+ case uint:
+ switch y := b.(type) {
+ case uint:
+ return int(x) >= int(y)
+ case uint8:
+ return int(x) >= int(y)
+ case uint16:
+ return int(x) >= int(y)
+ case uint32:
+ return int(x) >= int(y)
+ case uint64:
+ return int(x) >= int(y)
+ case int:
+ return int(x) >= int(y)
+ case int8:
+ return int(x) >= int(y)
+ case int16:
+ return int(x) >= int(y)
+ case int32:
+ return int(x) >= int(y)
+ case int64:
+ return int(x) >= int(y)
+ case float32:
+ return float64(x) >= float64(y)
+ case float64:
+ return float64(x) >= float64(y)
+ }
+ case uint8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) >= int(y)
+ case uint8:
+ return int(x) >= int(y)
+ case uint16:
+ return int(x) >= int(y)
+ case uint32:
+ return int(x) >= int(y)
+ case uint64:
+ return int(x) >= int(y)
+ case int:
+ return int(x) >= int(y)
+ case int8:
+ return int(x) >= int(y)
+ case int16:
+ return int(x) >= int(y)
+ case int32:
+ return int(x) >= int(y)
+ case int64:
+ return int(x) >= int(y)
+ case float32:
+ return float64(x) >= float64(y)
+ case float64:
+ return float64(x) >= float64(y)
+ }
+ case uint16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) >= int(y)
+ case uint8:
+ return int(x) >= int(y)
+ case uint16:
+ return int(x) >= int(y)
+ case uint32:
+ return int(x) >= int(y)
+ case uint64:
+ return int(x) >= int(y)
+ case int:
+ return int(x) >= int(y)
+ case int8:
+ return int(x) >= int(y)
+ case int16:
+ return int(x) >= int(y)
+ case int32:
+ return int(x) >= int(y)
+ case int64:
+ return int(x) >= int(y)
+ case float32:
+ return float64(x) >= float64(y)
+ case float64:
+ return float64(x) >= float64(y)
+ }
+ case uint32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) >= int(y)
+ case uint8:
+ return int(x) >= int(y)
+ case uint16:
+ return int(x) >= int(y)
+ case uint32:
+ return int(x) >= int(y)
+ case uint64:
+ return int(x) >= int(y)
+ case int:
+ return int(x) >= int(y)
+ case int8:
+ return int(x) >= int(y)
+ case int16:
+ return int(x) >= int(y)
+ case int32:
+ return int(x) >= int(y)
+ case int64:
+ return int(x) >= int(y)
+ case float32:
+ return float64(x) >= float64(y)
+ case float64:
+ return float64(x) >= float64(y)
+ }
+ case uint64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) >= int(y)
+ case uint8:
+ return int(x) >= int(y)
+ case uint16:
+ return int(x) >= int(y)
+ case uint32:
+ return int(x) >= int(y)
+ case uint64:
+ return int(x) >= int(y)
+ case int:
+ return int(x) >= int(y)
+ case int8:
+ return int(x) >= int(y)
+ case int16:
+ return int(x) >= int(y)
+ case int32:
+ return int(x) >= int(y)
+ case int64:
+ return int(x) >= int(y)
+ case float32:
+ return float64(x) >= float64(y)
+ case float64:
+ return float64(x) >= float64(y)
+ }
+ case int:
+ switch y := b.(type) {
+ case uint:
+ return int(x) >= int(y)
+ case uint8:
+ return int(x) >= int(y)
+ case uint16:
+ return int(x) >= int(y)
+ case uint32:
+ return int(x) >= int(y)
+ case uint64:
+ return int(x) >= int(y)
+ case int:
+ return int(x) >= int(y)
+ case int8:
+ return int(x) >= int(y)
+ case int16:
+ return int(x) >= int(y)
+ case int32:
+ return int(x) >= int(y)
+ case int64:
+ return int(x) >= int(y)
+ case float32:
+ return float64(x) >= float64(y)
+ case float64:
+ return float64(x) >= float64(y)
+ }
+ case int8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) >= int(y)
+ case uint8:
+ return int(x) >= int(y)
+ case uint16:
+ return int(x) >= int(y)
+ case uint32:
+ return int(x) >= int(y)
+ case uint64:
+ return int(x) >= int(y)
+ case int:
+ return int(x) >= int(y)
+ case int8:
+ return int(x) >= int(y)
+ case int16:
+ return int(x) >= int(y)
+ case int32:
+ return int(x) >= int(y)
+ case int64:
+ return int(x) >= int(y)
+ case float32:
+ return float64(x) >= float64(y)
+ case float64:
+ return float64(x) >= float64(y)
+ }
+ case int16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) >= int(y)
+ case uint8:
+ return int(x) >= int(y)
+ case uint16:
+ return int(x) >= int(y)
+ case uint32:
+ return int(x) >= int(y)
+ case uint64:
+ return int(x) >= int(y)
+ case int:
+ return int(x) >= int(y)
+ case int8:
+ return int(x) >= int(y)
+ case int16:
+ return int(x) >= int(y)
+ case int32:
+ return int(x) >= int(y)
+ case int64:
+ return int(x) >= int(y)
+ case float32:
+ return float64(x) >= float64(y)
+ case float64:
+ return float64(x) >= float64(y)
+ }
+ case int32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) >= int(y)
+ case uint8:
+ return int(x) >= int(y)
+ case uint16:
+ return int(x) >= int(y)
+ case uint32:
+ return int(x) >= int(y)
+ case uint64:
+ return int(x) >= int(y)
+ case int:
+ return int(x) >= int(y)
+ case int8:
+ return int(x) >= int(y)
+ case int16:
+ return int(x) >= int(y)
+ case int32:
+ return int(x) >= int(y)
+ case int64:
+ return int(x) >= int(y)
+ case float32:
+ return float64(x) >= float64(y)
+ case float64:
+ return float64(x) >= float64(y)
+ }
+ case int64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) >= int(y)
+ case uint8:
+ return int(x) >= int(y)
+ case uint16:
+ return int(x) >= int(y)
+ case uint32:
+ return int(x) >= int(y)
+ case uint64:
+ return int(x) >= int(y)
+ case int:
+ return int(x) >= int(y)
+ case int8:
+ return int(x) >= int(y)
+ case int16:
+ return int(x) >= int(y)
+ case int32:
+ return int(x) >= int(y)
+ case int64:
+ return int(x) >= int(y)
+ case float32:
+ return float64(x) >= float64(y)
+ case float64:
+ return float64(x) >= float64(y)
+ }
+ case float32:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) >= float64(y)
+ case uint8:
+ return float64(x) >= float64(y)
+ case uint16:
+ return float64(x) >= float64(y)
+ case uint32:
+ return float64(x) >= float64(y)
+ case uint64:
+ return float64(x) >= float64(y)
+ case int:
+ return float64(x) >= float64(y)
+ case int8:
+ return float64(x) >= float64(y)
+ case int16:
+ return float64(x) >= float64(y)
+ case int32:
+ return float64(x) >= float64(y)
+ case int64:
+ return float64(x) >= float64(y)
+ case float32:
+ return float64(x) >= float64(y)
+ case float64:
+ return float64(x) >= float64(y)
+ }
+ case float64:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) >= float64(y)
+ case uint8:
+ return float64(x) >= float64(y)
+ case uint16:
+ return float64(x) >= float64(y)
+ case uint32:
+ return float64(x) >= float64(y)
+ case uint64:
+ return float64(x) >= float64(y)
+ case int:
+ return float64(x) >= float64(y)
+ case int8:
+ return float64(x) >= float64(y)
+ case int16:
+ return float64(x) >= float64(y)
+ case int32:
+ return float64(x) >= float64(y)
+ case int64:
+ return float64(x) >= float64(y)
+ case float32:
+ return float64(x) >= float64(y)
+ case float64:
+ return float64(x) >= float64(y)
+ }
+ case string:
+ switch y := b.(type) {
+ case string:
+ return x >= y
+ }
+ case time.Time:
+ switch y := b.(type) {
+ case time.Time:
+ return x.After(y) || x.Equal(y)
+ }
+ case time.Duration:
+ switch y := b.(type) {
+ case time.Duration:
+ return x >= y
+ }
+ }
+ panic(fmt.Sprintf("invalid operation: %T >= %T", a, b))
+}
+
+func Add(a, b interface{}) interface{} {
+ switch x := a.(type) {
+ case uint:
+ switch y := b.(type) {
+ case uint:
+ return int(x) + int(y)
+ case uint8:
+ return int(x) + int(y)
+ case uint16:
+ return int(x) + int(y)
+ case uint32:
+ return int(x) + int(y)
+ case uint64:
+ return int(x) + int(y)
+ case int:
+ return int(x) + int(y)
+ case int8:
+ return int(x) + int(y)
+ case int16:
+ return int(x) + int(y)
+ case int32:
+ return int(x) + int(y)
+ case int64:
+ return int(x) + int(y)
+ case float32:
+ return float64(x) + float64(y)
+ case float64:
+ return float64(x) + float64(y)
+ }
+ case uint8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) + int(y)
+ case uint8:
+ return int(x) + int(y)
+ case uint16:
+ return int(x) + int(y)
+ case uint32:
+ return int(x) + int(y)
+ case uint64:
+ return int(x) + int(y)
+ case int:
+ return int(x) + int(y)
+ case int8:
+ return int(x) + int(y)
+ case int16:
+ return int(x) + int(y)
+ case int32:
+ return int(x) + int(y)
+ case int64:
+ return int(x) + int(y)
+ case float32:
+ return float64(x) + float64(y)
+ case float64:
+ return float64(x) + float64(y)
+ }
+ case uint16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) + int(y)
+ case uint8:
+ return int(x) + int(y)
+ case uint16:
+ return int(x) + int(y)
+ case uint32:
+ return int(x) + int(y)
+ case uint64:
+ return int(x) + int(y)
+ case int:
+ return int(x) + int(y)
+ case int8:
+ return int(x) + int(y)
+ case int16:
+ return int(x) + int(y)
+ case int32:
+ return int(x) + int(y)
+ case int64:
+ return int(x) + int(y)
+ case float32:
+ return float64(x) + float64(y)
+ case float64:
+ return float64(x) + float64(y)
+ }
+ case uint32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) + int(y)
+ case uint8:
+ return int(x) + int(y)
+ case uint16:
+ return int(x) + int(y)
+ case uint32:
+ return int(x) + int(y)
+ case uint64:
+ return int(x) + int(y)
+ case int:
+ return int(x) + int(y)
+ case int8:
+ return int(x) + int(y)
+ case int16:
+ return int(x) + int(y)
+ case int32:
+ return int(x) + int(y)
+ case int64:
+ return int(x) + int(y)
+ case float32:
+ return float64(x) + float64(y)
+ case float64:
+ return float64(x) + float64(y)
+ }
+ case uint64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) + int(y)
+ case uint8:
+ return int(x) + int(y)
+ case uint16:
+ return int(x) + int(y)
+ case uint32:
+ return int(x) + int(y)
+ case uint64:
+ return int(x) + int(y)
+ case int:
+ return int(x) + int(y)
+ case int8:
+ return int(x) + int(y)
+ case int16:
+ return int(x) + int(y)
+ case int32:
+ return int(x) + int(y)
+ case int64:
+ return int(x) + int(y)
+ case float32:
+ return float64(x) + float64(y)
+ case float64:
+ return float64(x) + float64(y)
+ }
+ case int:
+ switch y := b.(type) {
+ case uint:
+ return int(x) + int(y)
+ case uint8:
+ return int(x) + int(y)
+ case uint16:
+ return int(x) + int(y)
+ case uint32:
+ return int(x) + int(y)
+ case uint64:
+ return int(x) + int(y)
+ case int:
+ return int(x) + int(y)
+ case int8:
+ return int(x) + int(y)
+ case int16:
+ return int(x) + int(y)
+ case int32:
+ return int(x) + int(y)
+ case int64:
+ return int(x) + int(y)
+ case float32:
+ return float64(x) + float64(y)
+ case float64:
+ return float64(x) + float64(y)
+ }
+ case int8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) + int(y)
+ case uint8:
+ return int(x) + int(y)
+ case uint16:
+ return int(x) + int(y)
+ case uint32:
+ return int(x) + int(y)
+ case uint64:
+ return int(x) + int(y)
+ case int:
+ return int(x) + int(y)
+ case int8:
+ return int(x) + int(y)
+ case int16:
+ return int(x) + int(y)
+ case int32:
+ return int(x) + int(y)
+ case int64:
+ return int(x) + int(y)
+ case float32:
+ return float64(x) + float64(y)
+ case float64:
+ return float64(x) + float64(y)
+ }
+ case int16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) + int(y)
+ case uint8:
+ return int(x) + int(y)
+ case uint16:
+ return int(x) + int(y)
+ case uint32:
+ return int(x) + int(y)
+ case uint64:
+ return int(x) + int(y)
+ case int:
+ return int(x) + int(y)
+ case int8:
+ return int(x) + int(y)
+ case int16:
+ return int(x) + int(y)
+ case int32:
+ return int(x) + int(y)
+ case int64:
+ return int(x) + int(y)
+ case float32:
+ return float64(x) + float64(y)
+ case float64:
+ return float64(x) + float64(y)
+ }
+ case int32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) + int(y)
+ case uint8:
+ return int(x) + int(y)
+ case uint16:
+ return int(x) + int(y)
+ case uint32:
+ return int(x) + int(y)
+ case uint64:
+ return int(x) + int(y)
+ case int:
+ return int(x) + int(y)
+ case int8:
+ return int(x) + int(y)
+ case int16:
+ return int(x) + int(y)
+ case int32:
+ return int(x) + int(y)
+ case int64:
+ return int(x) + int(y)
+ case float32:
+ return float64(x) + float64(y)
+ case float64:
+ return float64(x) + float64(y)
+ }
+ case int64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) + int(y)
+ case uint8:
+ return int(x) + int(y)
+ case uint16:
+ return int(x) + int(y)
+ case uint32:
+ return int(x) + int(y)
+ case uint64:
+ return int(x) + int(y)
+ case int:
+ return int(x) + int(y)
+ case int8:
+ return int(x) + int(y)
+ case int16:
+ return int(x) + int(y)
+ case int32:
+ return int(x) + int(y)
+ case int64:
+ return int(x) + int(y)
+ case float32:
+ return float64(x) + float64(y)
+ case float64:
+ return float64(x) + float64(y)
+ }
+ case float32:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) + float64(y)
+ case uint8:
+ return float64(x) + float64(y)
+ case uint16:
+ return float64(x) + float64(y)
+ case uint32:
+ return float64(x) + float64(y)
+ case uint64:
+ return float64(x) + float64(y)
+ case int:
+ return float64(x) + float64(y)
+ case int8:
+ return float64(x) + float64(y)
+ case int16:
+ return float64(x) + float64(y)
+ case int32:
+ return float64(x) + float64(y)
+ case int64:
+ return float64(x) + float64(y)
+ case float32:
+ return float64(x) + float64(y)
+ case float64:
+ return float64(x) + float64(y)
+ }
+ case float64:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) + float64(y)
+ case uint8:
+ return float64(x) + float64(y)
+ case uint16:
+ return float64(x) + float64(y)
+ case uint32:
+ return float64(x) + float64(y)
+ case uint64:
+ return float64(x) + float64(y)
+ case int:
+ return float64(x) + float64(y)
+ case int8:
+ return float64(x) + float64(y)
+ case int16:
+ return float64(x) + float64(y)
+ case int32:
+ return float64(x) + float64(y)
+ case int64:
+ return float64(x) + float64(y)
+ case float32:
+ return float64(x) + float64(y)
+ case float64:
+ return float64(x) + float64(y)
+ }
+ case string:
+ switch y := b.(type) {
+ case string:
+ return x + y
+ }
+ case time.Time:
+ switch y := b.(type) {
+ case time.Duration:
+ return x.Add(y)
+ }
+ case time.Duration:
+ switch y := b.(type) {
+ case time.Time:
+ return y.Add(x)
+ case time.Duration:
+ return x + y
+ }
+ }
+ panic(fmt.Sprintf("invalid operation: %T + %T", a, b))
+}
+
+func Subtract(a, b interface{}) interface{} {
+ switch x := a.(type) {
+ case uint:
+ switch y := b.(type) {
+ case uint:
+ return int(x) - int(y)
+ case uint8:
+ return int(x) - int(y)
+ case uint16:
+ return int(x) - int(y)
+ case uint32:
+ return int(x) - int(y)
+ case uint64:
+ return int(x) - int(y)
+ case int:
+ return int(x) - int(y)
+ case int8:
+ return int(x) - int(y)
+ case int16:
+ return int(x) - int(y)
+ case int32:
+ return int(x) - int(y)
+ case int64:
+ return int(x) - int(y)
+ case float32:
+ return float64(x) - float64(y)
+ case float64:
+ return float64(x) - float64(y)
+ }
+ case uint8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) - int(y)
+ case uint8:
+ return int(x) - int(y)
+ case uint16:
+ return int(x) - int(y)
+ case uint32:
+ return int(x) - int(y)
+ case uint64:
+ return int(x) - int(y)
+ case int:
+ return int(x) - int(y)
+ case int8:
+ return int(x) - int(y)
+ case int16:
+ return int(x) - int(y)
+ case int32:
+ return int(x) - int(y)
+ case int64:
+ return int(x) - int(y)
+ case float32:
+ return float64(x) - float64(y)
+ case float64:
+ return float64(x) - float64(y)
+ }
+ case uint16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) - int(y)
+ case uint8:
+ return int(x) - int(y)
+ case uint16:
+ return int(x) - int(y)
+ case uint32:
+ return int(x) - int(y)
+ case uint64:
+ return int(x) - int(y)
+ case int:
+ return int(x) - int(y)
+ case int8:
+ return int(x) - int(y)
+ case int16:
+ return int(x) - int(y)
+ case int32:
+ return int(x) - int(y)
+ case int64:
+ return int(x) - int(y)
+ case float32:
+ return float64(x) - float64(y)
+ case float64:
+ return float64(x) - float64(y)
+ }
+ case uint32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) - int(y)
+ case uint8:
+ return int(x) - int(y)
+ case uint16:
+ return int(x) - int(y)
+ case uint32:
+ return int(x) - int(y)
+ case uint64:
+ return int(x) - int(y)
+ case int:
+ return int(x) - int(y)
+ case int8:
+ return int(x) - int(y)
+ case int16:
+ return int(x) - int(y)
+ case int32:
+ return int(x) - int(y)
+ case int64:
+ return int(x) - int(y)
+ case float32:
+ return float64(x) - float64(y)
+ case float64:
+ return float64(x) - float64(y)
+ }
+ case uint64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) - int(y)
+ case uint8:
+ return int(x) - int(y)
+ case uint16:
+ return int(x) - int(y)
+ case uint32:
+ return int(x) - int(y)
+ case uint64:
+ return int(x) - int(y)
+ case int:
+ return int(x) - int(y)
+ case int8:
+ return int(x) - int(y)
+ case int16:
+ return int(x) - int(y)
+ case int32:
+ return int(x) - int(y)
+ case int64:
+ return int(x) - int(y)
+ case float32:
+ return float64(x) - float64(y)
+ case float64:
+ return float64(x) - float64(y)
+ }
+ case int:
+ switch y := b.(type) {
+ case uint:
+ return int(x) - int(y)
+ case uint8:
+ return int(x) - int(y)
+ case uint16:
+ return int(x) - int(y)
+ case uint32:
+ return int(x) - int(y)
+ case uint64:
+ return int(x) - int(y)
+ case int:
+ return int(x) - int(y)
+ case int8:
+ return int(x) - int(y)
+ case int16:
+ return int(x) - int(y)
+ case int32:
+ return int(x) - int(y)
+ case int64:
+ return int(x) - int(y)
+ case float32:
+ return float64(x) - float64(y)
+ case float64:
+ return float64(x) - float64(y)
+ }
+ case int8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) - int(y)
+ case uint8:
+ return int(x) - int(y)
+ case uint16:
+ return int(x) - int(y)
+ case uint32:
+ return int(x) - int(y)
+ case uint64:
+ return int(x) - int(y)
+ case int:
+ return int(x) - int(y)
+ case int8:
+ return int(x) - int(y)
+ case int16:
+ return int(x) - int(y)
+ case int32:
+ return int(x) - int(y)
+ case int64:
+ return int(x) - int(y)
+ case float32:
+ return float64(x) - float64(y)
+ case float64:
+ return float64(x) - float64(y)
+ }
+ case int16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) - int(y)
+ case uint8:
+ return int(x) - int(y)
+ case uint16:
+ return int(x) - int(y)
+ case uint32:
+ return int(x) - int(y)
+ case uint64:
+ return int(x) - int(y)
+ case int:
+ return int(x) - int(y)
+ case int8:
+ return int(x) - int(y)
+ case int16:
+ return int(x) - int(y)
+ case int32:
+ return int(x) - int(y)
+ case int64:
+ return int(x) - int(y)
+ case float32:
+ return float64(x) - float64(y)
+ case float64:
+ return float64(x) - float64(y)
+ }
+ case int32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) - int(y)
+ case uint8:
+ return int(x) - int(y)
+ case uint16:
+ return int(x) - int(y)
+ case uint32:
+ return int(x) - int(y)
+ case uint64:
+ return int(x) - int(y)
+ case int:
+ return int(x) - int(y)
+ case int8:
+ return int(x) - int(y)
+ case int16:
+ return int(x) - int(y)
+ case int32:
+ return int(x) - int(y)
+ case int64:
+ return int(x) - int(y)
+ case float32:
+ return float64(x) - float64(y)
+ case float64:
+ return float64(x) - float64(y)
+ }
+ case int64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) - int(y)
+ case uint8:
+ return int(x) - int(y)
+ case uint16:
+ return int(x) - int(y)
+ case uint32:
+ return int(x) - int(y)
+ case uint64:
+ return int(x) - int(y)
+ case int:
+ return int(x) - int(y)
+ case int8:
+ return int(x) - int(y)
+ case int16:
+ return int(x) - int(y)
+ case int32:
+ return int(x) - int(y)
+ case int64:
+ return int(x) - int(y)
+ case float32:
+ return float64(x) - float64(y)
+ case float64:
+ return float64(x) - float64(y)
+ }
+ case float32:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) - float64(y)
+ case uint8:
+ return float64(x) - float64(y)
+ case uint16:
+ return float64(x) - float64(y)
+ case uint32:
+ return float64(x) - float64(y)
+ case uint64:
+ return float64(x) - float64(y)
+ case int:
+ return float64(x) - float64(y)
+ case int8:
+ return float64(x) - float64(y)
+ case int16:
+ return float64(x) - float64(y)
+ case int32:
+ return float64(x) - float64(y)
+ case int64:
+ return float64(x) - float64(y)
+ case float32:
+ return float64(x) - float64(y)
+ case float64:
+ return float64(x) - float64(y)
+ }
+ case float64:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) - float64(y)
+ case uint8:
+ return float64(x) - float64(y)
+ case uint16:
+ return float64(x) - float64(y)
+ case uint32:
+ return float64(x) - float64(y)
+ case uint64:
+ return float64(x) - float64(y)
+ case int:
+ return float64(x) - float64(y)
+ case int8:
+ return float64(x) - float64(y)
+ case int16:
+ return float64(x) - float64(y)
+ case int32:
+ return float64(x) - float64(y)
+ case int64:
+ return float64(x) - float64(y)
+ case float32:
+ return float64(x) - float64(y)
+ case float64:
+ return float64(x) - float64(y)
+ }
+ case time.Time:
+ switch y := b.(type) {
+ case time.Time:
+ return x.Sub(y)
+ case time.Duration:
+ return x.Add(-y)
+ }
+ case time.Duration:
+ switch y := b.(type) {
+ case time.Duration:
+ return x - y
+ }
+ }
+ panic(fmt.Sprintf("invalid operation: %T - %T", a, b))
+}
+
+func Multiply(a, b interface{}) interface{} {
+ switch x := a.(type) {
+ case uint:
+ switch y := b.(type) {
+ case uint:
+ return int(x) * int(y)
+ case uint8:
+ return int(x) * int(y)
+ case uint16:
+ return int(x) * int(y)
+ case uint32:
+ return int(x) * int(y)
+ case uint64:
+ return int(x) * int(y)
+ case int:
+ return int(x) * int(y)
+ case int8:
+ return int(x) * int(y)
+ case int16:
+ return int(x) * int(y)
+ case int32:
+ return int(x) * int(y)
+ case int64:
+ return int(x) * int(y)
+ case float32:
+ return float64(x) * float64(y)
+ case float64:
+ return float64(x) * float64(y)
+ case time.Duration:
+ return time.Duration(x) * time.Duration(y)
+ }
+ case uint8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) * int(y)
+ case uint8:
+ return int(x) * int(y)
+ case uint16:
+ return int(x) * int(y)
+ case uint32:
+ return int(x) * int(y)
+ case uint64:
+ return int(x) * int(y)
+ case int:
+ return int(x) * int(y)
+ case int8:
+ return int(x) * int(y)
+ case int16:
+ return int(x) * int(y)
+ case int32:
+ return int(x) * int(y)
+ case int64:
+ return int(x) * int(y)
+ case float32:
+ return float64(x) * float64(y)
+ case float64:
+ return float64(x) * float64(y)
+ case time.Duration:
+ return time.Duration(x) * time.Duration(y)
+ }
+ case uint16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) * int(y)
+ case uint8:
+ return int(x) * int(y)
+ case uint16:
+ return int(x) * int(y)
+ case uint32:
+ return int(x) * int(y)
+ case uint64:
+ return int(x) * int(y)
+ case int:
+ return int(x) * int(y)
+ case int8:
+ return int(x) * int(y)
+ case int16:
+ return int(x) * int(y)
+ case int32:
+ return int(x) * int(y)
+ case int64:
+ return int(x) * int(y)
+ case float32:
+ return float64(x) * float64(y)
+ case float64:
+ return float64(x) * float64(y)
+ case time.Duration:
+ return time.Duration(x) * time.Duration(y)
+ }
+ case uint32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) * int(y)
+ case uint8:
+ return int(x) * int(y)
+ case uint16:
+ return int(x) * int(y)
+ case uint32:
+ return int(x) * int(y)
+ case uint64:
+ return int(x) * int(y)
+ case int:
+ return int(x) * int(y)
+ case int8:
+ return int(x) * int(y)
+ case int16:
+ return int(x) * int(y)
+ case int32:
+ return int(x) * int(y)
+ case int64:
+ return int(x) * int(y)
+ case float32:
+ return float64(x) * float64(y)
+ case float64:
+ return float64(x) * float64(y)
+ case time.Duration:
+ return time.Duration(x) * time.Duration(y)
+ }
+ case uint64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) * int(y)
+ case uint8:
+ return int(x) * int(y)
+ case uint16:
+ return int(x) * int(y)
+ case uint32:
+ return int(x) * int(y)
+ case uint64:
+ return int(x) * int(y)
+ case int:
+ return int(x) * int(y)
+ case int8:
+ return int(x) * int(y)
+ case int16:
+ return int(x) * int(y)
+ case int32:
+ return int(x) * int(y)
+ case int64:
+ return int(x) * int(y)
+ case float32:
+ return float64(x) * float64(y)
+ case float64:
+ return float64(x) * float64(y)
+ case time.Duration:
+ return time.Duration(x) * time.Duration(y)
+ }
+ case int:
+ switch y := b.(type) {
+ case uint:
+ return int(x) * int(y)
+ case uint8:
+ return int(x) * int(y)
+ case uint16:
+ return int(x) * int(y)
+ case uint32:
+ return int(x) * int(y)
+ case uint64:
+ return int(x) * int(y)
+ case int:
+ return int(x) * int(y)
+ case int8:
+ return int(x) * int(y)
+ case int16:
+ return int(x) * int(y)
+ case int32:
+ return int(x) * int(y)
+ case int64:
+ return int(x) * int(y)
+ case float32:
+ return float64(x) * float64(y)
+ case float64:
+ return float64(x) * float64(y)
+ case time.Duration:
+ return time.Duration(x) * time.Duration(y)
+ }
+ case int8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) * int(y)
+ case uint8:
+ return int(x) * int(y)
+ case uint16:
+ return int(x) * int(y)
+ case uint32:
+ return int(x) * int(y)
+ case uint64:
+ return int(x) * int(y)
+ case int:
+ return int(x) * int(y)
+ case int8:
+ return int(x) * int(y)
+ case int16:
+ return int(x) * int(y)
+ case int32:
+ return int(x) * int(y)
+ case int64:
+ return int(x) * int(y)
+ case float32:
+ return float64(x) * float64(y)
+ case float64:
+ return float64(x) * float64(y)
+ case time.Duration:
+ return time.Duration(x) * time.Duration(y)
+ }
+ case int16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) * int(y)
+ case uint8:
+ return int(x) * int(y)
+ case uint16:
+ return int(x) * int(y)
+ case uint32:
+ return int(x) * int(y)
+ case uint64:
+ return int(x) * int(y)
+ case int:
+ return int(x) * int(y)
+ case int8:
+ return int(x) * int(y)
+ case int16:
+ return int(x) * int(y)
+ case int32:
+ return int(x) * int(y)
+ case int64:
+ return int(x) * int(y)
+ case float32:
+ return float64(x) * float64(y)
+ case float64:
+ return float64(x) * float64(y)
+ case time.Duration:
+ return time.Duration(x) * time.Duration(y)
+ }
+ case int32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) * int(y)
+ case uint8:
+ return int(x) * int(y)
+ case uint16:
+ return int(x) * int(y)
+ case uint32:
+ return int(x) * int(y)
+ case uint64:
+ return int(x) * int(y)
+ case int:
+ return int(x) * int(y)
+ case int8:
+ return int(x) * int(y)
+ case int16:
+ return int(x) * int(y)
+ case int32:
+ return int(x) * int(y)
+ case int64:
+ return int(x) * int(y)
+ case float32:
+ return float64(x) * float64(y)
+ case float64:
+ return float64(x) * float64(y)
+ case time.Duration:
+ return time.Duration(x) * time.Duration(y)
+ }
+ case int64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) * int(y)
+ case uint8:
+ return int(x) * int(y)
+ case uint16:
+ return int(x) * int(y)
+ case uint32:
+ return int(x) * int(y)
+ case uint64:
+ return int(x) * int(y)
+ case int:
+ return int(x) * int(y)
+ case int8:
+ return int(x) * int(y)
+ case int16:
+ return int(x) * int(y)
+ case int32:
+ return int(x) * int(y)
+ case int64:
+ return int(x) * int(y)
+ case float32:
+ return float64(x) * float64(y)
+ case float64:
+ return float64(x) * float64(y)
+ case time.Duration:
+ return time.Duration(x) * time.Duration(y)
+ }
+ case float32:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) * float64(y)
+ case uint8:
+ return float64(x) * float64(y)
+ case uint16:
+ return float64(x) * float64(y)
+ case uint32:
+ return float64(x) * float64(y)
+ case uint64:
+ return float64(x) * float64(y)
+ case int:
+ return float64(x) * float64(y)
+ case int8:
+ return float64(x) * float64(y)
+ case int16:
+ return float64(x) * float64(y)
+ case int32:
+ return float64(x) * float64(y)
+ case int64:
+ return float64(x) * float64(y)
+ case float32:
+ return float64(x) * float64(y)
+ case float64:
+ return float64(x) * float64(y)
+ case time.Duration:
+ return float64(x) * float64(y)
+ }
+ case float64:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) * float64(y)
+ case uint8:
+ return float64(x) * float64(y)
+ case uint16:
+ return float64(x) * float64(y)
+ case uint32:
+ return float64(x) * float64(y)
+ case uint64:
+ return float64(x) * float64(y)
+ case int:
+ return float64(x) * float64(y)
+ case int8:
+ return float64(x) * float64(y)
+ case int16:
+ return float64(x) * float64(y)
+ case int32:
+ return float64(x) * float64(y)
+ case int64:
+ return float64(x) * float64(y)
+ case float32:
+ return float64(x) * float64(y)
+ case float64:
+ return float64(x) * float64(y)
+ case time.Duration:
+ return float64(x) * float64(y)
+ }
+ case time.Duration:
+ switch y := b.(type) {
+ case uint:
+ return time.Duration(x) * time.Duration(y)
+ case uint8:
+ return time.Duration(x) * time.Duration(y)
+ case uint16:
+ return time.Duration(x) * time.Duration(y)
+ case uint32:
+ return time.Duration(x) * time.Duration(y)
+ case uint64:
+ return time.Duration(x) * time.Duration(y)
+ case int:
+ return time.Duration(x) * time.Duration(y)
+ case int8:
+ return time.Duration(x) * time.Duration(y)
+ case int16:
+ return time.Duration(x) * time.Duration(y)
+ case int32:
+ return time.Duration(x) * time.Duration(y)
+ case int64:
+ return time.Duration(x) * time.Duration(y)
+ case float32:
+ return float64(x) * float64(y)
+ case float64:
+ return float64(x) * float64(y)
+ case time.Duration:
+ return time.Duration(x) * time.Duration(y)
+ }
+ }
+ panic(fmt.Sprintf("invalid operation: %T * %T", a, b))
+}
+
+func Divide(a, b interface{}) float64 {
+ switch x := a.(type) {
+ case uint:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) / float64(y)
+ case uint8:
+ return float64(x) / float64(y)
+ case uint16:
+ return float64(x) / float64(y)
+ case uint32:
+ return float64(x) / float64(y)
+ case uint64:
+ return float64(x) / float64(y)
+ case int:
+ return float64(x) / float64(y)
+ case int8:
+ return float64(x) / float64(y)
+ case int16:
+ return float64(x) / float64(y)
+ case int32:
+ return float64(x) / float64(y)
+ case int64:
+ return float64(x) / float64(y)
+ case float32:
+ return float64(x) / float64(y)
+ case float64:
+ return float64(x) / float64(y)
+ }
+ case uint8:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) / float64(y)
+ case uint8:
+ return float64(x) / float64(y)
+ case uint16:
+ return float64(x) / float64(y)
+ case uint32:
+ return float64(x) / float64(y)
+ case uint64:
+ return float64(x) / float64(y)
+ case int:
+ return float64(x) / float64(y)
+ case int8:
+ return float64(x) / float64(y)
+ case int16:
+ return float64(x) / float64(y)
+ case int32:
+ return float64(x) / float64(y)
+ case int64:
+ return float64(x) / float64(y)
+ case float32:
+ return float64(x) / float64(y)
+ case float64:
+ return float64(x) / float64(y)
+ }
+ case uint16:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) / float64(y)
+ case uint8:
+ return float64(x) / float64(y)
+ case uint16:
+ return float64(x) / float64(y)
+ case uint32:
+ return float64(x) / float64(y)
+ case uint64:
+ return float64(x) / float64(y)
+ case int:
+ return float64(x) / float64(y)
+ case int8:
+ return float64(x) / float64(y)
+ case int16:
+ return float64(x) / float64(y)
+ case int32:
+ return float64(x) / float64(y)
+ case int64:
+ return float64(x) / float64(y)
+ case float32:
+ return float64(x) / float64(y)
+ case float64:
+ return float64(x) / float64(y)
+ }
+ case uint32:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) / float64(y)
+ case uint8:
+ return float64(x) / float64(y)
+ case uint16:
+ return float64(x) / float64(y)
+ case uint32:
+ return float64(x) / float64(y)
+ case uint64:
+ return float64(x) / float64(y)
+ case int:
+ return float64(x) / float64(y)
+ case int8:
+ return float64(x) / float64(y)
+ case int16:
+ return float64(x) / float64(y)
+ case int32:
+ return float64(x) / float64(y)
+ case int64:
+ return float64(x) / float64(y)
+ case float32:
+ return float64(x) / float64(y)
+ case float64:
+ return float64(x) / float64(y)
+ }
+ case uint64:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) / float64(y)
+ case uint8:
+ return float64(x) / float64(y)
+ case uint16:
+ return float64(x) / float64(y)
+ case uint32:
+ return float64(x) / float64(y)
+ case uint64:
+ return float64(x) / float64(y)
+ case int:
+ return float64(x) / float64(y)
+ case int8:
+ return float64(x) / float64(y)
+ case int16:
+ return float64(x) / float64(y)
+ case int32:
+ return float64(x) / float64(y)
+ case int64:
+ return float64(x) / float64(y)
+ case float32:
+ return float64(x) / float64(y)
+ case float64:
+ return float64(x) / float64(y)
+ }
+ case int:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) / float64(y)
+ case uint8:
+ return float64(x) / float64(y)
+ case uint16:
+ return float64(x) / float64(y)
+ case uint32:
+ return float64(x) / float64(y)
+ case uint64:
+ return float64(x) / float64(y)
+ case int:
+ return float64(x) / float64(y)
+ case int8:
+ return float64(x) / float64(y)
+ case int16:
+ return float64(x) / float64(y)
+ case int32:
+ return float64(x) / float64(y)
+ case int64:
+ return float64(x) / float64(y)
+ case float32:
+ return float64(x) / float64(y)
+ case float64:
+ return float64(x) / float64(y)
+ }
+ case int8:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) / float64(y)
+ case uint8:
+ return float64(x) / float64(y)
+ case uint16:
+ return float64(x) / float64(y)
+ case uint32:
+ return float64(x) / float64(y)
+ case uint64:
+ return float64(x) / float64(y)
+ case int:
+ return float64(x) / float64(y)
+ case int8:
+ return float64(x) / float64(y)
+ case int16:
+ return float64(x) / float64(y)
+ case int32:
+ return float64(x) / float64(y)
+ case int64:
+ return float64(x) / float64(y)
+ case float32:
+ return float64(x) / float64(y)
+ case float64:
+ return float64(x) / float64(y)
+ }
+ case int16:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) / float64(y)
+ case uint8:
+ return float64(x) / float64(y)
+ case uint16:
+ return float64(x) / float64(y)
+ case uint32:
+ return float64(x) / float64(y)
+ case uint64:
+ return float64(x) / float64(y)
+ case int:
+ return float64(x) / float64(y)
+ case int8:
+ return float64(x) / float64(y)
+ case int16:
+ return float64(x) / float64(y)
+ case int32:
+ return float64(x) / float64(y)
+ case int64:
+ return float64(x) / float64(y)
+ case float32:
+ return float64(x) / float64(y)
+ case float64:
+ return float64(x) / float64(y)
+ }
+ case int32:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) / float64(y)
+ case uint8:
+ return float64(x) / float64(y)
+ case uint16:
+ return float64(x) / float64(y)
+ case uint32:
+ return float64(x) / float64(y)
+ case uint64:
+ return float64(x) / float64(y)
+ case int:
+ return float64(x) / float64(y)
+ case int8:
+ return float64(x) / float64(y)
+ case int16:
+ return float64(x) / float64(y)
+ case int32:
+ return float64(x) / float64(y)
+ case int64:
+ return float64(x) / float64(y)
+ case float32:
+ return float64(x) / float64(y)
+ case float64:
+ return float64(x) / float64(y)
+ }
+ case int64:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) / float64(y)
+ case uint8:
+ return float64(x) / float64(y)
+ case uint16:
+ return float64(x) / float64(y)
+ case uint32:
+ return float64(x) / float64(y)
+ case uint64:
+ return float64(x) / float64(y)
+ case int:
+ return float64(x) / float64(y)
+ case int8:
+ return float64(x) / float64(y)
+ case int16:
+ return float64(x) / float64(y)
+ case int32:
+ return float64(x) / float64(y)
+ case int64:
+ return float64(x) / float64(y)
+ case float32:
+ return float64(x) / float64(y)
+ case float64:
+ return float64(x) / float64(y)
+ }
+ case float32:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) / float64(y)
+ case uint8:
+ return float64(x) / float64(y)
+ case uint16:
+ return float64(x) / float64(y)
+ case uint32:
+ return float64(x) / float64(y)
+ case uint64:
+ return float64(x) / float64(y)
+ case int:
+ return float64(x) / float64(y)
+ case int8:
+ return float64(x) / float64(y)
+ case int16:
+ return float64(x) / float64(y)
+ case int32:
+ return float64(x) / float64(y)
+ case int64:
+ return float64(x) / float64(y)
+ case float32:
+ return float64(x) / float64(y)
+ case float64:
+ return float64(x) / float64(y)
+ }
+ case float64:
+ switch y := b.(type) {
+ case uint:
+ return float64(x) / float64(y)
+ case uint8:
+ return float64(x) / float64(y)
+ case uint16:
+ return float64(x) / float64(y)
+ case uint32:
+ return float64(x) / float64(y)
+ case uint64:
+ return float64(x) / float64(y)
+ case int:
+ return float64(x) / float64(y)
+ case int8:
+ return float64(x) / float64(y)
+ case int16:
+ return float64(x) / float64(y)
+ case int32:
+ return float64(x) / float64(y)
+ case int64:
+ return float64(x) / float64(y)
+ case float32:
+ return float64(x) / float64(y)
+ case float64:
+ return float64(x) / float64(y)
+ }
+ }
+ panic(fmt.Sprintf("invalid operation: %T / %T", a, b))
+}
+
+func Modulo(a, b interface{}) int {
+ switch x := a.(type) {
+ case uint:
+ switch y := b.(type) {
+ case uint:
+ return int(x) % int(y)
+ case uint8:
+ return int(x) % int(y)
+ case uint16:
+ return int(x) % int(y)
+ case uint32:
+ return int(x) % int(y)
+ case uint64:
+ return int(x) % int(y)
+ case int:
+ return int(x) % int(y)
+ case int8:
+ return int(x) % int(y)
+ case int16:
+ return int(x) % int(y)
+ case int32:
+ return int(x) % int(y)
+ case int64:
+ return int(x) % int(y)
+ }
+ case uint8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) % int(y)
+ case uint8:
+ return int(x) % int(y)
+ case uint16:
+ return int(x) % int(y)
+ case uint32:
+ return int(x) % int(y)
+ case uint64:
+ return int(x) % int(y)
+ case int:
+ return int(x) % int(y)
+ case int8:
+ return int(x) % int(y)
+ case int16:
+ return int(x) % int(y)
+ case int32:
+ return int(x) % int(y)
+ case int64:
+ return int(x) % int(y)
+ }
+ case uint16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) % int(y)
+ case uint8:
+ return int(x) % int(y)
+ case uint16:
+ return int(x) % int(y)
+ case uint32:
+ return int(x) % int(y)
+ case uint64:
+ return int(x) % int(y)
+ case int:
+ return int(x) % int(y)
+ case int8:
+ return int(x) % int(y)
+ case int16:
+ return int(x) % int(y)
+ case int32:
+ return int(x) % int(y)
+ case int64:
+ return int(x) % int(y)
+ }
+ case uint32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) % int(y)
+ case uint8:
+ return int(x) % int(y)
+ case uint16:
+ return int(x) % int(y)
+ case uint32:
+ return int(x) % int(y)
+ case uint64:
+ return int(x) % int(y)
+ case int:
+ return int(x) % int(y)
+ case int8:
+ return int(x) % int(y)
+ case int16:
+ return int(x) % int(y)
+ case int32:
+ return int(x) % int(y)
+ case int64:
+ return int(x) % int(y)
+ }
+ case uint64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) % int(y)
+ case uint8:
+ return int(x) % int(y)
+ case uint16:
+ return int(x) % int(y)
+ case uint32:
+ return int(x) % int(y)
+ case uint64:
+ return int(x) % int(y)
+ case int:
+ return int(x) % int(y)
+ case int8:
+ return int(x) % int(y)
+ case int16:
+ return int(x) % int(y)
+ case int32:
+ return int(x) % int(y)
+ case int64:
+ return int(x) % int(y)
+ }
+ case int:
+ switch y := b.(type) {
+ case uint:
+ return int(x) % int(y)
+ case uint8:
+ return int(x) % int(y)
+ case uint16:
+ return int(x) % int(y)
+ case uint32:
+ return int(x) % int(y)
+ case uint64:
+ return int(x) % int(y)
+ case int:
+ return int(x) % int(y)
+ case int8:
+ return int(x) % int(y)
+ case int16:
+ return int(x) % int(y)
+ case int32:
+ return int(x) % int(y)
+ case int64:
+ return int(x) % int(y)
+ }
+ case int8:
+ switch y := b.(type) {
+ case uint:
+ return int(x) % int(y)
+ case uint8:
+ return int(x) % int(y)
+ case uint16:
+ return int(x) % int(y)
+ case uint32:
+ return int(x) % int(y)
+ case uint64:
+ return int(x) % int(y)
+ case int:
+ return int(x) % int(y)
+ case int8:
+ return int(x) % int(y)
+ case int16:
+ return int(x) % int(y)
+ case int32:
+ return int(x) % int(y)
+ case int64:
+ return int(x) % int(y)
+ }
+ case int16:
+ switch y := b.(type) {
+ case uint:
+ return int(x) % int(y)
+ case uint8:
+ return int(x) % int(y)
+ case uint16:
+ return int(x) % int(y)
+ case uint32:
+ return int(x) % int(y)
+ case uint64:
+ return int(x) % int(y)
+ case int:
+ return int(x) % int(y)
+ case int8:
+ return int(x) % int(y)
+ case int16:
+ return int(x) % int(y)
+ case int32:
+ return int(x) % int(y)
+ case int64:
+ return int(x) % int(y)
+ }
+ case int32:
+ switch y := b.(type) {
+ case uint:
+ return int(x) % int(y)
+ case uint8:
+ return int(x) % int(y)
+ case uint16:
+ return int(x) % int(y)
+ case uint32:
+ return int(x) % int(y)
+ case uint64:
+ return int(x) % int(y)
+ case int:
+ return int(x) % int(y)
+ case int8:
+ return int(x) % int(y)
+ case int16:
+ return int(x) % int(y)
+ case int32:
+ return int(x) % int(y)
+ case int64:
+ return int(x) % int(y)
+ }
+ case int64:
+ switch y := b.(type) {
+ case uint:
+ return int(x) % int(y)
+ case uint8:
+ return int(x) % int(y)
+ case uint16:
+ return int(x) % int(y)
+ case uint32:
+ return int(x) % int(y)
+ case uint64:
+ return int(x) % int(y)
+ case int:
+ return int(x) % int(y)
+ case int8:
+ return int(x) % int(y)
+ case int16:
+ return int(x) % int(y)
+ case int32:
+ return int(x) % int(y)
+ case int64:
+ return int(x) % int(y)
+ }
+ }
+ panic(fmt.Sprintf("invalid operation: %T %% %T", a, b))
+}
diff --git a/vendor/github.com/expr-lang/expr/vm/runtime/runtime.go b/vendor/github.com/expr-lang/expr/vm/runtime/runtime.go
new file mode 100644
index 0000000..cd48a28
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/vm/runtime/runtime.go
@@ -0,0 +1,394 @@
+package runtime
+
+//go:generate sh -c "go run ./helpers > ./helpers[generated].go"
+
+import (
+ "fmt"
+ "math"
+ "reflect"
+
+ "github.com/expr-lang/expr/internal/deref"
+)
+
+func Fetch(from, i any) any {
+ v := reflect.ValueOf(from)
+ if v.Kind() == reflect.Invalid {
+ panic(fmt.Sprintf("cannot fetch %v from %T", i, from))
+ }
+
+ // Methods can be defined on any type.
+ if v.NumMethod() > 0 {
+ if methodName, ok := i.(string); ok {
+ method := v.MethodByName(methodName)
+ if method.IsValid() {
+ return method.Interface()
+ }
+ }
+ }
+
+ // Structs, maps, and slices can be access through a pointer or through
+ // a value, when they are accessed through a pointer we don't want to
+ // copy them to a value.
+ // De-reference everything if necessary (interface and pointers)
+ v = deref.Value(v)
+
+ switch v.Kind() {
+ case reflect.Array, reflect.Slice, reflect.String:
+ index := ToInt(i)
+ l := v.Len()
+ if index < 0 {
+ index = l + index
+ }
+ if index < 0 || index >= l {
+ panic(fmt.Sprintf("index out of range: %v (array length is %v)", index, l))
+ }
+ value := v.Index(index)
+ if value.IsValid() {
+ return value.Interface()
+ }
+
+ case reflect.Map:
+ var value reflect.Value
+ if i == nil {
+ value = v.MapIndex(reflect.Zero(v.Type().Key()))
+ } else {
+ value = v.MapIndex(reflect.ValueOf(i))
+ }
+ if value.IsValid() {
+ return value.Interface()
+ } else {
+ elem := reflect.TypeOf(from).Elem()
+ return reflect.Zero(elem).Interface()
+ }
+
+ case reflect.Struct:
+ fieldName := i.(string)
+ value := v.FieldByNameFunc(func(name string) bool {
+ field, _ := v.Type().FieldByName(name)
+ if field.Tag.Get("expr") == fieldName {
+ return true
+ }
+ return name == fieldName
+ })
+ if value.IsValid() {
+ return value.Interface()
+ }
+ }
+ panic(fmt.Sprintf("cannot fetch %v from %T", i, from))
+}
+
+type Field struct {
+ Index []int
+ Path []string
+}
+
+func FetchField(from any, field *Field) any {
+ v := reflect.ValueOf(from)
+ if v.Kind() != reflect.Invalid {
+ v = reflect.Indirect(v)
+
+ // We can use v.FieldByIndex here, but it will panic if the field
+ // is not exists. And we need to recover() to generate a more
+ // user-friendly error message.
+ // Also, our fieldByIndex() function is slightly faster than the
+ // v.FieldByIndex() function as we don't need to verify what a field
+ // is a struct as we already did it on compilation step.
+ value := fieldByIndex(v, field)
+ if value.IsValid() {
+ return value.Interface()
+ }
+ }
+ panic(fmt.Sprintf("cannot get %v from %T", field.Path[0], from))
+}
+
+func fieldByIndex(v reflect.Value, field *Field) reflect.Value {
+ if len(field.Index) == 1 {
+ return v.Field(field.Index[0])
+ }
+ for i, x := range field.Index {
+ if i > 0 {
+ if v.Kind() == reflect.Ptr {
+ if v.IsNil() {
+ panic(fmt.Sprintf("cannot get %v from %v", field.Path[i], field.Path[i-1]))
+ }
+ v = v.Elem()
+ }
+ }
+ v = v.Field(x)
+ }
+ return v
+}
+
+type Method struct {
+ Index int
+ Name string
+}
+
+func FetchMethod(from any, method *Method) any {
+ v := reflect.ValueOf(from)
+ kind := v.Kind()
+ if kind != reflect.Invalid {
+ // Methods can be defined on any type, no need to dereference.
+ method := v.Method(method.Index)
+ if method.IsValid() {
+ return method.Interface()
+ }
+ }
+ panic(fmt.Sprintf("cannot fetch %v from %T", method.Name, from))
+}
+
+func Slice(array, from, to any) any {
+ v := reflect.ValueOf(array)
+
+ switch v.Kind() {
+ case reflect.Array, reflect.Slice, reflect.String:
+ length := v.Len()
+ a, b := ToInt(from), ToInt(to)
+ if a < 0 {
+ a = length + a
+ }
+ if a < 0 {
+ a = 0
+ }
+ if b < 0 {
+ b = length + b
+ }
+ if b < 0 {
+ b = 0
+ }
+ if b > length {
+ b = length
+ }
+ if a > b {
+ a = b
+ }
+ value := v.Slice(a, b)
+ if value.IsValid() {
+ return value.Interface()
+ }
+
+ case reflect.Ptr:
+ value := v.Elem()
+ if value.IsValid() {
+ return Slice(value.Interface(), from, to)
+ }
+
+ }
+ panic(fmt.Sprintf("cannot slice %v", from))
+}
+
+func In(needle any, array any) bool {
+ if array == nil {
+ return false
+ }
+ v := reflect.ValueOf(array)
+
+ switch v.Kind() {
+
+ case reflect.Array, reflect.Slice:
+ for i := 0; i < v.Len(); i++ {
+ value := v.Index(i)
+ if value.IsValid() {
+ if Equal(value.Interface(), needle) {
+ return true
+ }
+ }
+ }
+ return false
+
+ case reflect.Map:
+ var value reflect.Value
+ if needle == nil {
+ value = v.MapIndex(reflect.Zero(v.Type().Key()))
+ } else {
+ value = v.MapIndex(reflect.ValueOf(needle))
+ }
+ if value.IsValid() {
+ return true
+ }
+ return false
+
+ case reflect.Struct:
+ n := reflect.ValueOf(needle)
+ if !n.IsValid() || n.Kind() != reflect.String {
+ panic(fmt.Sprintf("cannot use %T as field name of %T", needle, array))
+ }
+ value := v.FieldByName(n.String())
+ if value.IsValid() {
+ return true
+ }
+ return false
+
+ case reflect.Ptr:
+ value := v.Elem()
+ if value.IsValid() {
+ return In(needle, value.Interface())
+ }
+ return false
+ }
+
+ panic(fmt.Sprintf(`operator "in" not defined on %T`, array))
+}
+
+func Len(a any) int {
+ v := reflect.ValueOf(a)
+ switch v.Kind() {
+ case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
+ return v.Len()
+ default:
+ panic(fmt.Sprintf("invalid argument for len (type %T)", a))
+ }
+}
+
+func Negate(i any) any {
+ switch v := i.(type) {
+ case float32:
+ return -v
+ case float64:
+ return -v
+ case int:
+ return -v
+ case int8:
+ return -v
+ case int16:
+ return -v
+ case int32:
+ return -v
+ case int64:
+ return -v
+ case uint:
+ return -v
+ case uint8:
+ return -v
+ case uint16:
+ return -v
+ case uint32:
+ return -v
+ case uint64:
+ return -v
+ default:
+ panic(fmt.Sprintf("invalid operation: - %T", v))
+ }
+}
+
+func Exponent(a, b any) float64 {
+ return math.Pow(ToFloat64(a), ToFloat64(b))
+}
+
+func MakeRange(min, max int) []int {
+ size := max - min + 1
+ if size <= 0 {
+ return []int{}
+ }
+ rng := make([]int, size)
+ for i := range rng {
+ rng[i] = min + i
+ }
+ return rng
+}
+
+func ToInt(a any) int {
+ switch x := a.(type) {
+ case float32:
+ return int(x)
+ case float64:
+ return int(x)
+ case int:
+ return x
+ case int8:
+ return int(x)
+ case int16:
+ return int(x)
+ case int32:
+ return int(x)
+ case int64:
+ return int(x)
+ case uint:
+ return int(x)
+ case uint8:
+ return int(x)
+ case uint16:
+ return int(x)
+ case uint32:
+ return int(x)
+ case uint64:
+ return int(x)
+ default:
+ panic(fmt.Sprintf("invalid operation: int(%T)", x))
+ }
+}
+
+func ToInt64(a any) int64 {
+ switch x := a.(type) {
+ case float32:
+ return int64(x)
+ case float64:
+ return int64(x)
+ case int:
+ return int64(x)
+ case int8:
+ return int64(x)
+ case int16:
+ return int64(x)
+ case int32:
+ return int64(x)
+ case int64:
+ return x
+ case uint:
+ return int64(x)
+ case uint8:
+ return int64(x)
+ case uint16:
+ return int64(x)
+ case uint32:
+ return int64(x)
+ case uint64:
+ return int64(x)
+ default:
+ panic(fmt.Sprintf("invalid operation: int64(%T)", x))
+ }
+}
+
+func ToFloat64(a any) float64 {
+ switch x := a.(type) {
+ case float32:
+ return float64(x)
+ case float64:
+ return x
+ case int:
+ return float64(x)
+ case int8:
+ return float64(x)
+ case int16:
+ return float64(x)
+ case int32:
+ return float64(x)
+ case int64:
+ return float64(x)
+ case uint:
+ return float64(x)
+ case uint8:
+ return float64(x)
+ case uint16:
+ return float64(x)
+ case uint32:
+ return float64(x)
+ case uint64:
+ return float64(x)
+ default:
+ panic(fmt.Sprintf("invalid operation: float(%T)", x))
+ }
+}
+
+func IsNil(v any) bool {
+ if v == nil {
+ return true
+ }
+ r := reflect.ValueOf(v)
+ switch r.Kind() {
+ case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Slice:
+ return r.IsNil()
+ default:
+ return false
+ }
+}
diff --git a/vendor/github.com/expr-lang/expr/vm/runtime/sort.go b/vendor/github.com/expr-lang/expr/vm/runtime/sort.go
new file mode 100644
index 0000000..fb1f340
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/vm/runtime/sort.go
@@ -0,0 +1,45 @@
+package runtime
+
+type SortBy struct {
+ Desc bool
+ Array []any
+ Values []any
+}
+
+func (s *SortBy) Len() int {
+ return len(s.Array)
+}
+
+func (s *SortBy) Swap(i, j int) {
+ s.Array[i], s.Array[j] = s.Array[j], s.Array[i]
+ s.Values[i], s.Values[j] = s.Values[j], s.Values[i]
+}
+
+func (s *SortBy) Less(i, j int) bool {
+ a, b := s.Values[i], s.Values[j]
+ if s.Desc {
+ return Less(b, a)
+ }
+ return Less(a, b)
+}
+
+type Sort struct {
+ Desc bool
+ Array []any
+}
+
+func (s *Sort) Len() int {
+ return len(s.Array)
+}
+
+func (s *Sort) Swap(i, j int) {
+ s.Array[i], s.Array[j] = s.Array[j], s.Array[i]
+}
+
+func (s *Sort) Less(i, j int) bool {
+ a, b := s.Array[i], s.Array[j]
+ if s.Desc {
+ return Less(b, a)
+ }
+ return Less(a, b)
+}
diff --git a/vendor/github.com/expr-lang/expr/vm/utils.go b/vendor/github.com/expr-lang/expr/vm/utils.go
new file mode 100644
index 0000000..1100513
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/vm/utils.go
@@ -0,0 +1,37 @@
+package vm
+
+import (
+ "reflect"
+ "time"
+)
+
+type (
+ Function = func(params ...any) (any, error)
+ SafeFunction = func(params ...any) (any, uint, error)
+)
+
+var (
+ errorType = reflect.TypeOf((*error)(nil)).Elem()
+)
+
+type Scope struct {
+ Array reflect.Value
+ Index int
+ Len int
+ Count int
+ Acc any
+}
+
+type groupBy = map[any][]any
+
+type Span struct {
+ Name string `json:"name"`
+ Expression string `json:"expression"`
+ Duration int64 `json:"duration"`
+ Children []*Span `json:"children"`
+ start time.Time
+}
+
+func GetSpan(program *Program) *Span {
+ return program.span
+}
diff --git a/vendor/github.com/expr-lang/expr/vm/vm.go b/vendor/github.com/expr-lang/expr/vm/vm.go
new file mode 100644
index 0000000..de13cad
--- /dev/null
+++ b/vendor/github.com/expr-lang/expr/vm/vm.go
@@ -0,0 +1,617 @@
+package vm
+
+//go:generate sh -c "go run ./func_types > ./func_types[generated].go"
+
+import (
+ "fmt"
+ "reflect"
+ "regexp"
+ "sort"
+ "strings"
+ "time"
+
+ "github.com/expr-lang/expr/builtin"
+ "github.com/expr-lang/expr/conf"
+ "github.com/expr-lang/expr/file"
+ "github.com/expr-lang/expr/internal/deref"
+ "github.com/expr-lang/expr/vm/runtime"
+)
+
+func Run(program *Program, env any) (any, error) {
+ if program == nil {
+ return nil, fmt.Errorf("program is nil")
+ }
+ vm := VM{}
+ return vm.Run(program, env)
+}
+
+func Debug() *VM {
+ vm := &VM{
+ debug: true,
+ step: make(chan struct{}, 0),
+ curr: make(chan int, 0),
+ }
+ return vm
+}
+
+type VM struct {
+ Stack []any
+ Scopes []*Scope
+ Variables []any
+ MemoryBudget uint
+ ip int
+ memory uint
+ debug bool
+ step chan struct{}
+ curr chan int
+}
+
+func (vm *VM) Run(program *Program, env any) (_ any, err error) {
+ defer func() {
+ if r := recover(); r != nil {
+ var location file.Location
+ if vm.ip-1 < len(program.locations) {
+ location = program.locations[vm.ip-1]
+ }
+ f := &file.Error{
+ Location: location,
+ Message: fmt.Sprintf("%v", r),
+ }
+ if err, ok := r.(error); ok {
+ f.Wrap(err)
+ }
+ err = f.Bind(program.source)
+ }
+ }()
+
+ if vm.Stack == nil {
+ vm.Stack = make([]any, 0, 2)
+ } else {
+ vm.Stack = vm.Stack[0:0]
+ }
+ if vm.Scopes != nil {
+ vm.Scopes = vm.Scopes[0:0]
+ }
+ if len(vm.Variables) < program.variables {
+ vm.Variables = make([]any, program.variables)
+ }
+
+ if vm.MemoryBudget == 0 {
+ vm.MemoryBudget = conf.DefaultMemoryBudget
+ }
+ vm.memory = 0
+ vm.ip = 0
+
+ for vm.ip < len(program.Bytecode) {
+ if debug && vm.debug {
+ <-vm.step
+ }
+
+ op := program.Bytecode[vm.ip]
+ arg := program.Arguments[vm.ip]
+ vm.ip += 1
+
+ switch op {
+
+ case OpInvalid:
+ panic("invalid opcode")
+
+ case OpPush:
+ vm.push(program.Constants[arg])
+
+ case OpInt:
+ vm.push(arg)
+
+ case OpPop:
+ vm.pop()
+
+ case OpStore:
+ vm.Variables[arg] = vm.pop()
+
+ case OpLoadVar:
+ vm.push(vm.Variables[arg])
+
+ case OpLoadConst:
+ vm.push(runtime.Fetch(env, program.Constants[arg]))
+
+ case OpLoadField:
+ vm.push(runtime.FetchField(env, program.Constants[arg].(*runtime.Field)))
+
+ case OpLoadFast:
+ vm.push(env.(map[string]any)[program.Constants[arg].(string)])
+
+ case OpLoadMethod:
+ vm.push(runtime.FetchMethod(env, program.Constants[arg].(*runtime.Method)))
+
+ case OpLoadFunc:
+ vm.push(program.functions[arg])
+
+ case OpFetch:
+ b := vm.pop()
+ a := vm.pop()
+ vm.push(runtime.Fetch(a, b))
+
+ case OpFetchField:
+ a := vm.pop()
+ vm.push(runtime.FetchField(a, program.Constants[arg].(*runtime.Field)))
+
+ case OpLoadEnv:
+ vm.push(env)
+
+ case OpMethod:
+ a := vm.pop()
+ vm.push(runtime.FetchMethod(a, program.Constants[arg].(*runtime.Method)))
+
+ case OpTrue:
+ vm.push(true)
+
+ case OpFalse:
+ vm.push(false)
+
+ case OpNil:
+ vm.push(nil)
+
+ case OpNegate:
+ v := runtime.Negate(vm.pop())
+ vm.push(v)
+
+ case OpNot:
+ v := vm.pop().(bool)
+ vm.push(!v)
+
+ case OpEqual:
+ b := vm.pop()
+ a := vm.pop()
+ vm.push(runtime.Equal(a, b))
+
+ case OpEqualInt:
+ b := vm.pop()
+ a := vm.pop()
+ vm.push(a.(int) == b.(int))
+
+ case OpEqualString:
+ b := vm.pop()
+ a := vm.pop()
+ vm.push(a.(string) == b.(string))
+
+ case OpJump:
+ vm.ip += arg
+
+ case OpJumpIfTrue:
+ if vm.current().(bool) {
+ vm.ip += arg
+ }
+
+ case OpJumpIfFalse:
+ if !vm.current().(bool) {
+ vm.ip += arg
+ }
+
+ case OpJumpIfNil:
+ if runtime.IsNil(vm.current()) {
+ vm.ip += arg
+ }
+
+ case OpJumpIfNotNil:
+ if !runtime.IsNil(vm.current()) {
+ vm.ip += arg
+ }
+
+ case OpJumpIfEnd:
+ scope := vm.scope()
+ if scope.Index >= scope.Len {
+ vm.ip += arg
+ }
+
+ case OpJumpBackward:
+ vm.ip -= arg
+
+ case OpIn:
+ b := vm.pop()
+ a := vm.pop()
+ vm.push(runtime.In(a, b))
+
+ case OpLess:
+ b := vm.pop()
+ a := vm.pop()
+ vm.push(runtime.Less(a, b))
+
+ case OpMore:
+ b := vm.pop()
+ a := vm.pop()
+ vm.push(runtime.More(a, b))
+
+ case OpLessOrEqual:
+ b := vm.pop()
+ a := vm.pop()
+ vm.push(runtime.LessOrEqual(a, b))
+
+ case OpMoreOrEqual:
+ b := vm.pop()
+ a := vm.pop()
+ vm.push(runtime.MoreOrEqual(a, b))
+
+ case OpAdd:
+ b := vm.pop()
+ a := vm.pop()
+ vm.push(runtime.Add(a, b))
+
+ case OpSubtract:
+ b := vm.pop()
+ a := vm.pop()
+ vm.push(runtime.Subtract(a, b))
+
+ case OpMultiply:
+ b := vm.pop()
+ a := vm.pop()
+ vm.push(runtime.Multiply(a, b))
+
+ case OpDivide:
+ b := vm.pop()
+ a := vm.pop()
+ vm.push(runtime.Divide(a, b))
+
+ case OpModulo:
+ b := vm.pop()
+ a := vm.pop()
+ vm.push(runtime.Modulo(a, b))
+
+ case OpExponent:
+ b := vm.pop()
+ a := vm.pop()
+ vm.push(runtime.Exponent(a, b))
+
+ case OpRange:
+ b := vm.pop()
+ a := vm.pop()
+ min := runtime.ToInt(a)
+ max := runtime.ToInt(b)
+ size := max - min + 1
+ if size <= 0 {
+ size = 0
+ }
+ vm.memGrow(uint(size))
+ vm.push(runtime.MakeRange(min, max))
+
+ case OpMatches:
+ b := vm.pop()
+ a := vm.pop()
+ if runtime.IsNil(a) || runtime.IsNil(b) {
+ vm.push(false)
+ break
+ }
+ match, err := regexp.MatchString(b.(string), a.(string))
+ if err != nil {
+ panic(err)
+ }
+ vm.push(match)
+
+ case OpMatchesConst:
+ a := vm.pop()
+ if runtime.IsNil(a) {
+ vm.push(false)
+ break
+ }
+ r := program.Constants[arg].(*regexp.Regexp)
+ vm.push(r.MatchString(a.(string)))
+
+ case OpContains:
+ b := vm.pop()
+ a := vm.pop()
+ if runtime.IsNil(a) || runtime.IsNil(b) {
+ vm.push(false)
+ break
+ }
+ vm.push(strings.Contains(a.(string), b.(string)))
+
+ case OpStartsWith:
+ b := vm.pop()
+ a := vm.pop()
+ if runtime.IsNil(a) || runtime.IsNil(b) {
+ vm.push(false)
+ break
+ }
+ vm.push(strings.HasPrefix(a.(string), b.(string)))
+
+ case OpEndsWith:
+ b := vm.pop()
+ a := vm.pop()
+ if runtime.IsNil(a) || runtime.IsNil(b) {
+ vm.push(false)
+ break
+ }
+ vm.push(strings.HasSuffix(a.(string), b.(string)))
+
+ case OpSlice:
+ from := vm.pop()
+ to := vm.pop()
+ node := vm.pop()
+ vm.push(runtime.Slice(node, from, to))
+
+ case OpCall:
+ fn := reflect.ValueOf(vm.pop())
+ size := arg
+ in := make([]reflect.Value, size)
+ for i := int(size) - 1; i >= 0; i-- {
+ param := vm.pop()
+ if param == nil {
+ in[i] = reflect.Zero(fn.Type().In(i))
+ } else {
+ in[i] = reflect.ValueOf(param)
+ }
+ }
+ out := fn.Call(in)
+ if len(out) == 2 && out[1].Type() == errorType && !out[1].IsNil() {
+ panic(out[1].Interface().(error))
+ }
+ vm.push(out[0].Interface())
+
+ case OpCall0:
+ out, err := program.functions[arg]()
+ if err != nil {
+ panic(err)
+ }
+ vm.push(out)
+
+ case OpCall1:
+ a := vm.pop()
+ out, err := program.functions[arg](a)
+ if err != nil {
+ panic(err)
+ }
+ vm.push(out)
+
+ case OpCall2:
+ b := vm.pop()
+ a := vm.pop()
+ out, err := program.functions[arg](a, b)
+ if err != nil {
+ panic(err)
+ }
+ vm.push(out)
+
+ case OpCall3:
+ c := vm.pop()
+ b := vm.pop()
+ a := vm.pop()
+ out, err := program.functions[arg](a, b, c)
+ if err != nil {
+ panic(err)
+ }
+ vm.push(out)
+
+ case OpCallN:
+ fn := vm.pop().(Function)
+ size := arg
+ in := make([]any, size)
+ for i := int(size) - 1; i >= 0; i-- {
+ in[i] = vm.pop()
+ }
+ out, err := fn(in...)
+ if err != nil {
+ panic(err)
+ }
+ vm.push(out)
+
+ case OpCallFast:
+ fn := vm.pop().(func(...any) any)
+ size := arg
+ in := make([]any, size)
+ for i := int(size) - 1; i >= 0; i-- {
+ in[i] = vm.pop()
+ }
+ vm.push(fn(in...))
+
+ case OpCallSafe:
+ fn := vm.pop().(SafeFunction)
+ size := arg
+ in := make([]any, size)
+ for i := int(size) - 1; i >= 0; i-- {
+ in[i] = vm.pop()
+ }
+ out, mem, err := fn(in...)
+ if err != nil {
+ panic(err)
+ }
+ vm.memGrow(mem)
+ vm.push(out)
+
+ case OpCallTyped:
+ vm.push(vm.call(vm.pop(), arg))
+
+ case OpCallBuiltin1:
+ vm.push(builtin.Builtins[arg].Fast(vm.pop()))
+
+ case OpArray:
+ size := vm.pop().(int)
+ vm.memGrow(uint(size))
+ array := make([]any, size)
+ for i := size - 1; i >= 0; i-- {
+ array[i] = vm.pop()
+ }
+ vm.push(array)
+
+ case OpMap:
+ size := vm.pop().(int)
+ vm.memGrow(uint(size))
+ m := make(map[string]any)
+ for i := size - 1; i >= 0; i-- {
+ value := vm.pop()
+ key := vm.pop()
+ m[key.(string)] = value
+ }
+ vm.push(m)
+
+ case OpLen:
+ vm.push(runtime.Len(vm.current()))
+
+ case OpCast:
+ switch arg {
+ case 0:
+ vm.push(runtime.ToInt(vm.pop()))
+ case 1:
+ vm.push(runtime.ToInt64(vm.pop()))
+ case 2:
+ vm.push(runtime.ToFloat64(vm.pop()))
+ }
+
+ case OpDeref:
+ a := vm.pop()
+ vm.push(deref.Interface(a))
+
+ case OpIncrementIndex:
+ vm.scope().Index++
+
+ case OpDecrementIndex:
+ scope := vm.scope()
+ scope.Index--
+
+ case OpIncrementCount:
+ scope := vm.scope()
+ scope.Count++
+
+ case OpGetIndex:
+ vm.push(vm.scope().Index)
+
+ case OpGetCount:
+ scope := vm.scope()
+ vm.push(scope.Count)
+
+ case OpGetLen:
+ scope := vm.scope()
+ vm.push(scope.Len)
+
+ case OpGetAcc:
+ vm.push(vm.scope().Acc)
+
+ case OpSetAcc:
+ vm.scope().Acc = vm.pop()
+
+ case OpSetIndex:
+ scope := vm.scope()
+ scope.Index = vm.pop().(int)
+
+ case OpPointer:
+ scope := vm.scope()
+ vm.push(scope.Array.Index(scope.Index).Interface())
+
+ case OpThrow:
+ panic(vm.pop().(error))
+
+ case OpCreate:
+ switch arg {
+ case 1:
+ vm.push(make(groupBy))
+ case 2:
+ scope := vm.scope()
+ var desc bool
+ switch vm.pop().(string) {
+ case "asc":
+ desc = false
+ case "desc":
+ desc = true
+ default:
+ panic("unknown order, use asc or desc")
+ }
+ vm.push(&runtime.SortBy{
+ Desc: desc,
+ Array: make([]any, 0, scope.Len),
+ Values: make([]any, 0, scope.Len),
+ })
+ default:
+ panic(fmt.Sprintf("unknown OpCreate argument %v", arg))
+ }
+
+ case OpGroupBy:
+ scope := vm.scope()
+ key := vm.pop()
+ item := scope.Array.Index(scope.Index).Interface()
+ scope.Acc.(groupBy)[key] = append(scope.Acc.(groupBy)[key], item)
+
+ case OpSortBy:
+ scope := vm.scope()
+ value := vm.pop()
+ item := scope.Array.Index(scope.Index).Interface()
+ sortable := scope.Acc.(*runtime.SortBy)
+ sortable.Array = append(sortable.Array, item)
+ sortable.Values = append(sortable.Values, value)
+
+ case OpSort:
+ scope := vm.scope()
+ sortable := scope.Acc.(*runtime.SortBy)
+ sort.Sort(sortable)
+ vm.memGrow(uint(scope.Len))
+ vm.push(sortable.Array)
+
+ case OpProfileStart:
+ span := program.Constants[arg].(*Span)
+ span.start = time.Now()
+
+ case OpProfileEnd:
+ span := program.Constants[arg].(*Span)
+ span.Duration += time.Since(span.start).Nanoseconds()
+
+ case OpBegin:
+ a := vm.pop()
+ array := reflect.ValueOf(a)
+ vm.Scopes = append(vm.Scopes, &Scope{
+ Array: array,
+ Len: array.Len(),
+ })
+
+ case OpEnd:
+ vm.Scopes = vm.Scopes[:len(vm.Scopes)-1]
+
+ default:
+ panic(fmt.Sprintf("unknown bytecode %#x", op))
+ }
+
+ if debug && vm.debug {
+ vm.curr <- vm.ip
+ }
+ }
+
+ if debug && vm.debug {
+ close(vm.curr)
+ close(vm.step)
+ }
+
+ if len(vm.Stack) > 0 {
+ return vm.pop(), nil
+ }
+
+ return nil, nil
+}
+
+func (vm *VM) push(value any) {
+ vm.Stack = append(vm.Stack, value)
+}
+
+func (vm *VM) current() any {
+ return vm.Stack[len(vm.Stack)-1]
+}
+
+func (vm *VM) pop() any {
+ value := vm.Stack[len(vm.Stack)-1]
+ vm.Stack = vm.Stack[:len(vm.Stack)-1]
+ return value
+}
+
+func (vm *VM) memGrow(size uint) {
+ vm.memory += size
+ if vm.memory >= vm.MemoryBudget {
+ panic("memory budget exceeded")
+ }
+}
+
+func (vm *VM) scope() *Scope {
+ return vm.Scopes[len(vm.Scopes)-1]
+}
+
+func (vm *VM) Step() {
+ vm.step <- struct{}{}
+}
+
+func (vm *VM) Position() chan int {
+ return vm.curr
+}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/.gitignore b/vendor/github.com/lucasb-eyer/go-colorful/.gitignore
new file mode 100644
index 0000000..0aa2c92
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/.gitignore
@@ -0,0 +1,101 @@
+# Created by https://www.toptal.com/developers/gitignore/api/code,go,linux,macos,windows
+# Edit at https://www.toptal.com/developers/gitignore?templates=code,go,linux,macos,windows
+
+### Code ###
+.vscode/*
+!.vscode/tasks.json
+!.vscode/launch.json
+*.code-workspace
+
+### Go ###
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Dependency directories (remove the comment below to include it)
+# vendor/
+
+### Go Patch ###
+/vendor/
+/Godeps/
+
+### Linux ###
+*~
+
+# temporary files which can be created if a process still has a handle open of a deleted file
+.fuse_hidden*
+
+# KDE directory preferences
+.directory
+
+# Linux trash folder which might appear on any partition or disk
+.Trash-*
+
+# .nfs files are created when an open file is removed but is still being accessed
+.nfs*
+
+### macOS ###
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+### Windows ###
+# Windows thumbnail cache files
+Thumbs.db
+Thumbs.db:encryptable
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# End of https://www.toptal.com/developers/gitignore/api/code,go,linux,macos,windows
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/CHANGELOG.md b/vendor/github.com/lucasb-eyer/go-colorful/CHANGELOG.md
new file mode 100644
index 0000000..84f9c7b
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/CHANGELOG.md
@@ -0,0 +1,42 @@
+# Changelog
+All notable changes to this project will be documented in this file.
+
+This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+The format of this file is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+but only releases after v1.0.3 properly adhere to it.
+
+
+## [1.2.0] - 2021-01-27
+### Added
+- HSLuv and HPLuv color spaces (#41, #51)
+- CIE LCh(uv) color space, called `LuvLCh` in code (#51)
+- JSON and envconfig serialization support for `HexColor` (#42)
+- `DistanceLinearRGB` (#53)
+
+### Fixed
+- RGB to/from XYZ conversion is more accurate (#51)
+- A bug in `XYZToLuvWhiteRef` that only applied to very small values was fixed (#51)
+- `BlendHCL` output is clamped so that it's not invalid (#46)
+- Properly documented `DistanceCIE76` (#40)
+- Some small godoc fixes
+
+
+## [1.0.3] - 2019-11-11
+- Remove SQLMock dependency
+
+
+## [1.0.2] - 2019-04-07
+- Fixes SQLMock dependency
+
+
+## [1.0.1] - 2019-03-24
+- Adds support for Go Modules
+
+
+## [1.0.0] - 2018-05-26
+- API Breaking change in `MakeColor`: instead of `panic`ing when alpha is zero, it now returns a secondary, boolean return value indicating success. See [the color.Color interface](#the-colorcolor-interface) section and [this FAQ entry](#q-why-would-makecolor-ever-fail) for details.
+
+
+## [0.9.0] - 2018-05-26
+- Initial version number after having ignored versioning for a long time :)
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/LICENSE b/vendor/github.com/lucasb-eyer/go-colorful/LICENSE
new file mode 100644
index 0000000..4e402a0
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/LICENSE
@@ -0,0 +1,7 @@
+Copyright (c) 2013 Lucas Beyer
+
+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/vendor/github.com/lucasb-eyer/go-colorful/README.md b/vendor/github.com/lucasb-eyer/go-colorful/README.md
new file mode 100644
index 0000000..8b9bd49
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/README.md
@@ -0,0 +1,482 @@
+go-colorful
+===========
+
+[](https://goreportcard.com/report/github.com/lucasb-eyer/go-colorful)
+
+A library for playing with colors in Go. Supports Go 1.13 onwards.
+
+Why?
+====
+I love games. I make games. I love detail and I get lost in detail.
+One such detail popped up during the development of [Memory Which Does Not Suck](https://github.com/lucasb-eyer/mwdns/),
+when we wanted the server to assign the players random colors. Sometimes
+two players got very similar colors, which bugged me. The very same evening,
+[I want hue](http://tools.medialab.sciences-po.fr/iwanthue/) was the top post
+on HackerNews' frontpage and showed me how to Do It Right™. Last but not
+least, there was no library for handling color spaces available in go. Colorful
+does just that and implements Go's `color.Color` interface.
+
+What?
+=====
+Go-Colorful stores colors in RGB and provides methods from converting these to various color-spaces. Currently supported colorspaces are:
+
+- **RGB:** All three of Red, Green and Blue in [0..1].
+- **HSL:** Hue in [0..360], Saturation and Luminance in [0..1]. For legacy reasons; please forget that it exists.
+- **HSV:** Hue in [0..360], Saturation and Value in [0..1]. You're better off using HCL, see below.
+- **Hex RGB:** The "internet" color format, as in #FF00FF.
+- **Linear RGB:** See [gamma correct rendering](http://www.sjbrown.co.uk/2004/05/14/gamma-correct-rendering/).
+- **CIE-XYZ:** CIE's standard color space, almost in [0..1].
+- **CIE-xyY:** encodes chromacity in x and y and luminance in Y, all in [0..1]
+- **CIE-L\*a\*b\*:** A *perceptually uniform* color space, i.e. distances are meaningful. L\* in [0..1] and a\*, b\* almost in [-1..1].
+- **CIE-L\*u\*v\*:** Very similar to CIE-L\*a\*b\*, there is [no consensus](http://en.wikipedia.org/wiki/CIELUV#Historical_background) on which one is "better".
+- **CIE-L\*C\*h° (HCL):** This is generally the [most useful](http://vis4.net/blog/posts/avoid-equidistant-hsv-colors/) one; CIE-L\*a\*b\* space in polar coordinates, i.e. a *better* HSV. H° is in [0..360], C\* almost in [-1..1] and L\* as in CIE-L\*a\*b\*.
+- **CIE LCh(uv):** Called `LuvLCh` in code, this is a cylindrical transformation of the CIE-L\*u\*v\* color space. Like HCL above: H° is in [0..360], C\* almost in [-1..1] and L\* as in CIE-L\*u\*v\*.
+- **HSLuv:** The better alternative to HSL, see [here](https://www.hsluv.org/) and [here](https://www.kuon.ch/post/2020-03-08-hsluv/). Hue in [0..360], Saturation and Luminance in [0..1].
+- **HPLuv:** A variant of HSLuv. The color space is smoother, but only pastel colors can be included. Because the valid colors are limited, it's easy to get invalid Saturation values way above 1.0, indicating the color can't be represented in HPLuv beccause it's not pastel.
+
+For the colorspaces where it makes sense (XYZ, Lab, Luv, HCl), the
+[D65](http://en.wikipedia.org/wiki/Illuminant_D65) is used as reference white
+by default but methods for using your own reference white are provided.
+
+A coordinate being *almost in* a range means that generally it is, but for very
+bright colors and depending on the reference white, it might overflow this
+range slightly. For example, C\* of #0000ff is 1.338.
+
+Unit-tests are provided.
+
+Nice, but what's it useful for?
+-------------------------------
+
+- Converting color spaces. Some people like to do that.
+- Blending (interpolating) between colors in a "natural" look by using the right colorspace.
+- Generating random colors under some constraints (e.g. colors of the same shade, or shades of one color.)
+- Generating gorgeous random palettes with distinct colors of a same temperature.
+
+What not (yet)?
+===============
+There are a few features which are currently missing and might be useful.
+I just haven't implemented them yet because I didn't have the need for it.
+Pull requests welcome.
+
+- Sorting colors (potentially using above mentioned distances)
+
+So which colorspace should I use?
+=================================
+It depends on what you want to do. I think the folks from *I want hue* are
+on-spot when they say that RGB fits to how *screens produce* color, CIE L\*a\*b\*
+fits how *humans perceive* color and HCL fits how *humans think* colors.
+
+Whenever you'd use HSV, rather go for CIE-L\*C\*h°. for fixed lightness L\* and
+chroma C\* values, the hue angle h° rotates through colors of the same
+perceived brightness and intensity.
+
+How?
+====
+
+### Installing
+Installing the library is as easy as
+
+```bash
+$ go get github.com/lucasb-eyer/go-colorful
+```
+
+The package can then be used through an
+
+```go
+import "github.com/lucasb-eyer/go-colorful"
+```
+
+### Basic usage
+
+Create a beautiful blue color using different source space:
+
+```go
+// Any of the following should be the same
+c := colorful.Color{0.313725, 0.478431, 0.721569}
+c, err := colorful.Hex("#517AB8")
+if err != nil {
+ log.Fatal(err)
+}
+c = colorful.Hsv(216.0, 0.56, 0.722)
+c = colorful.Xyz(0.189165, 0.190837, 0.480248)
+c = colorful.Xyy(0.219895, 0.221839, 0.190837)
+c = colorful.Lab(0.507850, 0.040585,-0.370945)
+c = colorful.Luv(0.507849,-0.194172,-0.567924)
+c = colorful.Hcl(276.2440, 0.373160, 0.507849)
+fmt.Printf("RGB values: %v, %v, %v", c.R, c.G, c.B)
+```
+
+And then converting this color back into various color spaces:
+
+```go
+hex := c.Hex()
+h, s, v := c.Hsv()
+x, y, z := c.Xyz()
+x, y, Y := c.Xyy()
+l, a, b := c.Lab()
+l, u, v := c.Luv()
+h, c, l := c.Hcl()
+```
+
+Note that, because of Go's unfortunate choice of requiring an initial uppercase,
+the name of the functions relating to the xyY space are just off. If you have
+any good suggestion, please open an issue. (I don't consider XyY good.)
+
+### The `color.Color` interface
+Because a `colorful.Color` implements Go's `color.Color` interface (found in the
+`image/color` package), it can be used anywhere that expects a `color.Color`.
+
+Furthermore, you can convert anything that implements the `color.Color` interface
+into a `colorful.Color` using the `MakeColor` function:
+
+```go
+c, ok := colorful.MakeColor(color.Gray16{12345})
+```
+
+**Caveat:** Be aware that this latter conversion (using `MakeColor`) hits a
+corner-case when alpha is exactly zero. Because `color.Color` uses pre-multiplied
+alpha colors, this means the RGB values are lost (set to 0) and it's impossible
+to recover them. In such a case `MakeColor` will return `false` as its second value.
+
+### Comparing colors
+In the RGB color space, the Euclidian distance between colors *doesn't* correspond
+to visual/perceptual distance. This means that two pairs of colors which have the
+same distance in RGB space can look much further apart. This is fixed by the
+CIE-L\*a\*b\*, CIE-L\*u\*v\* and CIE-L\*C\*h° color spaces.
+Thus you should only compare colors in any of these space.
+(Note that the distance in CIE-L\*a\*b\* and CIE-L\*C\*h° are the same, since it's the same space but in cylindrical coordinates)
+
+
+
+The two colors shown on the top look much more different than the two shown on
+the bottom. Still, in RGB space, their distance is the same.
+Here is a little example program which shows the distances between the top two
+and bottom two colors in RGB, CIE-L\*a\*b\* and CIE-L\*u\*v\* space. You can find it in `doc/colordist/colordist.go`.
+
+```go
+package main
+
+import "fmt"
+import "github.com/lucasb-eyer/go-colorful"
+
+func main() {
+ c1a := colorful.Color{150.0 / 255.0, 10.0 / 255.0, 150.0 / 255.0}
+ c1b := colorful.Color{53.0 / 255.0, 10.0 / 255.0, 150.0 / 255.0}
+ c2a := colorful.Color{10.0 / 255.0, 150.0 / 255.0, 50.0 / 255.0}
+ c2b := colorful.Color{99.9 / 255.0, 150.0 / 255.0, 10.0 / 255.0}
+
+ fmt.Printf("DistanceRgb: c1: %v\tand c2: %v\n", c1a.DistanceRgb(c1b), c2a.DistanceRgb(c2b))
+ fmt.Printf("DistanceLab: c1: %v\tand c2: %v\n", c1a.DistanceLab(c1b), c2a.DistanceLab(c2b))
+ fmt.Printf("DistanceLuv: c1: %v\tand c2: %v\n", c1a.DistanceLuv(c1b), c2a.DistanceLuv(c2b))
+ fmt.Printf("DistanceCIE76: c1: %v\tand c2: %v\n", c1a.DistanceCIE76(c1b), c2a.DistanceCIE76(c2b))
+ fmt.Printf("DistanceCIE94: c1: %v\tand c2: %v\n", c1a.DistanceCIE94(c1b), c2a.DistanceCIE94(c2b))
+ fmt.Printf("DistanceCIEDE2000: c1: %v\tand c2: %v\n", c1a.DistanceCIEDE2000(c1b), c2a.DistanceCIEDE2000(c2b))
+}
+```
+
+Running the above program shows that you should always prefer any of the CIE distances:
+
+```bash
+$ go run colordist.go
+DistanceRgb: c1: 0.3803921568627451 and c2: 0.3858713931171159
+DistanceLab: c1: 0.32048458312798056 and c2: 0.24397151758565272
+DistanceLuv: c1: 0.5134369614199698 and c2: 0.2568692839860636
+DistanceCIE76: c1: 0.32048458312798056 and c2: 0.24397151758565272
+DistanceCIE94: c1: 0.19799168128511324 and c2: 0.12207136371167401
+DistanceCIEDE2000: c1: 0.17274551120971166 and c2: 0.10665210031428465
+```
+
+It also shows that `DistanceLab` is more formally known as `DistanceCIE76` and
+has been superseded by the slightly more accurate, but much more expensive
+`DistanceCIE94` and `DistanceCIEDE2000`.
+
+Note that `AlmostEqualRgb` is provided mainly for (unit-)testing purposes. Use
+it only if you really know what you're doing. It will eat your cat.
+
+### Blending colors
+Blending is highly connected to distance, since it basically "walks through" the
+colorspace thus, if the colorspace maps distances well, the walk is "smooth".
+
+Colorful comes with blending functions in RGB, HSV and any of the LAB spaces.
+Of course, you'd rather want to use the blending functions of the LAB spaces since
+these spaces map distances well but, just in case, here is an example showing
+you how the blendings (`#fdffcc` to `#242a42`) are done in the various spaces:
+
+
+
+What you see is that HSV is really bad: it adds some green, which is not present
+in the original colors at all! RGB is much better, but it stays light a little
+too long. LUV and LAB both hit the right lightness but LAB has a little more
+color. HCL works in the same vein as HSV (both cylindrical interpolations) but
+it does it right in that there is no green appearing and the lighthness changes
+in a linear manner.
+
+While this seems all good, you need to know one thing: When interpolating in any
+of the CIE color spaces, you might get invalid RGB colors! This is important if
+the starting and ending colors are user-input or random. An example of where this
+happens is when blending between `#eeef61` and `#1e3140`:
+
+
+
+You can test whether a color is a valid RGB color by calling the `IsValid` method
+and indeed, calling IsValid will return false for the redish colors on the bottom.
+One way to "fix" this is to get a valid color close to the invalid one by calling
+`Clamped`, which always returns a nearby valid color. Doing this, we get the
+following result, which is satisfactory:
+
+
+
+The following is the code creating the above three images; it can be found in `doc/colorblend/colorblend.go`
+
+```go
+package main
+
+import "fmt"
+import "github.com/lucasb-eyer/go-colorful"
+import "image"
+import "image/draw"
+import "image/png"
+import "os"
+
+func main() {
+ blocks := 10
+ blockw := 40
+ img := image.NewRGBA(image.Rect(0,0,blocks*blockw,200))
+
+ c1, _ := colorful.Hex("#fdffcc")
+ c2, _ := colorful.Hex("#242a42")
+
+ // Use these colors to get invalid RGB in the gradient.
+ //c1, _ := colorful.Hex("#EEEF61")
+ //c2, _ := colorful.Hex("#1E3140")
+
+ for i := 0 ; i < blocks ; i++ {
+ draw.Draw(img, image.Rect(i*blockw, 0,(i+1)*blockw, 40), &image.Uniform{c1.BlendHsv(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
+ draw.Draw(img, image.Rect(i*blockw, 40,(i+1)*blockw, 80), &image.Uniform{c1.BlendLuv(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
+ draw.Draw(img, image.Rect(i*blockw, 80,(i+1)*blockw,120), &image.Uniform{c1.BlendRgb(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
+ draw.Draw(img, image.Rect(i*blockw,120,(i+1)*blockw,160), &image.Uniform{c1.BlendLab(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
+ draw.Draw(img, image.Rect(i*blockw,160,(i+1)*blockw,200), &image.Uniform{c1.BlendHcl(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
+
+ // This can be used to "fix" invalid colors in the gradient.
+ //draw.Draw(img, image.Rect(i*blockw,160,(i+1)*blockw,200), &image.Uniform{c1.BlendHcl(c2, float64(i)/float64(blocks-1)).Clamped()}, image.Point{}, draw.Src)
+ }
+
+ toimg, err := os.Create("colorblend.png")
+ if err != nil {
+ fmt.Printf("Error: %v", err)
+ return
+ }
+ defer toimg.Close()
+
+ png.Encode(toimg, img)
+}
+```
+
+#### Generating color gradients
+A very common reason to blend colors is creating gradients. There is an example
+program in [doc/gradientgen.go](doc/gradientgen/gradientgen.go); it doesn't use any API
+which hasn't been used in the previous example code, so I won't bother pasting
+the code in here. Just look at that gorgeous gradient it generated in HCL space:
+
+
+
+### Getting random colors
+It is sometimes necessary to generate random colors. You could simply do this
+on your own by generating colors with random values. By restricting the random
+values to a range smaller than [0..1] and using a space such as CIE-H\*C\*l° or
+HSV, you can generate both random shades of a color or random colors of a
+lightness:
+
+```go
+random_blue := colorful.Hcl(180.0+rand.Float64()*50.0, 0.2+rand.Float64()*0.8, 0.3+rand.Float64()*0.7)
+random_dark := colorful.Hcl(rand.Float64()*360.0, rand.Float64(), rand.Float64()*0.4)
+random_light := colorful.Hcl(rand.Float64()*360.0, rand.Float64(), 0.6+rand.Float64()*0.4)
+```
+
+Since getting random "warm" and "happy" colors is quite a common task, there
+are some helper functions:
+
+```go
+colorful.WarmColor()
+colorful.HappyColor()
+colorful.FastWarmColor()
+colorful.FastHappyColor()
+```
+
+The ones prefixed by `Fast` are faster but less coherent since they use the HSV
+space as opposed to the regular ones which use CIE-L\*C\*h° space. The
+following picture shows the warm colors in the top two rows and happy colors
+in the bottom two rows. Within these, the first is the regular one and the
+second is the fast one.
+
+
+
+Don't forget to initialize the random seed! You can see the code used for
+generating this picture in `doc/colorgens/colorgens.go`.
+
+### Getting random palettes
+As soon as you need to generate more than one random color, you probably want
+them to be distinguishible. Playing against an opponent which has almost the
+same blue as I do is not fun. This is where random palettes can help.
+
+These palettes are generated using an algorithm which ensures that all colors
+on the palette are as distinguishible as possible. Again, there is a `Fast`
+method which works in HSV and is less perceptually uniform and a non-`Fast`
+method which works in CIE spaces. For more theory on `SoftPalette`, check out
+[I want hue](http://tools.medialab.sciences-po.fr/iwanthue/theory.php). Yet
+again, there is a `Happy` and a `Warm` version, which do what you expect, but
+now there is an additional `Soft` version, which is more configurable: you can
+give a constraint on the color space in order to get colors within a certain *feel*.
+
+Let's start with the simple methods first, all they take is the amount of
+colors to generate, which could, for example, be the player count. They return
+an array of `colorful.Color` objects:
+
+```go
+pal1, err1 := colorful.WarmPalette(10)
+pal2 := colorful.FastWarmPalette(10)
+pal3, err3 := colorful.HappyPalette(10)
+pal4 := colorful.FastHappyPalette(10)
+pal5, err5 := colorful.SoftPalette(10)
+```
+
+Note that the non-fast methods *may* fail if you ask for way too many colors.
+Let's move on to the advanced one, namely `SoftPaletteEx`. Besides the color
+count, this function takes a `SoftPaletteSettings` object as argument. The
+interesting part here is its `CheckColor` member, which is a boolean function
+taking three floating points as arguments: `l`, `a` and `b`. This function
+should return `true` for colors which lie within the region you want and `false`
+otherwise. The other members are `Iteration`, which should be within [5..100]
+where higher means slower but more exact palette, and `ManySamples` which you
+should set to `true` in case your `CheckColor` constraint rejects a large part
+of the color space.
+
+For example, to create a palette of 10 brownish colors, you'd call it like this:
+
+```go
+func isbrowny(l, a, b float64) bool {
+ h, c, L := colorful.LabToHcl(l, a, b)
+ return 10.0 < h && h < 50.0 && 0.1 < c && c < 0.5 && L < 0.5
+}
+// Since the above function is pretty restrictive, we set ManySamples to true.
+brownies := colorful.SoftPaletteEx(10, colorful.SoftPaletteSettings{isbrowny, 50, true})
+```
+
+The following picture shows the palettes generated by all of these methods
+(sourcecode in `doc/palettegens/palettegens.go`), in the order they were presented, i.e.
+from top to bottom: `Warm`, `FastWarm`, `Happy`, `FastHappy`, `Soft`,
+`SoftEx(isbrowny)`. All of them contain some randomness, so YMMV.
+
+
+
+Again, the code used for generating the above image is available as [doc/palettegens/palettegens.go](https://github.com/lucasb-eyer/go-colorful/blob/master/doc/palettegens/palettegens.go).
+
+### Sorting colors
+TODO: Sort using dist fn.
+
+### Using linear RGB for computations
+There are two methods for transforming RGB<->Linear RGB: a fast and almost precise one,
+and a slow and precise one.
+
+```go
+r, g, b := colorful.Hex("#FF0000").FastLinearRgb()
+```
+
+TODO: describe some more.
+
+### Want to use some other reference point?
+
+```go
+c := colorful.LabWhiteRef(0.507850, 0.040585,-0.370945, colorful.D50)
+l, a, b := c.LabWhiteRef(colorful.D50)
+```
+
+### Reading and writing colors from databases
+
+The type `HexColor` makes it easy to store colors as strings in a database. It
+implements the [https://godoc.org/database/sql#Scanner](database/sql.Scanner)
+and [database/sql/driver.Value](https://godoc.org/database/sql/driver.Value)
+interfaces which provide automatic type conversion.
+
+Example:
+
+```go
+var hc HexColor
+_, err := db.QueryRow("SELECT '#ff0000';").Scan(&hc)
+// hc == HexColor{R: 1, G: 0, B: 0}; err == nil
+```
+
+FAQ
+===
+
+### Q: I get all f!@#ed up values! Your library sucks!
+A: You probably provided values in the wrong range. For example, RGB values are
+expected to reside between 0 and 1, *not* between 0 and 255. Normalize your colors.
+
+### Q: Lab/Luv/HCl seem broken! Your library sucks!
+They look like this:
+
+
+
+A: You're likely trying to generate and display colors that can't be represented by RGB,
+and thus monitors. When you're trying to convert, say, `HCL(190.0, 1.0, 1.0).RGB255()`,
+you're asking for RGB values of `(-2105.254 300.680 286.185)`, which clearly don't exist,
+and the `RGB255` function just casts these numbers to `uint8`, creating wrap-around and
+what looks like a completely broken gradient. What you want to do, is either use more
+reasonable values of colors which actually exist in RGB, or just `Clamp()` the resulting
+color to its nearest existing one, living with the consequences:
+`HCL(190.0, 1.0, 1.0).Clamp().RGB255()`. It will look something like this:
+
+
+
+[Here's an issue going in-depth about this](https://github.com/lucasb-eyer/go-colorful/issues/14),
+as well as [my answer](https://github.com/lucasb-eyer/go-colorful/issues/14#issuecomment-324205385),
+both with code and pretty pictures. Also note that this was somewhat covered above in the
+["Blending colors" section](https://github.com/lucasb-eyer/go-colorful#blending-colors).
+
+### Q: In a tight loop, conversion to Lab/Luv/HCl/... are slooooow!
+A: Yes, they are.
+This library aims for correctness, readability, and modularity; it wasn't written with speed in mind.
+A large part of the slowness comes from these conversions going through `LinearRgb` which uses powers.
+I implemented a fast approximation to `LinearRgb` called `FastLinearRgb` by using Taylor approximations.
+The approximation is roughly 5x faster and precise up to roughly 0.5%,
+the major caveat being that if the input values are outside the range 0-1, accuracy drops dramatically.
+You can use these in your conversions as follows:
+
+```go
+col := // Get your color somehow
+l, a, b := XyzToLab(LinearRgbToXyz(col.LinearRgb()))
+```
+
+If you need faster versions of `Distance*` and `Blend*` that make use of this fast approximation,
+feel free to implement them and open a pull-request, I'll happily accept.
+
+The derivation of these functions can be followed in [this Jupyter notebook](doc/LinearRGB Approximations.ipynb).
+Here's the main figure showing the approximation quality:
+
+
+
+More speed could be gained by using SIMD instructions in many places.
+You can also get more speed for specific conversions by approximating the full conversion function,
+but that is outside the scope of this library.
+Thanks to [@ZirconiumX](https://github.com/ZirconiumX) for starting this investigation,
+see [issue #18](https://github.com/lucasb-eyer/go-colorful/issues/18) for details.
+
+### Q: Why would `MakeColor` ever fail!?
+A: `MakeColor` fails when the alpha channel is zero. In that case, the
+conversion is undefined. See [issue 21](https://github.com/lucasb-eyer/go-colorful/issues/21)
+as well as the short caveat note in the ["The `color.Color` interface"](README.md#the-colorcolor-interface)
+section above.
+
+Who?
+====
+
+This library was developed by Lucas Beyer with contributions from
+Bastien Dejean (@baskerville), Phil Kulak (@pkulak) and Christian Muehlhaeuser (@muesli).
+
+It is now maintained by makeworld (@makeworld-the-better-one).
+
+
+## License
+
+This repo is under the MIT license, see [LICENSE](LICENSE) for details.
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/colorgens.go b/vendor/github.com/lucasb-eyer/go-colorful/colorgens.go
new file mode 100644
index 0000000..2e2e49e
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/colorgens.go
@@ -0,0 +1,55 @@
+// Various ways to generate single random colors
+
+package colorful
+
+import (
+ "math/rand"
+)
+
+// Creates a random dark, "warm" color through a restricted HSV space.
+func FastWarmColor() Color {
+ return Hsv(
+ rand.Float64()*360.0,
+ 0.5+rand.Float64()*0.3,
+ 0.3+rand.Float64()*0.3)
+}
+
+// Creates a random dark, "warm" color through restricted HCL space.
+// This is slower than FastWarmColor but will likely give you colors which have
+// the same "warmness" if you run it many times.
+func WarmColor() (c Color) {
+ for c = randomWarm(); !c.IsValid(); c = randomWarm() {
+ }
+ return
+}
+
+func randomWarm() Color {
+ return Hcl(
+ rand.Float64()*360.0,
+ 0.1+rand.Float64()*0.3,
+ 0.2+rand.Float64()*0.3)
+}
+
+// Creates a random bright, "pimpy" color through a restricted HSV space.
+func FastHappyColor() Color {
+ return Hsv(
+ rand.Float64()*360.0,
+ 0.7+rand.Float64()*0.3,
+ 0.6+rand.Float64()*0.3)
+}
+
+// Creates a random bright, "pimpy" color through restricted HCL space.
+// This is slower than FastHappyColor but will likely give you colors which
+// have the same "brightness" if you run it many times.
+func HappyColor() (c Color) {
+ for c = randomPimp(); !c.IsValid(); c = randomPimp() {
+ }
+ return
+}
+
+func randomPimp() Color {
+ return Hcl(
+ rand.Float64()*360.0,
+ 0.5+rand.Float64()*0.3,
+ 0.5+rand.Float64()*0.3)
+}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/colors.go b/vendor/github.com/lucasb-eyer/go-colorful/colors.go
new file mode 100644
index 0000000..0d5bffe
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/colors.go
@@ -0,0 +1,979 @@
+// The colorful package provides all kinds of functions for working with colors.
+package colorful
+
+import (
+ "fmt"
+ "image/color"
+ "math"
+)
+
+// A color is stored internally using sRGB (standard RGB) values in the range 0-1
+type Color struct {
+ R, G, B float64
+}
+
+// Implement the Go color.Color interface.
+func (col Color) RGBA() (r, g, b, a uint32) {
+ r = uint32(col.R*65535.0 + 0.5)
+ g = uint32(col.G*65535.0 + 0.5)
+ b = uint32(col.B*65535.0 + 0.5)
+ a = 0xFFFF
+ return
+}
+
+// Constructs a colorful.Color from something implementing color.Color
+func MakeColor(col color.Color) (Color, bool) {
+ r, g, b, a := col.RGBA()
+ if a == 0 {
+ return Color{0, 0, 0}, false
+ }
+
+ // Since color.Color is alpha pre-multiplied, we need to divide the
+ // RGB values by alpha again in order to get back the original RGB.
+ r *= 0xffff
+ r /= a
+ g *= 0xffff
+ g /= a
+ b *= 0xffff
+ b /= a
+
+ return Color{float64(r) / 65535.0, float64(g) / 65535.0, float64(b) / 65535.0}, true
+}
+
+// Might come in handy sometimes to reduce boilerplate code.
+func (col Color) RGB255() (r, g, b uint8) {
+ r = uint8(col.R*255.0 + 0.5)
+ g = uint8(col.G*255.0 + 0.5)
+ b = uint8(col.B*255.0 + 0.5)
+ return
+}
+
+// Used to simplify HSLuv testing.
+func (col Color) values() (float64, float64, float64) {
+ return col.R, col.G, col.B
+}
+
+// This is the tolerance used when comparing colors using AlmostEqualRgb.
+const Delta = 1.0 / 255.0
+
+// This is the default reference white point.
+var D65 = [3]float64{0.95047, 1.00000, 1.08883}
+
+// And another one.
+var D50 = [3]float64{0.96422, 1.00000, 0.82521}
+
+// Checks whether the color exists in RGB space, i.e. all values are in [0..1]
+func (c Color) IsValid() bool {
+ return 0.0 <= c.R && c.R <= 1.0 &&
+ 0.0 <= c.G && c.G <= 1.0 &&
+ 0.0 <= c.B && c.B <= 1.0
+}
+
+// clamp01 clamps from 0 to 1.
+func clamp01(v float64) float64 {
+ return math.Max(0.0, math.Min(v, 1.0))
+}
+
+// Returns Clamps the color into valid range, clamping each value to [0..1]
+// If the color is valid already, this is a no-op.
+func (c Color) Clamped() Color {
+ return Color{clamp01(c.R), clamp01(c.G), clamp01(c.B)}
+}
+
+func sq(v float64) float64 {
+ return v * v
+}
+
+func cub(v float64) float64 {
+ return v * v * v
+}
+
+// DistanceRgb computes the distance between two colors in RGB space.
+// This is not a good measure! Rather do it in Lab space.
+func (c1 Color) DistanceRgb(c2 Color) float64 {
+ return math.Sqrt(sq(c1.R-c2.R) + sq(c1.G-c2.G) + sq(c1.B-c2.B))
+}
+
+// DistanceLinearRGB computes the distance between two colors in linear RGB
+// space. This is not useful for measuring how humans perceive color, but
+// might be useful for other things, like dithering.
+func (c1 Color) DistanceLinearRGB(c2 Color) float64 {
+ r1, g1, b1 := c1.LinearRgb()
+ r2, g2, b2 := c2.LinearRgb()
+ return math.Sqrt(sq(r1-r2) + sq(g1-g2) + sq(b1-b2))
+}
+
+// Check for equality between colors within the tolerance Delta (1/255).
+func (c1 Color) AlmostEqualRgb(c2 Color) bool {
+ return math.Abs(c1.R-c2.R)+
+ math.Abs(c1.G-c2.G)+
+ math.Abs(c1.B-c2.B) < 3.0*Delta
+}
+
+// You don't really want to use this, do you? Go for BlendLab, BlendLuv or BlendHcl.
+func (c1 Color) BlendRgb(c2 Color, t float64) Color {
+ return Color{c1.R + t*(c2.R-c1.R),
+ c1.G + t*(c2.G-c1.G),
+ c1.B + t*(c2.B-c1.B)}
+}
+
+// Utility used by Hxx color-spaces for interpolating between two angles in [0,360].
+func interp_angle(a0, a1, t float64) float64 {
+ // Based on the answer here: http://stackoverflow.com/a/14498790/2366315
+ // With potential proof that it works here: http://math.stackexchange.com/a/2144499
+ delta := math.Mod(math.Mod(a1-a0, 360.0)+540, 360.0) - 180.0
+ return math.Mod(a0+t*delta+360.0, 360.0)
+}
+
+/// HSV ///
+///////////
+// From http://en.wikipedia.org/wiki/HSL_and_HSV
+// Note that h is in [0..360] and s,v in [0..1]
+
+// Hsv returns the Hue [0..360], Saturation and Value [0..1] of the color.
+func (col Color) Hsv() (h, s, v float64) {
+ min := math.Min(math.Min(col.R, col.G), col.B)
+ v = math.Max(math.Max(col.R, col.G), col.B)
+ C := v - min
+
+ s = 0.0
+ if v != 0.0 {
+ s = C / v
+ }
+
+ h = 0.0 // We use 0 instead of undefined as in wp.
+ if min != v {
+ if v == col.R {
+ h = math.Mod((col.G-col.B)/C, 6.0)
+ }
+ if v == col.G {
+ h = (col.B-col.R)/C + 2.0
+ }
+ if v == col.B {
+ h = (col.R-col.G)/C + 4.0
+ }
+ h *= 60.0
+ if h < 0.0 {
+ h += 360.0
+ }
+ }
+ return
+}
+
+// Hsv creates a new Color given a Hue in [0..360], a Saturation and a Value in [0..1]
+func Hsv(H, S, V float64) Color {
+ Hp := H / 60.0
+ C := V * S
+ X := C * (1.0 - math.Abs(math.Mod(Hp, 2.0)-1.0))
+
+ m := V - C
+ r, g, b := 0.0, 0.0, 0.0
+
+ switch {
+ case 0.0 <= Hp && Hp < 1.0:
+ r = C
+ g = X
+ case 1.0 <= Hp && Hp < 2.0:
+ r = X
+ g = C
+ case 2.0 <= Hp && Hp < 3.0:
+ g = C
+ b = X
+ case 3.0 <= Hp && Hp < 4.0:
+ g = X
+ b = C
+ case 4.0 <= Hp && Hp < 5.0:
+ r = X
+ b = C
+ case 5.0 <= Hp && Hp < 6.0:
+ r = C
+ b = X
+ }
+
+ return Color{m + r, m + g, m + b}
+}
+
+// You don't really want to use this, do you? Go for BlendLab, BlendLuv or BlendHcl.
+func (c1 Color) BlendHsv(c2 Color, t float64) Color {
+ h1, s1, v1 := c1.Hsv()
+ h2, s2, v2 := c2.Hsv()
+
+ // We know that h are both in [0..360]
+ return Hsv(interp_angle(h1, h2, t), s1+t*(s2-s1), v1+t*(v2-v1))
+}
+
+/// HSL ///
+///////////
+
+// Hsl returns the Hue [0..360], Saturation [0..1], and Luminance (lightness) [0..1] of the color.
+func (col Color) Hsl() (h, s, l float64) {
+ min := math.Min(math.Min(col.R, col.G), col.B)
+ max := math.Max(math.Max(col.R, col.G), col.B)
+
+ l = (max + min) / 2
+
+ if min == max {
+ s = 0
+ h = 0
+ } else {
+ if l < 0.5 {
+ s = (max - min) / (max + min)
+ } else {
+ s = (max - min) / (2.0 - max - min)
+ }
+
+ if max == col.R {
+ h = (col.G - col.B) / (max - min)
+ } else if max == col.G {
+ h = 2.0 + (col.B-col.R)/(max-min)
+ } else {
+ h = 4.0 + (col.R-col.G)/(max-min)
+ }
+
+ h *= 60
+
+ if h < 0 {
+ h += 360
+ }
+ }
+
+ return
+}
+
+// Hsl creates a new Color given a Hue in [0..360], a Saturation [0..1], and a Luminance (lightness) in [0..1]
+func Hsl(h, s, l float64) Color {
+ if s == 0 {
+ return Color{l, l, l}
+ }
+
+ var r, g, b float64
+ var t1 float64
+ var t2 float64
+ var tr float64
+ var tg float64
+ var tb float64
+
+ if l < 0.5 {
+ t1 = l * (1.0 + s)
+ } else {
+ t1 = l + s - l*s
+ }
+
+ t2 = 2*l - t1
+ h /= 360
+ tr = h + 1.0/3.0
+ tg = h
+ tb = h - 1.0/3.0
+
+ if tr < 0 {
+ tr++
+ }
+ if tr > 1 {
+ tr--
+ }
+ if tg < 0 {
+ tg++
+ }
+ if tg > 1 {
+ tg--
+ }
+ if tb < 0 {
+ tb++
+ }
+ if tb > 1 {
+ tb--
+ }
+
+ // Red
+ if 6*tr < 1 {
+ r = t2 + (t1-t2)*6*tr
+ } else if 2*tr < 1 {
+ r = t1
+ } else if 3*tr < 2 {
+ r = t2 + (t1-t2)*(2.0/3.0-tr)*6
+ } else {
+ r = t2
+ }
+
+ // Green
+ if 6*tg < 1 {
+ g = t2 + (t1-t2)*6*tg
+ } else if 2*tg < 1 {
+ g = t1
+ } else if 3*tg < 2 {
+ g = t2 + (t1-t2)*(2.0/3.0-tg)*6
+ } else {
+ g = t2
+ }
+
+ // Blue
+ if 6*tb < 1 {
+ b = t2 + (t1-t2)*6*tb
+ } else if 2*tb < 1 {
+ b = t1
+ } else if 3*tb < 2 {
+ b = t2 + (t1-t2)*(2.0/3.0-tb)*6
+ } else {
+ b = t2
+ }
+
+ return Color{r, g, b}
+}
+
+/// Hex ///
+///////////
+
+// Hex returns the hex "html" representation of the color, as in #ff0080.
+func (col Color) Hex() string {
+ // Add 0.5 for rounding
+ return fmt.Sprintf("#%02x%02x%02x", uint8(col.R*255.0+0.5), uint8(col.G*255.0+0.5), uint8(col.B*255.0+0.5))
+}
+
+// Hex parses a "html" hex color-string, either in the 3 "#f0c" or 6 "#ff1034" digits form.
+func Hex(scol string) (Color, error) {
+ format := "#%02x%02x%02x"
+ factor := 1.0 / 255.0
+ if len(scol) == 4 {
+ format = "#%1x%1x%1x"
+ factor = 1.0 / 15.0
+ }
+
+ var r, g, b uint8
+ n, err := fmt.Sscanf(scol, format, &r, &g, &b)
+ if err != nil {
+ return Color{}, err
+ }
+ if n != 3 {
+ return Color{}, fmt.Errorf("color: %v is not a hex-color", scol)
+ }
+
+ return Color{float64(r) * factor, float64(g) * factor, float64(b) * factor}, nil
+}
+
+/// Linear ///
+//////////////
+// http://www.sjbrown.co.uk/2004/05/14/gamma-correct-rendering/
+// http://www.brucelindbloom.com/Eqn_RGB_to_XYZ.html
+
+func linearize(v float64) float64 {
+ if v <= 0.04045 {
+ return v / 12.92
+ }
+ return math.Pow((v+0.055)/1.055, 2.4)
+}
+
+// LinearRgb converts the color into the linear RGB space (see http://www.sjbrown.co.uk/2004/05/14/gamma-correct-rendering/).
+func (col Color) LinearRgb() (r, g, b float64) {
+ r = linearize(col.R)
+ g = linearize(col.G)
+ b = linearize(col.B)
+ return
+}
+
+// A much faster and still quite precise linearization using a 6th-order Taylor approximation.
+// See the accompanying Jupyter notebook for derivation of the constants.
+func linearize_fast(v float64) float64 {
+ v1 := v - 0.5
+ v2 := v1 * v1
+ v3 := v2 * v1
+ v4 := v2 * v2
+ //v5 := v3*v2
+ return -0.248750514614486 + 0.925583310193438*v + 1.16740237321695*v2 + 0.280457026598666*v3 - 0.0757991963780179*v4 //+ 0.0437040411548932*v5
+}
+
+// FastLinearRgb is much faster than and almost as accurate as LinearRgb.
+// BUT it is important to NOTE that they only produce good results for valid colors r,g,b in [0,1].
+func (col Color) FastLinearRgb() (r, g, b float64) {
+ r = linearize_fast(col.R)
+ g = linearize_fast(col.G)
+ b = linearize_fast(col.B)
+ return
+}
+
+func delinearize(v float64) float64 {
+ if v <= 0.0031308 {
+ return 12.92 * v
+ }
+ return 1.055*math.Pow(v, 1.0/2.4) - 0.055
+}
+
+// LinearRgb creates an sRGB color out of the given linear RGB color (see http://www.sjbrown.co.uk/2004/05/14/gamma-correct-rendering/).
+func LinearRgb(r, g, b float64) Color {
+ return Color{delinearize(r), delinearize(g), delinearize(b)}
+}
+
+func delinearize_fast(v float64) float64 {
+ // This function (fractional root) is much harder to linearize, so we need to split.
+ if v > 0.2 {
+ v1 := v - 0.6
+ v2 := v1 * v1
+ v3 := v2 * v1
+ v4 := v2 * v2
+ v5 := v3 * v2
+ return 0.442430344268235 + 0.592178981271708*v - 0.287864782562636*v2 + 0.253214392068985*v3 - 0.272557158129811*v4 + 0.325554383321718*v5
+ } else if v > 0.03 {
+ v1 := v - 0.115
+ v2 := v1 * v1
+ v3 := v2 * v1
+ v4 := v2 * v2
+ v5 := v3 * v2
+ return 0.194915592891669 + 1.55227076330229*v - 3.93691860257828*v2 + 18.0679839248761*v3 - 101.468750302746*v4 + 632.341487393927*v5
+ } else {
+ v1 := v - 0.015
+ v2 := v1 * v1
+ v3 := v2 * v1
+ v4 := v2 * v2
+ v5 := v3 * v2
+ // You can clearly see from the involved constants that the low-end is highly nonlinear.
+ return 0.0519565234928877 + 5.09316778537561*v - 99.0338180489702*v2 + 3484.52322764895*v3 - 150028.083412663*v4 + 7168008.42971613*v5
+ }
+}
+
+// FastLinearRgb is much faster than and almost as accurate as LinearRgb.
+// BUT it is important to NOTE that they only produce good results for valid inputs r,g,b in [0,1].
+func FastLinearRgb(r, g, b float64) Color {
+ return Color{delinearize_fast(r), delinearize_fast(g), delinearize_fast(b)}
+}
+
+// XyzToLinearRgb converts from CIE XYZ-space to Linear RGB space.
+func XyzToLinearRgb(x, y, z float64) (r, g, b float64) {
+ r = 3.2409699419045214*x - 1.5373831775700935*y - 0.49861076029300328*z
+ g = -0.96924363628087983*x + 1.8759675015077207*y + 0.041555057407175613*z
+ b = 0.055630079696993609*x - 0.20397695888897657*y + 1.0569715142428786*z
+ return
+}
+
+func LinearRgbToXyz(r, g, b float64) (x, y, z float64) {
+ x = 0.41239079926595948*r + 0.35758433938387796*g + 0.18048078840183429*b
+ y = 0.21263900587151036*r + 0.71516867876775593*g + 0.072192315360733715*b
+ z = 0.019330818715591851*r + 0.11919477979462599*g + 0.95053215224966058*b
+ return
+}
+
+/// XYZ ///
+///////////
+// http://www.sjbrown.co.uk/2004/05/14/gamma-correct-rendering/
+
+func (col Color) Xyz() (x, y, z float64) {
+ return LinearRgbToXyz(col.LinearRgb())
+}
+
+func Xyz(x, y, z float64) Color {
+ return LinearRgb(XyzToLinearRgb(x, y, z))
+}
+
+/// xyY ///
+///////////
+// http://www.brucelindbloom.com/Eqn_XYZ_to_xyY.html
+
+// Well, the name is bad, since it's xyY but Golang needs me to start with a
+// capital letter to make the method public.
+func XyzToXyy(X, Y, Z float64) (x, y, Yout float64) {
+ return XyzToXyyWhiteRef(X, Y, Z, D65)
+}
+
+func XyzToXyyWhiteRef(X, Y, Z float64, wref [3]float64) (x, y, Yout float64) {
+ Yout = Y
+ N := X + Y + Z
+ if math.Abs(N) < 1e-14 {
+ // When we have black, Bruce Lindbloom recommends to use
+ // the reference white's chromacity for x and y.
+ x = wref[0] / (wref[0] + wref[1] + wref[2])
+ y = wref[1] / (wref[0] + wref[1] + wref[2])
+ } else {
+ x = X / N
+ y = Y / N
+ }
+ return
+}
+
+func XyyToXyz(x, y, Y float64) (X, Yout, Z float64) {
+ Yout = Y
+
+ if -1e-14 < y && y < 1e-14 {
+ X = 0.0
+ Z = 0.0
+ } else {
+ X = Y / y * x
+ Z = Y / y * (1.0 - x - y)
+ }
+
+ return
+}
+
+// Converts the given color to CIE xyY space using D65 as reference white.
+// (Note that the reference white is only used for black input.)
+// x, y and Y are in [0..1]
+func (col Color) Xyy() (x, y, Y float64) {
+ return XyzToXyy(col.Xyz())
+}
+
+// Converts the given color to CIE xyY space, taking into account
+// a given reference white. (i.e. the monitor's white)
+// (Note that the reference white is only used for black input.)
+// x, y and Y are in [0..1]
+func (col Color) XyyWhiteRef(wref [3]float64) (x, y, Y float64) {
+ X, Y2, Z := col.Xyz()
+ return XyzToXyyWhiteRef(X, Y2, Z, wref)
+}
+
+// Generates a color by using data given in CIE xyY space.
+// x, y and Y are in [0..1]
+func Xyy(x, y, Y float64) Color {
+ return Xyz(XyyToXyz(x, y, Y))
+}
+
+/// L*a*b* ///
+//////////////
+// http://en.wikipedia.org/wiki/Lab_color_space#CIELAB-CIEXYZ_conversions
+// For L*a*b*, we need to L*a*b*<->XYZ->RGB and the first one is device dependent.
+
+func lab_f(t float64) float64 {
+ if t > 6.0/29.0*6.0/29.0*6.0/29.0 {
+ return math.Cbrt(t)
+ }
+ return t/3.0*29.0/6.0*29.0/6.0 + 4.0/29.0
+}
+
+func XyzToLab(x, y, z float64) (l, a, b float64) {
+ // Use D65 white as reference point by default.
+ // http://www.fredmiranda.com/forum/topic/1035332
+ // http://en.wikipedia.org/wiki/Standard_illuminant
+ return XyzToLabWhiteRef(x, y, z, D65)
+}
+
+func XyzToLabWhiteRef(x, y, z float64, wref [3]float64) (l, a, b float64) {
+ fy := lab_f(y / wref[1])
+ l = 1.16*fy - 0.16
+ a = 5.0 * (lab_f(x/wref[0]) - fy)
+ b = 2.0 * (fy - lab_f(z/wref[2]))
+ return
+}
+
+func lab_finv(t float64) float64 {
+ if t > 6.0/29.0 {
+ return t * t * t
+ }
+ return 3.0 * 6.0 / 29.0 * 6.0 / 29.0 * (t - 4.0/29.0)
+}
+
+func LabToXyz(l, a, b float64) (x, y, z float64) {
+ // D65 white (see above).
+ return LabToXyzWhiteRef(l, a, b, D65)
+}
+
+func LabToXyzWhiteRef(l, a, b float64, wref [3]float64) (x, y, z float64) {
+ l2 := (l + 0.16) / 1.16
+ x = wref[0] * lab_finv(l2+a/5.0)
+ y = wref[1] * lab_finv(l2)
+ z = wref[2] * lab_finv(l2-b/2.0)
+ return
+}
+
+// Converts the given color to CIE L*a*b* space using D65 as reference white.
+func (col Color) Lab() (l, a, b float64) {
+ return XyzToLab(col.Xyz())
+}
+
+// Converts the given color to CIE L*a*b* space, taking into account
+// a given reference white. (i.e. the monitor's white)
+func (col Color) LabWhiteRef(wref [3]float64) (l, a, b float64) {
+ x, y, z := col.Xyz()
+ return XyzToLabWhiteRef(x, y, z, wref)
+}
+
+// Generates a color by using data given in CIE L*a*b* space using D65 as reference white.
+// WARNING: many combinations of `l`, `a`, and `b` values do not have corresponding
+// valid RGB values, check the FAQ in the README if you're unsure.
+func Lab(l, a, b float64) Color {
+ return Xyz(LabToXyz(l, a, b))
+}
+
+// Generates a color by using data given in CIE L*a*b* space, taking
+// into account a given reference white. (i.e. the monitor's white)
+func LabWhiteRef(l, a, b float64, wref [3]float64) Color {
+ return Xyz(LabToXyzWhiteRef(l, a, b, wref))
+}
+
+// DistanceLab is a good measure of visual similarity between two colors!
+// A result of 0 would mean identical colors, while a result of 1 or higher
+// means the colors differ a lot.
+func (c1 Color) DistanceLab(c2 Color) float64 {
+ l1, a1, b1 := c1.Lab()
+ l2, a2, b2 := c2.Lab()
+ return math.Sqrt(sq(l1-l2) + sq(a1-a2) + sq(b1-b2))
+}
+
+// DistanceCIE76 is the same as DistanceLab.
+func (c1 Color) DistanceCIE76(c2 Color) float64 {
+ return c1.DistanceLab(c2)
+}
+
+// Uses the CIE94 formula to calculate color distance. More accurate than
+// DistanceLab, but also more work.
+func (cl Color) DistanceCIE94(cr Color) float64 {
+ l1, a1, b1 := cl.Lab()
+ l2, a2, b2 := cr.Lab()
+
+ // NOTE: Since all those formulas expect L,a,b values 100x larger than we
+ // have them in this library, we either need to adjust all constants
+ // in the formula, or convert the ranges of L,a,b before, and then
+ // scale the distances down again. The latter is less error-prone.
+ l1, a1, b1 = l1*100.0, a1*100.0, b1*100.0
+ l2, a2, b2 = l2*100.0, a2*100.0, b2*100.0
+
+ kl := 1.0 // 2.0 for textiles
+ kc := 1.0
+ kh := 1.0
+ k1 := 0.045 // 0.048 for textiles
+ k2 := 0.015 // 0.014 for textiles.
+
+ deltaL := l1 - l2
+ c1 := math.Sqrt(sq(a1) + sq(b1))
+ c2 := math.Sqrt(sq(a2) + sq(b2))
+ deltaCab := c1 - c2
+
+ // Not taking Sqrt here for stability, and it's unnecessary.
+ deltaHab2 := sq(a1-a2) + sq(b1-b2) - sq(deltaCab)
+ sl := 1.0
+ sc := 1.0 + k1*c1
+ sh := 1.0 + k2*c1
+
+ vL2 := sq(deltaL / (kl * sl))
+ vC2 := sq(deltaCab / (kc * sc))
+ vH2 := deltaHab2 / sq(kh*sh)
+
+ return math.Sqrt(vL2+vC2+vH2) * 0.01 // See above.
+}
+
+// DistanceCIEDE2000 uses the Delta E 2000 formula to calculate color
+// distance. It is more expensive but more accurate than both DistanceLab
+// and DistanceCIE94.
+func (cl Color) DistanceCIEDE2000(cr Color) float64 {
+ return cl.DistanceCIEDE2000klch(cr, 1.0, 1.0, 1.0)
+}
+
+// DistanceCIEDE2000klch uses the Delta E 2000 formula with custom values
+// for the weighting factors kL, kC, and kH.
+func (cl Color) DistanceCIEDE2000klch(cr Color, kl, kc, kh float64) float64 {
+ l1, a1, b1 := cl.Lab()
+ l2, a2, b2 := cr.Lab()
+
+ // As with CIE94, we scale up the ranges of L,a,b beforehand and scale
+ // them down again afterwards.
+ l1, a1, b1 = l1*100.0, a1*100.0, b1*100.0
+ l2, a2, b2 = l2*100.0, a2*100.0, b2*100.0
+
+ cab1 := math.Sqrt(sq(a1) + sq(b1))
+ cab2 := math.Sqrt(sq(a2) + sq(b2))
+ cabmean := (cab1 + cab2) / 2
+
+ g := 0.5 * (1 - math.Sqrt(math.Pow(cabmean, 7)/(math.Pow(cabmean, 7)+math.Pow(25, 7))))
+ ap1 := (1 + g) * a1
+ ap2 := (1 + g) * a2
+ cp1 := math.Sqrt(sq(ap1) + sq(b1))
+ cp2 := math.Sqrt(sq(ap2) + sq(b2))
+
+ hp1 := 0.0
+ if b1 != ap1 || ap1 != 0 {
+ hp1 = math.Atan2(b1, ap1)
+ if hp1 < 0 {
+ hp1 += math.Pi * 2
+ }
+ hp1 *= 180 / math.Pi
+ }
+ hp2 := 0.0
+ if b2 != ap2 || ap2 != 0 {
+ hp2 = math.Atan2(b2, ap2)
+ if hp2 < 0 {
+ hp2 += math.Pi * 2
+ }
+ hp2 *= 180 / math.Pi
+ }
+
+ deltaLp := l2 - l1
+ deltaCp := cp2 - cp1
+ dhp := 0.0
+ cpProduct := cp1 * cp2
+ if cpProduct != 0 {
+ dhp = hp2 - hp1
+ if dhp > 180 {
+ dhp -= 360
+ } else if dhp < -180 {
+ dhp += 360
+ }
+ }
+ deltaHp := 2 * math.Sqrt(cpProduct) * math.Sin(dhp/2*math.Pi/180)
+
+ lpmean := (l1 + l2) / 2
+ cpmean := (cp1 + cp2) / 2
+ hpmean := hp1 + hp2
+ if cpProduct != 0 {
+ hpmean /= 2
+ if math.Abs(hp1-hp2) > 180 {
+ if hp1+hp2 < 360 {
+ hpmean += 180
+ } else {
+ hpmean -= 180
+ }
+ }
+ }
+
+ t := 1 - 0.17*math.Cos((hpmean-30)*math.Pi/180) + 0.24*math.Cos(2*hpmean*math.Pi/180) + 0.32*math.Cos((3*hpmean+6)*math.Pi/180) - 0.2*math.Cos((4*hpmean-63)*math.Pi/180)
+ deltaTheta := 30 * math.Exp(-sq((hpmean-275)/25))
+ rc := 2 * math.Sqrt(math.Pow(cpmean, 7)/(math.Pow(cpmean, 7)+math.Pow(25, 7)))
+ sl := 1 + (0.015*sq(lpmean-50))/math.Sqrt(20+sq(lpmean-50))
+ sc := 1 + 0.045*cpmean
+ sh := 1 + 0.015*cpmean*t
+ rt := -math.Sin(2*deltaTheta*math.Pi/180) * rc
+
+ return math.Sqrt(sq(deltaLp/(kl*sl))+sq(deltaCp/(kc*sc))+sq(deltaHp/(kh*sh))+rt*(deltaCp/(kc*sc))*(deltaHp/(kh*sh))) * 0.01
+}
+
+// BlendLab blends two colors in the L*a*b* color-space, which should result in a smoother blend.
+// t == 0 results in c1, t == 1 results in c2
+func (c1 Color) BlendLab(c2 Color, t float64) Color {
+ l1, a1, b1 := c1.Lab()
+ l2, a2, b2 := c2.Lab()
+ return Lab(l1+t*(l2-l1),
+ a1+t*(a2-a1),
+ b1+t*(b2-b1))
+}
+
+/// L*u*v* ///
+//////////////
+// http://en.wikipedia.org/wiki/CIELUV#XYZ_.E2.86.92_CIELUV_and_CIELUV_.E2.86.92_XYZ_conversions
+// For L*u*v*, we need to L*u*v*<->XYZ<->RGB and the first one is device dependent.
+
+func XyzToLuv(x, y, z float64) (l, a, b float64) {
+ // Use D65 white as reference point by default.
+ // http://www.fredmiranda.com/forum/topic/1035332
+ // http://en.wikipedia.org/wiki/Standard_illuminant
+ return XyzToLuvWhiteRef(x, y, z, D65)
+}
+
+func XyzToLuvWhiteRef(x, y, z float64, wref [3]float64) (l, u, v float64) {
+ if y/wref[1] <= 6.0/29.0*6.0/29.0*6.0/29.0 {
+ l = y / wref[1] * (29.0 / 3.0 * 29.0 / 3.0 * 29.0 / 3.0) / 100.0
+ } else {
+ l = 1.16*math.Cbrt(y/wref[1]) - 0.16
+ }
+ ubis, vbis := xyz_to_uv(x, y, z)
+ un, vn := xyz_to_uv(wref[0], wref[1], wref[2])
+ u = 13.0 * l * (ubis - un)
+ v = 13.0 * l * (vbis - vn)
+ return
+}
+
+// For this part, we do as R's graphics.hcl does, not as wikipedia does.
+// Or is it the same?
+func xyz_to_uv(x, y, z float64) (u, v float64) {
+ denom := x + 15.0*y + 3.0*z
+ if denom == 0.0 {
+ u, v = 0.0, 0.0
+ } else {
+ u = 4.0 * x / denom
+ v = 9.0 * y / denom
+ }
+ return
+}
+
+func LuvToXyz(l, u, v float64) (x, y, z float64) {
+ // D65 white (see above).
+ return LuvToXyzWhiteRef(l, u, v, D65)
+}
+
+func LuvToXyzWhiteRef(l, u, v float64, wref [3]float64) (x, y, z float64) {
+ //y = wref[1] * lab_finv((l + 0.16) / 1.16)
+ if l <= 0.08 {
+ y = wref[1] * l * 100.0 * 3.0 / 29.0 * 3.0 / 29.0 * 3.0 / 29.0
+ } else {
+ y = wref[1] * cub((l+0.16)/1.16)
+ }
+ un, vn := xyz_to_uv(wref[0], wref[1], wref[2])
+ if l != 0.0 {
+ ubis := u/(13.0*l) + un
+ vbis := v/(13.0*l) + vn
+ x = y * 9.0 * ubis / (4.0 * vbis)
+ z = y * (12.0 - 3.0*ubis - 20.0*vbis) / (4.0 * vbis)
+ } else {
+ x, y = 0.0, 0.0
+ }
+ return
+}
+
+// Converts the given color to CIE L*u*v* space using D65 as reference white.
+// L* is in [0..1] and both u* and v* are in about [-1..1]
+func (col Color) Luv() (l, u, v float64) {
+ return XyzToLuv(col.Xyz())
+}
+
+// Converts the given color to CIE L*u*v* space, taking into account
+// a given reference white. (i.e. the monitor's white)
+// L* is in [0..1] and both u* and v* are in about [-1..1]
+func (col Color) LuvWhiteRef(wref [3]float64) (l, u, v float64) {
+ x, y, z := col.Xyz()
+ return XyzToLuvWhiteRef(x, y, z, wref)
+}
+
+// Generates a color by using data given in CIE L*u*v* space using D65 as reference white.
+// L* is in [0..1] and both u* and v* are in about [-1..1]
+// WARNING: many combinations of `l`, `u`, and `v` values do not have corresponding
+// valid RGB values, check the FAQ in the README if you're unsure.
+func Luv(l, u, v float64) Color {
+ return Xyz(LuvToXyz(l, u, v))
+}
+
+// Generates a color by using data given in CIE L*u*v* space, taking
+// into account a given reference white. (i.e. the monitor's white)
+// L* is in [0..1] and both u* and v* are in about [-1..1]
+func LuvWhiteRef(l, u, v float64, wref [3]float64) Color {
+ return Xyz(LuvToXyzWhiteRef(l, u, v, wref))
+}
+
+// DistanceLuv is a good measure of visual similarity between two colors!
+// A result of 0 would mean identical colors, while a result of 1 or higher
+// means the colors differ a lot.
+func (c1 Color) DistanceLuv(c2 Color) float64 {
+ l1, u1, v1 := c1.Luv()
+ l2, u2, v2 := c2.Luv()
+ return math.Sqrt(sq(l1-l2) + sq(u1-u2) + sq(v1-v2))
+}
+
+// BlendLuv blends two colors in the CIE-L*u*v* color-space, which should result in a smoother blend.
+// t == 0 results in c1, t == 1 results in c2
+func (c1 Color) BlendLuv(c2 Color, t float64) Color {
+ l1, u1, v1 := c1.Luv()
+ l2, u2, v2 := c2.Luv()
+ return Luv(l1+t*(l2-l1),
+ u1+t*(u2-u1),
+ v1+t*(v2-v1))
+}
+
+/// HCL ///
+///////////
+// HCL is nothing else than L*a*b* in cylindrical coordinates!
+// (this was wrong on English wikipedia, I fixed it, let's hope the fix stays.)
+// But it is widely popular since it is a "correct HSV"
+// http://www.hunterlab.com/appnotes/an09_96a.pdf
+
+// Converts the given color to HCL space using D65 as reference white.
+// H values are in [0..360], C and L values are in [0..1] although C can overshoot 1.0
+func (col Color) Hcl() (h, c, l float64) {
+ return col.HclWhiteRef(D65)
+}
+
+func LabToHcl(L, a, b float64) (h, c, l float64) {
+ // Oops, floating point workaround necessary if a ~= b and both are very small (i.e. almost zero).
+ if math.Abs(b-a) > 1e-4 && math.Abs(a) > 1e-4 {
+ h = math.Mod(57.29577951308232087721*math.Atan2(b, a)+360.0, 360.0) // Rad2Deg
+ } else {
+ h = 0.0
+ }
+ c = math.Sqrt(sq(a) + sq(b))
+ l = L
+ return
+}
+
+// Converts the given color to HCL space, taking into account
+// a given reference white. (i.e. the monitor's white)
+// H values are in [0..360], C and L values are in [0..1]
+func (col Color) HclWhiteRef(wref [3]float64) (h, c, l float64) {
+ L, a, b := col.LabWhiteRef(wref)
+ return LabToHcl(L, a, b)
+}
+
+// Generates a color by using data given in HCL space using D65 as reference white.
+// H values are in [0..360], C and L values are in [0..1]
+// WARNING: many combinations of `h`, `c`, and `l` values do not have corresponding
+// valid RGB values, check the FAQ in the README if you're unsure.
+func Hcl(h, c, l float64) Color {
+ return HclWhiteRef(h, c, l, D65)
+}
+
+func HclToLab(h, c, l float64) (L, a, b float64) {
+ H := 0.01745329251994329576 * h // Deg2Rad
+ a = c * math.Cos(H)
+ b = c * math.Sin(H)
+ L = l
+ return
+}
+
+// Generates a color by using data given in HCL space, taking
+// into account a given reference white. (i.e. the monitor's white)
+// H values are in [0..360], C and L values are in [0..1]
+func HclWhiteRef(h, c, l float64, wref [3]float64) Color {
+ L, a, b := HclToLab(h, c, l)
+ return LabWhiteRef(L, a, b, wref)
+}
+
+// BlendHcl blends two colors in the CIE-L*C*h° color-space, which should result in a smoother blend.
+// t == 0 results in c1, t == 1 results in c2
+func (col1 Color) BlendHcl(col2 Color, t float64) Color {
+ h1, c1, l1 := col1.Hcl()
+ h2, c2, l2 := col2.Hcl()
+
+ // We know that h are both in [0..360]
+ return Hcl(interp_angle(h1, h2, t), c1+t*(c2-c1), l1+t*(l2-l1)).Clamped()
+}
+
+// LuvLch
+
+// Converts the given color to LuvLCh space using D65 as reference white.
+// h values are in [0..360], C and L values are in [0..1] although C can overshoot 1.0
+func (col Color) LuvLCh() (l, c, h float64) {
+ return col.LuvLChWhiteRef(D65)
+}
+
+func LuvToLuvLCh(L, u, v float64) (l, c, h float64) {
+ // Oops, floating point workaround necessary if u ~= v and both are very small (i.e. almost zero).
+ if math.Abs(v-u) > 1e-4 && math.Abs(u) > 1e-4 {
+ h = math.Mod(57.29577951308232087721*math.Atan2(v, u)+360.0, 360.0) // Rad2Deg
+ } else {
+ h = 0.0
+ }
+ l = L
+ c = math.Sqrt(sq(u) + sq(v))
+ return
+}
+
+// Converts the given color to LuvLCh space, taking into account
+// a given reference white. (i.e. the monitor's white)
+// h values are in [0..360], c and l values are in [0..1]
+func (col Color) LuvLChWhiteRef(wref [3]float64) (l, c, h float64) {
+ return LuvToLuvLCh(col.LuvWhiteRef(wref))
+}
+
+// Generates a color by using data given in LuvLCh space using D65 as reference white.
+// h values are in [0..360], C and L values are in [0..1]
+// WARNING: many combinations of `l`, `c`, and `h` values do not have corresponding
+// valid RGB values, check the FAQ in the README if you're unsure.
+func LuvLCh(l, c, h float64) Color {
+ return LuvLChWhiteRef(l, c, h, D65)
+}
+
+func LuvLChToLuv(l, c, h float64) (L, u, v float64) {
+ H := 0.01745329251994329576 * h // Deg2Rad
+ u = c * math.Cos(H)
+ v = c * math.Sin(H)
+ L = l
+ return
+}
+
+// Generates a color by using data given in LuvLCh space, taking
+// into account a given reference white. (i.e. the monitor's white)
+// h values are in [0..360], C and L values are in [0..1]
+func LuvLChWhiteRef(l, c, h float64, wref [3]float64) Color {
+ L, u, v := LuvLChToLuv(l, c, h)
+ return LuvWhiteRef(L, u, v, wref)
+}
+
+// BlendLuvLCh blends two colors in the cylindrical CIELUV color space.
+// t == 0 results in c1, t == 1 results in c2
+func (col1 Color) BlendLuvLCh(col2 Color, t float64) Color {
+ l1, c1, h1 := col1.LuvLCh()
+ l2, c2, h2 := col2.LuvLCh()
+
+ // We know that h are both in [0..360]
+ return LuvLCh(l1+t*(l2-l1), c1+t*(c2-c1), interp_angle(h1, h2, t))
+}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/happy_palettegen.go b/vendor/github.com/lucasb-eyer/go-colorful/happy_palettegen.go
new file mode 100644
index 0000000..bb66dfa
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/happy_palettegen.go
@@ -0,0 +1,25 @@
+package colorful
+
+import (
+ "math/rand"
+)
+
+// Uses the HSV color space to generate colors with similar S,V but distributed
+// evenly along their Hue. This is fast but not always pretty.
+// If you've got time to spare, use Lab (the non-fast below).
+func FastHappyPalette(colorsCount int) (colors []Color) {
+ colors = make([]Color, colorsCount)
+
+ for i := 0; i < colorsCount; i++ {
+ colors[i] = Hsv(float64(i)*(360.0/float64(colorsCount)), 0.8+rand.Float64()*0.2, 0.65+rand.Float64()*0.2)
+ }
+ return
+}
+
+func HappyPalette(colorsCount int) ([]Color, error) {
+ pimpy := func(l, a, b float64) bool {
+ _, c, _ := LabToHcl(l, a, b)
+ return 0.3 <= c && 0.4 <= l && l <= 0.8
+ }
+ return SoftPaletteEx(colorsCount, SoftPaletteSettings{pimpy, 50, true})
+}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/hexcolor.go b/vendor/github.com/lucasb-eyer/go-colorful/hexcolor.go
new file mode 100644
index 0000000..76f31d8
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/hexcolor.go
@@ -0,0 +1,67 @@
+package colorful
+
+import (
+ "database/sql/driver"
+ "encoding/json"
+ "fmt"
+ "reflect"
+)
+
+// A HexColor is a Color stored as a hex string "#rrggbb". It implements the
+// database/sql.Scanner, database/sql/driver.Value,
+// encoding/json.Unmarshaler and encoding/json.Marshaler interfaces.
+type HexColor Color
+
+type errUnsupportedType struct {
+ got interface{}
+ want reflect.Type
+}
+
+func (hc *HexColor) Scan(value interface{}) error {
+ s, ok := value.(string)
+ if !ok {
+ return errUnsupportedType{got: reflect.TypeOf(value), want: reflect.TypeOf("")}
+ }
+ c, err := Hex(s)
+ if err != nil {
+ return err
+ }
+ *hc = HexColor(c)
+ return nil
+}
+
+func (hc *HexColor) Value() (driver.Value, error) {
+ return Color(*hc).Hex(), nil
+}
+
+func (e errUnsupportedType) Error() string {
+ return fmt.Sprintf("unsupported type: got %v, want a %s", e.got, e.want)
+}
+
+func (hc *HexColor) UnmarshalJSON(data []byte) error {
+ var hexCode string
+ if err := json.Unmarshal(data, &hexCode); err != nil {
+ return err
+ }
+
+ var col, err = Hex(hexCode)
+ if err != nil {
+ return err
+ }
+ *hc = HexColor(col)
+ return nil
+}
+
+func (hc HexColor) MarshalJSON() ([]byte, error) {
+ return json.Marshal(Color(hc).Hex())
+}
+
+// Decode - deserialize function for https://github.com/kelseyhightower/envconfig
+func (hc *HexColor) Decode(hexCode string) error {
+ var col, err = Hex(hexCode)
+ if err != nil {
+ return err
+ }
+ *hc = HexColor(col)
+ return nil
+}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/hsluv-snapshot-rev4.json b/vendor/github.com/lucasb-eyer/go-colorful/hsluv-snapshot-rev4.json
new file mode 100644
index 0000000..16354ab
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/hsluv-snapshot-rev4.json
@@ -0,0 +1 @@
+{"#11ee00":{"lch":[82.5213119008325577,127.202882727266427,127.478988192005161],"luv":[82.5213119008325577,-77.3991947082883627,100.945222931227221],"rgb":[0.0666666666666666657,0.933333333333333348,0],"xyz":[0.308043578886299796,0.612655858810891907,0.102019012460713238],"hpluv":[127.478988192005161,308.195222762673438,82.5213119008325577],"hsluv":[127.478988192005161,100.000000000002416,82.5213119008325577]},"#11ee11":{"lch":[82.5429986110943759,126.352581314528209,127.715012949240403],"luv":[82.5429986110943759,-77.2942129186682,99.9528861720763473],"rgb":[0.0666666666666666657,0.933333333333333348,0.0666666666666666657],"xyz":[0.3090552443859369,0.613060525010746815,0.107347117425468874],"hpluv":[127.715012949240403,306.573296560288782,82.5429986110943759],"hsluv":[127.715012949240403,98.9038130800949205,82.5429986110943759]},"#11ee22":{"lch":[82.5831747617793184,124.791738379333623,128.158354445562821],"luv":[82.5831747617793184,-77.1009570540098,98.1245147202868253],"rgb":[0.0666666666666666657,0.933333333333333348,0.133333333333333331],"xyz":[0.310930602524413957,0.613810668266137616,0.117224003621448067],"hpluv":[128.158354445562821,303.59085997924285,82.5831747617793184],"hsluv":[128.158354445562821,98.9085620232469864,82.5831747617793184]},"#11ee33":{"lch":[82.6492529720821381,122.265269823008623,128.905098358231896],"luv":[82.6492529720821381,-76.7865393115689301,95.1452762119380537],"rgb":[0.0666666666666666657,0.933333333333333348,0.2],"xyz":[0.314018353256871663,0.615045768559120742,0.133486157479059203],"hpluv":[128.905098358231896,298.749143147736106,82.6492529720821381],"hsluv":[128.905098358231896,98.916292078887,82.6492529720821381]},"#11ee44":{"lch":[82.7444986901015511,118.712635154498344,130.021230388522838],"luv":[82.7444986901015511,-76.3407023620842,90.9108734321077],"rgb":[0.0666666666666666657,0.933333333333333348,0.266666666666666663],"xyz":[0.318476348501090578,0.616828966656808308,0.156964932431945842],"hpluv":[130.021230388522838,291.911386756693616,82.7444986901015511],"hsluv":[130.021230388522838,98.9272612770947148,82.7444986901015511]},"#11ee55":{"lch":[82.8716000285422894,114.135934527262179,131.587310643629934],"luv":[82.8716000285422894,-75.758934185545,85.3674144008224],"rgb":[0.0666666666666666657,0.933333333333333348,0.333333333333333315],"xyz":[0.324438762540452563,0.619213932272553058,0.188366979705919757],"hpluv":[131.587310643629934,283.052591495130912,82.8716000285422894],"hsluv":[131.587310643629934,98.941589727101146,82.8716000285422894]},"#11ee66":{"lch":[83.0328193013522622,108.602333046050703,133.707640253052432],"luv":[83.0328193013522622,-75.0419109433949103,78.5059128028513697],"rgb":[0.0666666666666666657,0.933333333333333348,0.4],"xyz":[0.332023758313960748,0.622247930581956377,0.228314624113063719],"hpluv":[133.707640253052432,272.269449526145593,83.0328193013522622],"hsluv":[133.707640253052432,98.9592735060659,83.0328193013522622]},"#11ee77":{"lch":[83.2300736177455747,102.250357200027821,136.520544097163679],"luv":[83.2300736177455747,-74.1950209885278866,70.3579022430685228],"rgb":[0.0666666666666666657,0.933333333333333348,0.466666666666666674],"xyz":[0.341337771334162654,0.625973535790037228,0.277368426019461656],"hpluv":[136.520544097163679,259.803949175129901,83.2300736177455747],"hsluv":[136.520544097163679,98.9801962733070155,83.2300736177455747]},"#11ee88":{"lch":[83.4649827070576151,95.3003261118453651,140.209511574476238],"luv":[83.4649827070576151,-73.2277962837693082,60.990507527375577],"rgb":[0.0666666666666666657,0.933333333333333348,0.533333333333333326],"xyz":[0.352478188436106454,0.63042970263081477,0.336041289423033795],"hpluv":[140.209511574476238,246.084644167270028,83.4649827070576151],"hsluv":[140.209511574476238,99.0041428894333109,83.4649827070576151]},"#11ee99":{"lch":[83.7388997377875626,88.07037792773761,145.011549795441141],"luv":[83.7388997377875626,-72.1532115864445416,50.5005497603372433],"rgb":[0.0666666666666666657,0.933333333333333348,0.6],"xyz":[0.365535152545179209,0.635652488274444,0.404807967064151675],"hpluv":[145.011549795441141,231.793725377578141,83.7388997377875626],"hsluv":[145.011549795441141,99.0308160530368582,83.7388997377875626]},"#11eeaa":{"lch":[84.0529327571252907,80.9984265129003802,151.210882439188083],"luv":[84.0529327571252907,-70.9868724309634729,39.0078074241021824],"rgb":[0.0666666666666666657,0.933333333333333348,0.66666666666666663],"xyz":[0.38059284551043171,0.641675565460545,0.484111816681150331],"hpluv":[151.210882439188083,217.967504021816438,84.0529327571252907],"hsluv":[151.210882439188083,99.0598554997167895,84.0529327571252907]},"#11eebb":{"lch":[84.4079608499599914,74.6634505604909435,159.089705667287262],"luv":[84.4079608499599914,-69.7461428935043273,26.6478216947980826],"rgb":[0.0666666666666666657,0.933333333333333348,0.733333333333333282],"xyz":[0.397730437617768384,0.648530602303479808,0.574369801779792],"hpluv":[159.089705667287262,206.122134265545043,84.4079608499599914],"hsluv":[159.089705667287262,99.0908585861444209,84.4079608499599914]},"#11eecc":{"lch":[84.8046473826435,69.7804076798411,168.790807110150524],"luv":[84.8046473826435,-68.449275126866155,13.5647348138992196],"rgb":[0.0666666666666666657,0.933333333333333348,0.8],"xyz":[0.417022813061490139,0.656247552480968666,0.675976312450062178],"hpluv":[168.790807110150524,198.342538571842852,84.8046473826435],"hsluv":[168.790807110150524,99.123400814408285,84.8046473826435]},"#11eedd":{"lch":[85.2434517572140749,67.1146678094459,180.081412911690762],"luv":[85.2434517572140749,-67.114600056421537,-0.0953647673755886743],"rgb":[0.0666666666666666657,0.933333333333333348,0.866666666666666696],"xyz":[0.438541138612123627,0.664854882701222172,0.789306160350068176],"hpluv":[180.081412911690762,197.173954094180345,85.2434517572140749],"hsluv":[180.081412911690762,99.1570549081779546,85.2434517572140749]},"#11eeee":{"lch":[85.7246405502341275,67.2734484234975,192.17705063006116],"luv":[85.7246405502341275,-65.759826803247222,-14.1902093570146306],"rgb":[0.0666666666666666657,0.933333333333333348,0.933333333333333348],"xyz":[0.462353318878298392,0.674379754807692189,0.914716976418591399],"hpluv":[192.17705063006116,205.138082793863816,85.7246405502341275],"hsluv":[192.17705063006116,99.1914073274009098,85.7246405502341275]},"#11eeff":{"lch":[86.2482985645723517,70.4606934075819282,203.935071880927921],"luv":[86.2482985645723517,-64.401481656171029,-28.585983907627277],"rgb":[0.0666666666666666657,0.933333333333333348,1],"xyz":[0.488524367288129757,0.684848174171624913,1.05255116471037335],"hpluv":[203.935071880927921,224.026806300523,86.2482985645723517],"hsluv":[203.935071880927921,99.9999999999942304,86.2482985645723517]},"#11ff00":{"lch":[87.7931168603164,135.408535196841626,127.513270797457935],"luv":[87.7931168603164,-82.4563732780469,107.407718111808407],"rgb":[0.0666666666666666657,1,0],"xyz":[0.359895951315973628,0.716360603670241,0.119303136603937349],"hpluv":[127.513270797457935,491.310985978769054,87.7931168603164],"hsluv":[127.513270797457935,100.000000000002373,87.7931168603164]},"#11ff11":{"lch":[87.8126571401035108,134.634318462908169,127.715012949240432],"luv":[87.8126571401035108,-82.3604359259359313,106.50426424355777],"rgb":[0.0666666666666666657,1,0.0666666666666666657],"xyz":[0.360907616815610732,0.716765269870095922,0.124631241568692985],"hpluv":[127.715012949240432,489.364334505449051,87.8126571401035108],"hsluv":[127.715012949240432,99.999999999991914,87.8126571401035108]},"#11ff22":{"lch":[87.848860165327963,133.211117719966126,128.093229681784152],"luv":[87.848860165327963,-82.1836510367646,104.838205757586152],"rgb":[0.0666666666666666657,1,0.133333333333333331],"xyz":[0.362782974954087789,0.717515413125486723,0.134508127764672164],"hpluv":[128.093229681784152,485.7796458877379,87.848860165327963],"hsluv":[128.093229681784152,99.9999999999918572,87.848860165327963]},"#11ff33":{"lch":[87.9084130007832698,130.901693692038833,128.728166832562891],"luv":[87.9084130007832698,-81.8955348861488659,102.119414300885666],"rgb":[0.0666666666666666657,1,0.2],"xyz":[0.365870725686545495,0.71875051341846985,0.150770281622283314],"hpluv":[128.728166832562891,479.945632467831388,87.9084130007832698],"hsluv":[128.728166832562891,99.9999999999919567,87.9084130007832698]},"#11ff44":{"lch":[87.9942732352876,127.641489512823171,129.672386074694657],"luv":[87.9942732352876,-81.4859348177847806,98.2465891108891185],"rgb":[0.0666666666666666657,1,0.266666666666666663],"xyz":[0.37032872093076441,0.720533711516157416,0.174249056575169953],"hpluv":[129.672386074694657,471.674193406224788,87.9942732352876],"hsluv":[129.672386074694657,99.9999999999918856,87.9942732352876]},"#11ff55":{"lch":[88.1088871723243727,123.41738800901625,130.987994113812931],"luv":[88.1088871723243727,-80.9495722978130772,93.1612494966077662],"rgb":[0.0666666666666666657,1,0.333333333333333315],"xyz":[0.376291134970126395,0.722918677131902165,0.205651103849143868],"hpluv":[130.987994113812931,460.897243009671797,88.1088871723243727],"hsluv":[130.987994113812931,99.9999999999917,88.1088871723243727]},"#11ff66":{"lch":[88.2543278429396,118.268592142924746,132.753132104158254],"luv":[88.2543278429396,-80.2855559529031382,86.8429006471038],"rgb":[0.0666666666666666657,1,0.4],"xyz":[0.38387613074363458,0.725952675441305484,0.24559874825628783],"hpluv":[132.753132104158254,447.675525940365219,88.2543278429396],"hsluv":[132.753132104158254,99.9999999999916724,88.2543278429396]},"#11ff77":{"lch":[88.4323687925046613,112.290518027227137,135.069051083024959],"luv":[88.4323687925046613,-79.4970211443964558,79.3056370505300521],"rgb":[0.0666666666666666657,1,0.466666666666666674],"xyz":[0.393190143763836486,0.729678280649386335,0.294652550162685767],"hpluv":[135.069051083024959,432.222948715922314,88.4323687925046613],"hsluv":[135.069051083024959,99.999999999991644,88.4323687925046613]},"#11ff88":{"lch":[88.6445280109338825,105.641380676940045,138.068036362648229],"luv":[88.6445280109338825,-78.5907289650887577,70.5946076698930369],"rgb":[0.0666666666666666657,1,0.533333333333333326],"xyz":[0.404330560865780286,0.734134447490163877,0.353325413566257907],"hpluv":[138.068036362648229,414.95023459347243,88.6445280109338825],"hsluv":[138.068036362648229,99.9999999999915,88.6445280109338825]},"#11ff99":{"lch":[88.8920961876840465,98.552301258979881,141.921030988541872],"luv":[88.8920961876840465,-77.5765731609304225,60.7818342932124338],"rgb":[0.0666666666666666657,1,0.6],"xyz":[0.417387524974853,0.73935723313379309,0.422092091207375786],"hpluv":[141.921030988541872,396.537381185702543,88.8920961876840465],"hsluv":[141.921030988541872,99.9999999999913456,88.8920961876840465]},"#11ffaa":{"lch":[89.1761561490339147,91.3418654410923523,146.840553381528281],"luv":[89.1761561490339147,-76.4669946123218,49.9613362233014158],"rgb":[0.0666666666666666657,1,0.66666666666666663],"xyz":[0.432445217940105542,0.745380310319894157,0.501395940824374442],"hpluv":[146.840553381528281,378.048392077141443,89.1761561490339147],"hsluv":[146.840553381528281,99.9999999999913,89.1761561490339147]},"#11ffbb":{"lch":[89.4975971674113,84.4340589142561413,153.067388238784645],"luv":[89.4975971674113,-75.2763296710648859,38.2437510711127],"rgb":[0.0666666666666666657,1,0.733333333333333282],"xyz":[0.449582810047442216,0.752235347162828916,0.591653925923016133],"hpluv":[153.067388238784645,361.099415032935838,89.4975971674113],"hsluv":[153.067388238784645,99.9999999999909335,89.4975971674113]},"#11ffcc":{"lch":[89.8571262823018628,78.3714319324892159,160.817799258328876],"luv":[89.8571262823018628,-74.0201316086282901,25.7507564896672143],"rgb":[0.0666666666666666657,1,0.8],"xyz":[0.468875185491163915,0.759952297340317773,0.693260436593286289],"hpluv":[160.817799258328876,348.067615225706845,89.8571262823018628],"hsluv":[160.817799258328876,99.999999999991,89.8571262823018628]},"#11ffdd":{"lch":[90.2552779380141317,73.7997451229305,170.162013498752287],"luv":[90.2552779380141317,-72.7145076797264238,12.6096293801408788],"rgb":[0.0666666666666666657,1,0.866666666666666696],"xyz":[0.490393511041797514,0.768559627560571279,0.806590284493292287],"hpluv":[170.162013498752287,342.256686666565315,90.2552779380141317],"hsluv":[170.162013498752287,99.999999999990834,90.2552779380141317]},"#11ffee":{"lch":[90.6924227584195819,71.3832589696730793,180.844217403257659],"luv":[90.6924227584195819,-71.3755103944163665,-1.05174952720347981],"rgb":[0.0666666666666666657,1,0.933333333333333348],"xyz":[0.514205691307972224,0.778084499667041296,0.93200110056181551],"hpluv":[180.844217403257659,347.82122947809512,90.6924227584195819],"hsluv":[180.844217403257659,99.9999999999901803,90.6924227584195819]},"#11ffff":{"lch":[91.1687759776689859,71.6302608322469467,192.17705063006116],"luv":[91.1687759776689859,-70.0186129384549361,-15.1092061032524665],"rgb":[0.0666666666666666657,1,1],"xyz":[0.540376739717803645,0.788552919030974,1.06983528885359735],"hpluv":[192.17705063006116,369.258709956275879,91.1687759776689859],"hsluv":[192.17705063006116,99.9999999999898108,91.1687759776689859]},"#00aa00":{"lch":[60.5587499434736287,93.727653253516209,127.71501294924046],"luv":[60.5587499434736287,-57.3364240886418415,74.1445038903004559],"rgb":[0,0.66666666666666663,0],"xyz":[0.143740958848290495,0.287481917696585,0.0479136529494288144],"hpluv":[127.71501294924046,196.394882900214554,60.5587499434736287],"hsluv":[127.71501294924046,100.000000000002359,60.5587499434736287]},"#00aa11":{"lch":[60.5946550577951939,92.4075267438518182,128.220974416403209],"luv":[60.5946550577951939,-57.1721703645967665,72.5981675713458543],"rgb":[0,0.66666666666666663,0.0666666666666666657],"xyz":[0.144752624347927628,0.28788658389643984,0.0532417579141844441],"hpluv":[128.220974416403209,193.513984665985475,60.5946550577951939],"hsluv":[128.220974416403209,99.9999999999907772,60.5946550577951939]},"#00aa22":{"lch":[60.661124672570665,90.0113827545795715,129.185497299711983],"luv":[60.661124672570665,-56.8721735728637725,69.7682226983709199],"rgb":[0,0.66666666666666663,0.133333333333333331],"xyz":[0.146627982486404629,0.288636727151830641,0.0631186441101636436],"hpluv":[129.185497299711983,188.289586599726533,60.661124672570665],"hsluv":[129.185497299711983,99.9999999999908624,60.661124672570665]},"#00aa33":{"lch":[60.7703154938824355,86.2098857925288513,130.852037745481823],"luv":[60.7703154938824355,-56.3905639077229353,65.2092685937350751],"rgb":[0,0.66666666666666663,0.2],"xyz":[0.14971573321886239,0.289871827444813768,0.0793807979677747799],"hpluv":[130.852037745481823,180.013429236819462,60.7703154938824355],"hsluv":[130.852037745481823,99.9999999999908,60.7703154938824355]},"#00aa44":{"lch":[60.9274158721733841,81.0355822964375108,133.441426631804489],"luv":[60.9274158721733841,-55.7210928860807044,58.8381288426430444],"rgb":[0,0.66666666666666663,0.266666666666666663],"xyz":[0.15417372846308125,0.291655025542501334,0.102859572920661418],"hpluv":[133.441426631804489,168.77274926729055,60.9274158721733841],"hsluv":[133.441426631804489,99.9999999999908908,60.9274158721733841]},"#00aa55":{"lch":[61.1365343944832915,74.6960845180523592,137.272019015051796],"luv":[61.1365343944832915,-54.8704978500827636,50.6826746335676717],"rgb":[0,0.66666666666666663,0.333333333333333315],"xyz":[0.160136142502443235,0.294039991158246194,0.134261620194635334],"hpluv":[137.272019015051796,155.037353806827582,61.1365343944832915],"hsluv":[137.272019015051796,99.9999999999910614,61.1365343944832915]},"#00aa66":{"lch":[61.4009335299549264,67.6053275851037512,142.80970662058607],"luv":[61.4009335299549264,-53.8565898531593703,40.8649978254956139],"rgb":[0,0.66666666666666663,0.4],"xyz":[0.16772113827595142,0.297073989467649513,0.174209264601779296],"hpluv":[142.80970662058607,139.715720243970395,61.4009335299549264],"hsluv":[142.80970662058607,99.9999999999911893,61.4009335299549264]},"#00aa77":{"lch":[61.7231520087844814,60.4394033477847188,150.696962972825474],"luv":[61.7231520087844814,-52.7057786154446859,29.5807771631501382],"rgb":[0,0.66666666666666663,0.466666666666666674],"xyz":[0.177035151296153326,0.300799594675730309,0.223263066508177205],"hpluv":[150.696962972825474,124.254291935777843,61.7231520087844814],"hsluv":[150.696962972825474,99.9999999999911893,61.7231520087844814]},"#00aa88":{"lch":[62.1050795642419615,54.2095218153359397,161.640221068188367],"luv":[62.1050795642419615,-51.4501140589855126,17.0750700954568337],"rgb":[0,0.66666666666666663,0.533333333333333326],"xyz":[0.188175568398097182,0.305255761516507906,0.281935929911749372],"hpluv":[161.640221068188367,110.761232665855573,62.1050795642419615],"hsluv":[161.640221068188367,99.9999999999911466,62.1050795642419615]},"#00aa99":{"lch":[62.5480102999456307,50.2545412813378576,175.872445658321794],"luv":[62.5480102999456307,-50.1241952468173793,3.61717711159146882],"rgb":[0,0.66666666666666663,0.6],"xyz":[0.201232532507169881,0.310478547160137064,0.350702607552867307],"hpluv":[175.872445658321794,101.95326553071466,62.5480102999456307],"hsluv":[175.872445658321794,99.9999999999913314,62.5480102999456307]},"#00aaaa":{"lch":[63.0526871437625829,49.8847230087107931,192.17705063006116],"luv":[63.0526871437625829,-48.762339705407328,-10.5223484123201398],"rgb":[0,0.66666666666666663,0.66666666666666663],"xyz":[0.216290225472422437,0.316501624346238186,0.430006457169865852],"hpluv":[192.17705063006116,100.392967527320806,63.0526871437625829],"hsluv":[192.17705063006116,99.9999999999914451,63.0526871437625829]},"#00aabb":{"lch":[63.6193436646561565,53.6276681768737,207.895374658889665],"luv":[63.6193436646561565,-47.3963155750249143,-25.0901587081772526],"rgb":[0,0.66666666666666663,0.733333333333333282],"xyz":[0.233427817579759056,0.323356661189172945,0.520264442268507654],"hpluv":[207.895374658889665,106.964349821245364,63.6193436646561565],"hsluv":[207.895374658889665,99.9999999999916,63.6193436646561565]},"#00aacc":{"lch":[64.2477463386430259,60.9097449106327886,220.878520684721707],"luv":[64.2477463386430259,-46.0537892020538,-39.8628338833449],"rgb":[0,0.66666666666666663,0.8],"xyz":[0.25272019302348081,0.331073611366661746,0.62187095293877781],"hpluv":[220.878520684721707,120.300715116377788,64.2477463386430259],"hsluv":[220.878520684721707,99.9999999999916298,64.2477463386430259]},"#00aadd":{"lch":[64.9372385342214926,70.6418801813473465,230.685034316882962],"luv":[64.9372385342214926,-44.7574928469198525,-54.6538385624811625],"rgb":[0,0.66666666666666663,0.866666666666666696],"xyz":[0.274238518574114354,0.339680941586915253,0.735200800838783808],"hpluv":[230.685034316882962,138.04089297290011,64.9372385342214926],"hsluv":[230.685034316882962,99.9999999999918145,64.9372385342214926]},"#00aaee":{"lch":[65.6867863979168618,81.8478503674051,237.87423205753521],"luv":[65.6867863979168618,-43.5250094774703129,-69.3155405356638283],"rgb":[0,0.66666666666666663,0.933333333333333348],"xyz":[0.298050698840289119,0.34920581369338527,0.860611616907307],"hpluv":[237.87423205753521,158.11336767521891,65.6867863979168618],"hsluv":[237.87423205753521,99.999999999991843,65.6867863979168618]},"#00aaff":{"lch":[66.4950261675888,93.8462134827344,243.161780722675303],"luv":[66.4950261675888,-42.369016683119284,-83.7375555551541],"rgb":[0,0.66666666666666663,1],"xyz":[0.324221747250120484,0.359674233057318,0.998445805199088876],"hpluv":[243.161780722675303,179.088178632175044,66.4950261675888],"hsluv":[243.161780722675303,99.9999999999982805,66.4950261675888]},"#00bb00":{"lch":[66.1662429166961772,102.406451239047826,127.71501294924046],"luv":[66.1662429166961772,-62.6455428450044352,81.0099822060849135],"rgb":[0,0.733333333333333282,0],"xyz":[0.177695456756889275,0.355390913513783546,0.0592318189189614333],"hpluv":[127.71501294924046,196.39488290021464,66.1662429166961772],"hsluv":[127.71501294924046,100.000000000002373,66.1662429166961772]},"#00bb11":{"lch":[66.1974173108447559,101.237205455569821,128.123527834983577],"luv":[66.1974173108447559,-62.4996967519340956,79.6414444518024425],"rgb":[0,0.733333333333333282,0.0666666666666666657],"xyz":[0.178707122256526407,0.355795579713638399,0.064559923883717063],"hpluv":[128.123527834983577,194.061073356438868,66.1974173108447559],"hsluv":[128.123527834983577,99.9999999999909335,66.1974173108447559]},"#00bb22":{"lch":[66.2551438620851911,99.1062916374383747,128.898124119483072],"luv":[66.2551438620851911,-62.232564676438038,77.1308299962987718],"rgb":[0,0.733333333333333282,0.133333333333333331],"xyz":[0.180582480395003409,0.3565457229690292,0.0744368100796962556],"hpluv":[128.898124119483072,189.810813804630897,66.2551438620851911],"hsluv":[128.898124119483072,99.9999999999908624,66.2551438620851911]},"#00bb33":{"lch":[66.3500136661217255,95.7008075372637137,130.224174268563928],"luv":[66.3500136661217255,-61.8016571104716235,73.0698278476423155],"rgb":[0,0.733333333333333282,0.2],"xyz":[0.18367023112746117,0.357780823262012326,0.0906989639373074],"hpluv":[130.224174268563928,183.02647365261987,66.3500136661217255],"hsluv":[130.224174268563928,99.9999999999909335,66.3500136661217255]},"#00bb44":{"lch":[66.4865992404304,91.0092453899789859,132.255785626190885],"luv":[66.4865992404304,-61.1983980271068,67.3605138443080875],"rgb":[0,0.733333333333333282,0.266666666666666663],"xyz":[0.18812822637168003,0.359564021359699892,0.114177738890194044],"hpluv":[132.255785626190885,173.696361176634838,66.4865992404304],"hsluv":[132.255785626190885,99.9999999999909619,66.4865992404304]},"#00bb55":{"lch":[66.6685736373934219,85.1496193371524,135.204737263674588],"luv":[66.6685736373934219,-60.4246386982598,59.9943389949978751],"rgb":[0,0.733333333333333282,0.333333333333333315],"xyz":[0.194090640411042015,0.361948986975444753,0.145579786164167946],"hpluv":[135.204737263674588,162.069343805127659,66.6685736373934219],"hsluv":[135.204737263674588,99.9999999999909477,66.6685736373934219]},"#00bb66":{"lch":[66.8989180170192412,78.3861452968700689,139.371990675590268],"luv":[66.8989180170192412,-59.4914065933894,51.0407711152765629],"rgb":[0,0.733333333333333282,0.4],"xyz":[0.2016756361845502,0.364982985284848072,0.185527430571311908],"hpluv":[139.371990675590268,148.682392510907704,66.8989180170192412],"hsluv":[139.371990675590268,99.9999999999911182,66.8989180170192412]},"#00bb77":{"lch":[67.1800303821267448,71.1598447269708316,145.178146497089472],"luv":[67.1800303821267448,-58.4173559625633061,40.6341731047866617],"rgb":[0,0.733333333333333282,0.466666666666666674],"xyz":[0.210989649204752105,0.368708590492928867,0.234581232477709817],"hpluv":[145.178146497089472,134.410786503463328,67.1800303821267448],"hsluv":[145.178146497089472,99.9999999999910898,67.1800303821267448]},"#00bb88":{"lch":[67.5137905946342,64.1363411600919,153.159702568813543],"luv":[67.5137905946342,-57.2268359754185525,28.9578918715820954],"rgb":[0,0.733333333333333282,0.533333333333333326],"xyz":[0.222130066306695961,0.373164757333706465,0.293254095881282],"hpluv":[153.159702568813543,120.545503395456095,67.5137905946342],"hsluv":[153.159702568813543,99.9999999999911608,67.5137905946342]},"#00bb99":{"lch":[67.9016044714860811,58.2533417764790187,163.826150797364875],"luv":[67.9016044714860811,-55.9477282230567141,16.2266304205851419],"rgb":[0,0.733333333333333282,0.6],"xyz":[0.235187030415768661,0.378387542977335622,0.362020773522399919],"hpluv":[163.826150797364875,108.862958898475256,67.9016044714860811],"hsluv":[163.826150797364875,99.9999999999912461,67.9016044714860811]},"#00bbaa":{"lch":[68.3444379186728384,54.6744668749029543,177.202021912208522],"luv":[68.3444379186728384,-54.6092872876890922,2.66890801368250408],"rgb":[0,0.733333333333333282,0.66666666666666663],"xyz":[0.250244723381021217,0.384410620163436745,0.44132462313939852],"hpluv":[177.202021912208522,101.512776720033713,68.3444379186728384],"hsluv":[177.202021912208522,99.9999999999913598,68.3444379186728384]},"#00bbbb":{"lch":[68.8428468315880338,54.4656619866929645,192.177050630061132],"luv":[68.8428468315880338,-53.2402096652165113,-11.4886209116881091],"rgb":[0,0.733333333333333282,0.733333333333333282],"xyz":[0.267382315488357836,0.391265657006371503,0.531582608238040266],"hpluv":[192.177050630061132,100.392967527320806,68.8428468315880338],"hsluv":[192.177050630061132,99.9999999999914451,68.8428468315880338]},"#00bbcc":{"lch":[69.3970058395379397,58.0340346662075675,206.653495587531239],"luv":[69.3970058395379397,-51.8670935918889384,-26.0337047299998297],"rgb":[0,0.733333333333333282,0.8],"xyz":[0.28667469093207959,0.398982607183860305,0.633189118908310422],"hpluv":[206.653495587531239,106.116119046155191,69.3970058395379397],"hsluv":[206.653495587531239,99.9999999999915161,69.3970058395379397]},"#00bbdd":{"lch":[70.0067374807312461,64.9183055759271923,218.91244904401708],"luv":[70.0067374807312461,-50.5133677649133119,-40.7772740125682844],"rgb":[0,0.733333333333333282,0.866666666666666696],"xyz":[0.308193016482713134,0.407589937404113811,0.74651896680831642],"hpluv":[218.91244904401708,117.670246608059514,70.0067374807312461],"hsluv":[218.91244904401708,99.999999999991644,70.0067374807312461]},"#00bbee":{"lch":[70.6715424904064236,74.2108860535778,228.474155043258463],"luv":[70.6715424904064236,-49.1986871961444336,-55.5584807840624819],"rgb":[0,0.733333333333333282,0.933333333333333348],"xyz":[0.332005196748887843,0.417114809510583828,0.871929782876839643],"hpluv":[228.474155043258463,133.248513578578667,70.6715424904064236],"hsluv":[228.474155043258463,99.9999999999918288,70.6715424904064236]},"#00bbff":{"lch":[71.3906313155650167,85.0452269855302,235.688960914523477],"luv":[71.3906313155650167,-47.9387359102869155,-70.246481992653],"rgb":[0,0.733333333333333282,1],"xyz":[0.358176245158719264,0.427583228874516552,1.00976397116862149],"hpluv":[235.688960914523477,151.163886263776277,71.3906313155650167],"hsluv":[235.688960914523477,99.9999999999978,71.3906313155650167]},"#00cc00":{"lch":[71.6795694698327139,110.939506494120423,127.71501294924046],"luv":[71.6795694698327139,-67.8655057683618566,87.7601688009055181],"rgb":[0,0.8,0],"xyz":[0.215919200066506195,0.431838400133018441,0.0719730666888333814],"hpluv":[127.71501294924046,196.394882900214611,71.6795694698327139],"hsluv":[127.71501294924046,100.000000000002359,71.6795694698327139]},"#00cc11":{"lch":[71.7069484470386698,109.895339051400697,128.05073784188761],"luv":[71.7069484470386698,-67.7349868616780668,86.5387606802328548],"rgb":[0,0.8,0.0666666666666666657],"xyz":[0.216930865566143327,0.432243066332873294,0.0773011716535890181],"hpluv":[128.05073784188761,194.472124503698296,71.7069484470386698],"hsluv":[128.05073784188761,99.9999999999908766,71.7069484470386698]},"#00cc22":{"lch":[71.7576566073484,107.986601617430239,128.68476606632143],"luv":[71.7576566073484,-67.4954197535952289,84.2939763041676287],"rgb":[0,0.8,0.133333333333333331],"xyz":[0.218806223704620328,0.432993209588264094,0.0871780578495682107],"hpluv":[128.68476606632143,190.959361108477,71.7576566073484],"hsluv":[128.68476606632143,99.9999999999909193,71.7576566073484]},"#00cc33":{"lch":[71.8410194320707,104.91966800737103,129.762682813168567],"luv":[71.8410194320707,-67.1075822658835364,80.6517770244687853],"rgb":[0,0.8,0.2],"xyz":[0.22189397443707809,0.434228309881247221,0.103440211707179347],"hpluv":[129.762682813168567,185.320621425294917,71.8410194320707],"hsluv":[129.762682813168567,99.9999999999909761,71.8410194320707]},"#00cc44":{"lch":[71.9610975929873717,100.65733905537941,131.396818004218431],"luv":[71.9610975929873717,-66.561699323308261,75.5078809721416491],"rgb":[0,0.8,0.266666666666666663],"xyz":[0.226351969681296949,0.436011507978934787,0.126918986660065986],"hpluv":[131.396818004218431,177.495355343216744,71.9610975929873717],"hsluv":[131.396818004218431,99.9999999999909903,71.9610975929873717]},"#00cc55":{"lch":[72.1211872877728837,95.2615727691762828,133.734892870047815],"luv":[72.1211872877728837,-65.8564749898269639,68.8308938513177],"rgb":[0,0.8,0.333333333333333315],"xyz":[0.232314383720658935,0.438396473594679648,0.158321033934039901],"hpluv":[133.734892870047815,167.607792551030144,72.1211872877728837],"hsluv":[133.734892870047815,99.999999999991033,72.1211872877728837]},"#00cc66":{"lch":[72.3240060759138,88.9026050634798821,136.980115521422647],"luv":[72.3240060759138,-64.9982032665013207,60.6539921126355495],"rgb":[0,0.8,0.4],"xyz":[0.23989937949416712,0.441430471904082966,0.198268678341183863],"hpluv":[136.980115521422647,155.980870440536961,72.3240060759138],"hsluv":[136.980115521422647,99.9999999999910614,72.3240060759138]},"#00cc77":{"lch":[72.5717906268391459,81.8763194870781206,141.413175407098493],"luv":[72.5717906268391459,-63.9997644777707464,51.066249515114805],"rgb":[0,0.8,0.466666666666666674],"xyz":[0.249213392514369025,0.445156077112163762,0.247322480247581772],"hpluv":[141.413175407098493,143.162673336571032,72.5717906268391459],"hsluv":[141.413175407098493,99.9999999999910756,72.5717906268391459]},"#00cc88":{"lch":[72.8663546950801,74.6325704710961162,147.40707881161012],"luv":[72.8663546950801,-62.8793552775828672,40.2020802322297683],"rgb":[0,0.8,0.533333333333333326],"xyz":[0.260353809616312881,0.449612243952941359,0.305995343651153939],"hpluv":[147.40707881161012,129.969270924532168,72.8663546950801],"hsluv":[147.40707881161012,99.9999999999911608,72.8663546950801]},"#00cc99":{"lch":[73.2091273059676695,67.813783770663278,155.40051707617576],"luv":[73.2091273059676695,-61.6589956558222809,28.2290191825639418],"rgb":[0,0.8,0.6],"xyz":[0.273410773725385581,0.454835029596570517,0.374762021292271874],"hpluv":[155.40051707617576,117.541728748843539,73.2091273059676695],"hsluv":[155.40051707617576,99.9999999999911893,73.2091273059676695]},"#00ccaa":{"lch":[73.6011808048110368,62.2803364521242102,165.745935171574274],"luv":[73.6011808048110368,-60.3629393869259374,15.3347923742089414],"rgb":[0,0.8,0.66666666666666663],"xyz":[0.288468466690638137,0.460858106782671639,0.454065870909270419],"hpluv":[165.745935171574274,107.375573062224,73.6011808048110368],"hsluv":[165.745935171574274,99.9999999999912887,73.6011808048110368]},"#00ccbb":{"lch":[74.043253901593,59.041045922693165,178.335616576813749],"luv":[74.043253901593,-59.0161369965186395,1.7148404163965667],"rgb":[0,0.8,0.733333333333333282],"xyz":[0.305606058797974756,0.467713143625606398,0.544323856007912221],"hpluv":[178.335616576813749,101.183074845522739,74.043253901593],"hsluv":[178.335616576813749,99.9999999999913882,74.043253901593]},"#00cccc":{"lch":[74.5357725840108714,58.9696734274942429,192.177050630061132],"luv":[74.5357725840108714,-57.64288292201784,-12.4386668330598962],"rgb":[0,0.8,0.8],"xyz":[0.32489843424169651,0.4754300938030952,0.645930366678182377],"hpluv":[192.177050630061132,100.392967527320835,74.5357725840108714],"hsluv":[192.177050630061132,99.9999999999914877,74.5357725840108714]},"#00ccdd":{"lch":[75.0788705190671,62.3850861111967063,205.58971515357635],"luv":[75.0788705190671,-56.2657375800620656,-26.9456071312750254],"rgb":[0,0.8,0.866666666666666696],"xyz":[0.346416759792330053,0.484037424023348706,0.759260214578188375],"hpluv":[205.58971515357635,105.439266222061761,75.0788705190671],"hsluv":[205.58971515357635,99.9999999999915588,75.0788705190671]},"#00ccee":{"lch":[75.672409810316779,68.9113069897593,217.179575991302841],"luv":[75.672409810316779,-54.9047659259632326,-41.6441461630807765],"rgb":[0,0.8,0.933333333333333348],"xyz":[0.370228940058504818,0.493562296129818723,0.884671030646711598],"hpluv":[217.179575991302841,115.555933163518176,75.672409810316779],"hsluv":[217.179575991302841,99.9999999999916,75.672409810316779]},"#00ccff":{"lch":[76.3160024985922263,77.7871508482342193,226.46755023570978],"luv":[76.3160024985922263,-53.5770891110031471,-56.3944710009551713],"rgb":[0,0.8,1],"xyz":[0.396399988468336184,0.504030715493751447,1.02250521893849333],"hpluv":[226.46755023570978,131.600547876461974,76.3160024985922263],"hsluv":[226.46755023570978,99.9999999999969731,76.3160024985922263]},"#00dd00":{"lch":[77.1074905447145369,119.34037845513086,127.715012949240503],"luv":[77.1074905447145369,-73.004607631587163,94.4057900468603],"rgb":[0,0.866666666666666696,0],"xyz":[0.258553190613681372,0.51710638122737,0.0861843968712247],"hpluv":[127.715012949240503,210.385995725156505,77.1074905447145369],"hsluv":[127.715012949240503,100.000000000002203,77.1074905447145369]},"#00dd11":{"lch":[77.1317715771024268,118.40111864948102,127.995077421524911],"luv":[77.1317715771024268,-72.8869911141770359,93.3076171797906255],"rgb":[0,0.866666666666666696,0.0666666666666666657],"xyz":[0.259564856113318476,0.517511047427224868,0.0915125018359803366],"hpluv":[127.995077421524911,208.997725019578468,77.1317715771024268],"hsluv":[127.995077421524911,99.9999999999909193,77.1317715771024268]},"#00dd22":{"lch":[77.1767486793617081,116.680170458435171,128.522366120948305],"luv":[77.1767486793617081,-72.6707542705971434,91.2864921658838568],"rgb":[0,0.866666666666666696,0.133333333333333331],"xyz":[0.261440214251795533,0.518261190682615669,0.101389388031959529],"hpluv":[128.522366120948305,206.449864525990506,77.1767486793617081],"hsluv":[128.522366120948305,99.9999999999909335,77.1767486793617081]},"#00dd33":{"lch":[77.2507083817471312,113.903613467858165,129.414072915332611],"luv":[77.2507083817471312,-72.3197155087496668,87.9993858488157485],"rgb":[0,0.866666666666666696,0.2],"xyz":[0.264527964984253239,0.519496290975598796,0.117651541889570666],"hpluv":[129.414072915332611,202.327676795977681,77.2507083817471312],"hsluv":[129.414072915332611,99.9999999999909335,77.2507083817471312]},"#00dd44":{"lch":[77.3572825066044,110.019432359123073,130.755032484191332],"luv":[77.3572825066044,-71.8235777962907633,83.3405613681826907],"rgb":[0,0.866666666666666696,0.266666666666666663],"xyz":[0.268985960228472154,0.521279489073286362,0.141130316842457304],"hpluv":[130.755032484191332,196.537344059934071,77.3572825066044],"hsluv":[130.755032484191332,99.9999999999909193,77.3572825066044]},"#00dd55":{"lch":[77.499442461574418,105.05363654061,132.652443872197409],"luv":[77.499442461574418,-71.1790335676869717,77.2645567564888],"rgb":[0,0.866666666666666696,0.333333333333333315],"xyz":[0.274948374267834139,0.523664454689031111,0.172532364116431219],"hpluv":[132.652443872197409,189.094972829508237,77.499442461574418],"hsluv":[132.652443872197409,99.9999999999909477,77.499442461574418]},"#00dd66":{"lch":[77.6796666807438,99.1151742217995,135.249123061333165],"luv":[77.6796666807438,-70.3890792332532413,69.7796194150732276],"rgb":[0,0.866666666666666696,0.4],"xyz":[0.282533370041342324,0.52669845299843443,0.212480008523575181],"hpluv":[135.249123061333165,180.139247328423863,77.6796666807438],"hsluv":[135.249123061333165,99.9999999999909903,77.6796666807438]},"#00dd77":{"lch":[77.9000291762011301,92.4061998396230138,138.73841210181584],"luv":[77.9000291762011301,-69.4623356452591878,60.9416909472136155],"rgb":[0,0.866666666666666696,0.466666666666666674],"xyz":[0.29184738306154423,0.530424058206515281,0.26153381042997309],"hpluv":[138.73841210181584,169.957910917592017,77.9000291762011301],"hsluv":[138.73841210181584,99.9999999999910187,77.9000291762011301]},"#00dd88":{"lch":[78.1622519856154,85.2389230174627386,143.3784757437721],"luv":[78.1622519856154,-68.4122000424903,50.8472701580255091],"rgb":[0,0.866666666666666696,0.533333333333333326],"xyz":[0.30298780016348803,0.534880225047292823,0.320206673833545286],"hpluv":[143.3784757437721,159.033158409305884,78.1622519856154],"hsluv":[143.3784757437721,99.9999999999911608,78.1622519856154]},"#00dd99":{"lch":[78.4677391993035798,78.0607504013048583,149.494791226300919],"luv":[78.4677391993035798,-67.2558167964087801,39.6249398770864545],"rgb":[0,0.866666666666666696,0.6],"xyz":[0.316044764272560785,0.540103010690922,0.388973351474663165],"hpluv":[149.494791226300919,148.113090063328627,78.4677391993035798],"hsluv":[149.494791226300919,99.9999999999911466,78.4677391993035798]},"#00ddaa":{"lch":[78.8176011215583401,71.4835041270533225,157.438879868811341],"luv":[78.8176011215583401,-66.0129273361177,27.4259874352573583],"rgb":[0,0.866666666666666696,0.66666666666666663],"xyz":[0.331102457237813286,0.546126087877023103,0.468277201091661766],"hpluv":[157.438879868811341,138.307036304413771,78.8176011215583401],"hsluv":[157.438879868811341,99.9999999999912319,78.8176011215583401]},"#00ddbb":{"lch":[79.21267314937,66.2909050184163675,167.440816272526462],"luv":[79.21267314937,-64.7046905962200896,14.4148223370296193],"rgb":[0,0.866666666666666696,0.733333333333333282],"xyz":[0.34824004934514996,0.552981124719957862,0.558535186190303512],"hpluv":[167.440816272526462,131.160951364069831,79.21267314937],"hsluv":[167.440816272526462,99.9999999999912319,79.21267314937]},"#00ddcc":{"lch":[79.6535319864315738,63.3571261830985,179.312753048293331],"luv":[79.6535319864315738,-63.3525685364998381,0.759932897798095253],"rgb":[0,0.866666666666666696,0.8],"xyz":[0.367532424788871714,0.560698074897446719,0.660141696860573668],"hpluv":[179.312753048293331,128.577362979680402,79.6535319864315738],"hsluv":[179.312753048293331,99.9999999999913314,79.6535319864315738]},"#00dddd":{"lch":[80.1405107346531338,63.4039144225475795,192.177050630061245],"luv":[80.1405107346531338,-61.9773555359817649,-13.3739958452306631],"rgb":[0,0.866666666666666696,0.866666666666666696],"xyz":[0.389050750339505202,0.569305405117700225,0.773471544760579666],"hpluv":[192.177050630061245,132.399857962191078,80.1405107346531338],"hsluv":[192.177050630061245,99.9999999999915,80.1405107346531338]},"#00ddee":{"lch":[80.6737137665329,66.6843941199945078,204.668960845135786],"luv":[80.6737137665329,-60.59840405426975,-27.8323884211582282],"rgb":[0,0.866666666666666696,0.933333333333333348],"xyz":[0.412862930605679967,0.578830277224170242,0.898882360829102889],"hpluv":[204.668960845135786,143.769811077134563,80.6737137665329],"hsluv":[204.668960845135786,99.9999999999914735,80.6737137665329]},"#00ddff":{"lch":[81.2530318771427,72.8883394631876627,215.643856178856652],"luv":[81.2530318771427,-59.2330695533496296,-42.475328144570291],"rgb":[0,0.866666666666666696,1],"xyz":[0.439033979015511333,0.589298696588103,1.03671654912088473],"hpluv":[215.643856178856652,162.831862460855405,81.2530318771427],"hsluv":[215.643856178856652,99.9999999999960636,81.2530318771427]},"#00ee00":{"lch":[82.4573791946470749,127.620478503329409,127.715012949240503],"luv":[82.4573791946470749,-78.0698291684561241,100.955873068518613],"rgb":[0,0.933333333333333348,0],"xyz":[0.305731966954196188,0.611463933908400925,0.101910655651395884],"hpluv":[127.715012949240503,307.908475174189959,82.4573791946470749],"hsluv":[127.715012949240503,100.000000000002217,82.4573791946470749]},"#00ee11":{"lch":[82.4790940690076582,126.770138643430457,127.951660682688043],"luv":[82.4790940690076582,-77.963182339567652,99.9620440525398],"rgb":[0,0.933333333333333348,0.0666666666666666657],"xyz":[0.306743632453833293,0.611868600108255833,0.107238760616151521],"hpluv":[127.951660682688043,306.293921948395678,82.4790940690076582],"hsluv":[127.951660682688043,99.9999999999909193,82.4790940690076582]},"#00ee22":{"lch":[82.5193223464761729,125.209295581045268,128.396138884075839],"luv":[82.5193223464761729,-77.7668632323815814,98.1309466116455],"rgb":[0,0.933333333333333348,0.133333333333333331],"xyz":[0.308618990592310349,0.612618743363646634,0.117115646812130714],"hpluv":[128.396138884075839,303.325246698320768,82.5193223464761729],"hsluv":[128.396138884075839,99.9999999999907914,82.5193223464761729]},"#00ee33":{"lch":[82.5854861516441616,122.683025615083068,129.144698003447559],"luv":[82.5854861516441616,-77.4474668310457304,95.1473313105795881],"rgb":[0,0.933333333333333348,0.2],"xyz":[0.311706741324768055,0.613853843656629761,0.133377800669741864],"hpluv":[129.144698003447559,298.506449004286878,82.5854861516441616],"hsluv":[129.144698003447559,99.9999999999910187,82.5854861516441616]},"#00ee44":{"lch":[82.680854944152216,119.131104912681948,130.263308305441626],"luv":[82.680854944152216,-76.994580956063885,90.9068460629701889],"rgb":[0,0.933333333333333348,0.266666666666666663],"xyz":[0.31616473656898697,0.615637041754317327,0.156856575622628502],"hpluv":[130.263308305441626,291.702339981024693,82.680854944152216],"hsluv":[130.263308305441626,99.9999999999908624,82.680854944152216]},"#00ee55":{"lch":[82.8081199656530913,114.556122924925475,131.832385242542614],"luv":[82.8081199656530913,-76.4036333062175572,85.3556683366704192],"rgb":[0,0.933333333333333348,0.333333333333333315],"xyz":[0.322127150608348956,0.618022007370062076,0.18825862289660239],"hpluv":[131.832385242542614,282.889526663711365,82.8081199656530913],"hsluv":[131.832385242542614,99.9999999999908908,82.8081199656530913]},"#00ee66":{"lch":[82.9695459516691756,109.025909834785097,133.955863991345211],"luv":[82.9695459516691756,-75.6753248662734137,78.4849936082476347],"rgb":[0,0.933333333333333348,0.4],"xyz":[0.329712146381857141,0.621056005679465395,0.22820626730374638],"hpluv":[133.955863991345211,272.166364406401044,82.9695459516691756],"hsluv":[133.955863991345211,99.9999999999909193,82.9695459516691756]},"#00ee77":{"lch":[83.167051813506589,102.679799146220446,136.771308753659213],"luv":[83.167051813506589,-74.8151450958190338,70.3266323450776127],"rgb":[0,0.933333333333333348,0.466666666666666674],"xyz":[0.339026159402059046,0.624781610887546246,0.277260069210144289],"hpluv":[136.771308753659213,259.776444306911685,83.167051813506589],"hsluv":[136.771308753659213,99.9999999999910898,83.167051813506589]},"#00ee88":{"lch":[83.4022585136551839,95.7389522528198427,140.46074817536558],"luv":[83.4022585136551839,-73.8327925713246742,60.9480575538504],"rgb":[0,0.933333333333333348,0.533333333333333326],"xyz":[0.350166576504002847,0.629237777728323788,0.335932932613716428],"hpluv":[140.46074817536558,246.149488794882956,83.4022585136551839],"hsluv":[140.46074817536558,99.999999999991033,83.4022585136551839]},"#00ee99":{"lch":[83.6765199188301096,88.5221307628359142,145.258543938418427],"luv":[83.6765199188301096,-72.7414610621927,50.4464813176313],"rgb":[0,0.933333333333333348,0.6],"xyz":[0.363223540613075602,0.634460563371953,0.404699610254834363],"hpluv":[145.258543938418427,231.96752956627526,83.6765199188301096],"hsluv":[145.258543938418427,99.9999999999911,83.6765199188301096]},"#00eeaa":{"lch":[83.9909442670452364,81.4671227341597159,151.444498676017645],"luv":[83.9909442670452364,-71.557012704351564,38.9420854527837363],"rgb":[0,0.933333333333333348,0.66666666666666663],"xyz":[0.378281233578328102,0.640483640558054068,0.484003459871832964],"hpluv":[151.444498676017645,218.263507316576721,83.9909442670452364],"hsluv":[151.444498676017645,99.9999999999911893,83.9909442670452364]},"#00eebb":{"lch":[84.3464103530465366,75.1511025294100392,159.294479220170871],"luv":[84.3464103530465366,-70.2970903476626319,26.5707978811035801],"rgb":[0,0.933333333333333348,0.733333333333333282],"xyz":[0.395418825685664777,0.647338677400988827,0.57426144497047471],"hpluv":[159.294479220170871,206.543608310772072,84.3464103530465366],"hsluv":[159.294479220170871,99.9999999999912,84.3464103530465366]},"#00eecc":{"lch":[84.743580800257746,70.2844566194431195,168.945018717488722],"luv":[84.743580800257746,-68.9802322625990456,13.4771064879770393],"rgb":[0,0.933333333333333348,0.8],"xyz":[0.414711201129386531,0.655055627578477684,0.675867955640744866],"hpluv":[168.945018717488722,198.871854707918374,84.743580800257746],"hsluv":[168.945018717488722,99.9999999999913,84.743580800257746]},"#00eedd":{"lch":[85.1829138464002114,67.6253239558150625,180.163192871920216],"luv":[85.1829138464002114,-67.6250496492668418,-0.192613766721418916],"rgb":[0,0.933333333333333348,0.866666666666666696],"xyz":[0.43622952668002,0.66366295779873119,0.789197803540750864],"hpluv":[180.163192871920216,197.760624486431198,85.1829138464002114],"hsluv":[180.163192871920216,99.9999999999913882,85.1829138464002114]},"#00eeee":{"lch":[85.6646745174910507,67.7744082531008303,192.177050630061217],"luv":[85.6646745174910507,-66.2495152673009358,-14.2958784586901881],"rgb":[0,0.933333333333333348,0.933333333333333348],"xyz":[0.460041706946194784,0.673187829905201207,0.914608619609274087],"hpluv":[192.177050630061217,205.696714727687493,85.6646745174910507],"hsluv":[192.177050630061217,99.9999999999914309,85.6646745174910507]},"#00eeff":{"lch":[86.1889457184888,70.9350767712842867,203.864647638418489],"luv":[86.1889457184888,-64.8703943995767247,-28.6987290135183635],"rgb":[0,0.933333333333333348,1],"xyz":[0.486212755356026149,0.683656249269133931,1.05244280790105593],"hpluv":[203.864647638418489,224.453619733699583,86.1889457184888],"hsluv":[203.864647638418489,99.9999999999939888,86.1889457184888]},"#00ff00":{"lch":[87.7355191096597338,135.789531996666284,127.715012949240474],"luv":[87.7355191096597338,-83.0671197143942663,107.418111239344327],"rgb":[0,1,0],"xyz":[0.35758433938387,0.71516867876775,0.11919477979462],"hpluv":[127.715012949240474,490.145375063702204,87.7355191096597338],"hsluv":[127.715012949240474,100.000000000002217,87.7355191096597338]},"#00ff11":{"lch":[87.7550810882892165,135.01527678270574,127.917210072153054],"luv":[87.7550810882892165,-82.9698837721702915,106.513489059100834],"rgb":[0,1,0.0666666666666666657],"xyz":[0.358596004883507125,0.715573344967604941,0.124522884759375632],"hpluv":[127.917210072153054,488.208403570135204,87.7550810882892165],"hsluv":[127.917210072153054,99.9999999999917719,87.7550810882892165]},"#00ff22":{"lch":[87.7913242833811864,133.592052176160422,128.296258949772664],"luv":[87.7913242833811864,-82.7907071985999892,104.845291769319132],"rgb":[0,1,0.133333333333333331],"xyz":[0.360471363021984181,0.716323488222995741,0.134399770955354825],"hpluv":[128.296258949772664,484.641757887342919,87.7913242833811864],"hsluv":[128.296258949772664,99.9999999999919,87.7913242833811864]},"#00ff33":{"lch":[87.850943105558116,131.282721750620482,128.932531697131338],"luv":[87.850943105558116,-82.4986966230128616,102.123053644879462],"rgb":[0,1,0.2],"xyz":[0.363559113754441887,0.717558588515978868,0.150661924812965975],"hpluv":[128.932531697131338,478.837727878060548,87.850943105558116],"hsluv":[128.932531697131338,99.999999999991843,87.850943105558116]},"#00ff44":{"lch":[87.9368982766027756,128.022939247233296,129.878593634905172],"luv":[87.9368982766027756,-82.0835673214571528,98.245411848516369],"rgb":[0,1,0.266666666666666663],"xyz":[0.368017108998660802,0.719341786613666434,0.174140699765852613],"hpluv":[129.878593634905172,470.610169071279643,87.9368982766027756],"hsluv":[129.878593634905172,99.9999999999916724,87.9368982766027756]},"#00ff55":{"lch":[88.0516385770734189,123.799916713223595,131.196479790431113],"luv":[88.0516385770734189,-81.5399771501718362,93.1539129857171133],"rgb":[0,1,0.333333333333333315],"xyz":[0.373979523038022788,0.721726752229411184,0.205542747039826501],"hpluv":[131.196479790431113,459.892953467552729,88.0516385770734189],"hsluv":[131.196479790431113,99.9999999999917719,88.0516385770734189]},"#00ff66":{"lch":[88.197238997611,118.653311588493224,132.964137709394919],"luv":[88.197238997611,-80.8670327043222557,86.8281715373192498],"rgb":[0,1,0.4],"xyz":[0.381564518811531,0.724760750538814502,0.245490391446970491],"hpluv":[132.964137709394919,446.748834194207859,88.197238997611],"hsluv":[132.964137709394919,99.9999999999917719,88.197238997611]},"#00ff77":{"lch":[88.3754745956423164,112.679107800887323,135.2824164931273],"luv":[88.3754745956423164,-80.0679233099649537,79.2824633297525452],"rgb":[0,1,0.466666666666666674],"xyz":[0.390878531831732878,0.728486355746895353,0.2945441933533684],"hpluv":[135.2824164931273,431.3936933951166,88.3754745956423164],"hsluv":[135.2824164931273,99.9999999999915445,88.3754745956423164]},"#00ff88":{"lch":[88.587864465470858,106.036155512425779,138.2828406903445],"luv":[88.587864465470858,-79.1495135423216425,70.5621767086956311],"rgb":[0,1,0.533333333333333326],"xyz":[0.402018948933676679,0.732942522587672896,0.353217056756940539],"hpluv":[138.2828406903445,414.239888157084465,88.587864465470858],"hsluv":[138.2828406903445,99.9999999999914,88.587864465470858]},"#00ff99":{"lch":[88.8357000190422,98.9561663203651278,142.1349886621461],"luv":[88.8357000190422,-78.1218422027535695,60.739613298668921],"rgb":[0,1,0.6],"xyz":[0.415075913042749378,0.738165308231302109,0.421983734398058474],"hpluv":[142.1349886621461,395.967958147281365,88.8357000190422],"hsluv":[142.1349886621461,99.9999999999915303,88.8357000190422]},"#00ffaa":{"lch":[89.1200644426462674,91.7580340339716258,147.049061977519528],"luv":[89.1200644426462674,-76.997527549554917,49.9090929694682828],"rgb":[0,1,0.66666666666666663],"xyz":[0.430133606008001934,0.744188385417403175,0.501287584015057],"hpluv":[147.049061977519528,377.639750156066668,89.1200644426462674],"hsluv":[147.049061977519528,99.9999999999913,89.1200644426462674]},"#00ffbb":{"lch":[89.4418470234824241,84.8653215767476468,153.262243037154207],"luv":[89.4418470234824241,-75.791105608661141,38.1815546689964407],"rgb":[0,1,0.733333333333333282],"xyz":[0.447271198115338608,0.751043422260337934,0.591545569113698821],"hpluv":[153.262243037154207,360.863433446149145,89.4418470234824241],"hsluv":[153.262243037154207,99.9999999999912,89.4418470234824241]},"#00ffcc":{"lch":[89.801754487955634,78.8187300060100569,160.986090443114392],"luv":[89.801754487955634,-74.5183415032407197,25.6789598575702236],"rgb":[0,1,0.8],"xyz":[0.466563573559060307,0.758760372437826791,0.693152079783969],"hpluv":[160.986090443114392,347.997153451554084,89.801754487955634],"hsluv":[160.986090443114392,99.9999999999912461,89.801754487955634]},"#00ffdd":{"lch":[90.2003206582774339,74.260092310928,170.286849800478649],"luv":[90.2003206582774339,-73.1955569867131572,12.5288366352336915],"rgb":[0,1,0.866666666666666696],"xyz":[0.488081899109693906,0.767367702658080297,0.806481927683975],"hpluv":[170.286849800478649,342.308208972166483,90.2003206582774339],"hsluv":[170.286849800478649,99.9999999999913314,90.2003206582774339]},"#00ffee":{"lch":[90.6379152481429458,71.8480695265374294,180.909719109957],"luv":[90.6379152481429458,-71.8390133400929898,-1.14072652818200426],"rgb":[0,1,0.933333333333333348],"xyz":[0.511894079375868616,0.776892574764550314,0.931892743752498198],"hpluv":[180.909719109957,347.895283980605143,90.6379152481429458],"hsluv":[180.909719109957,99.999999999991374,90.6379152481429458]},"#00ffff":{"lch":[91.114752316705065,72.0862882649682,192.17705063006116],"luv":[91.114752316705065,-70.4643799638718207,-15.205397466925735],"rgb":[0,1,1],"xyz":[0.5380651277857,0.787360994128483,1.06972693204428],"hpluv":[192.17705063006116,369.190533917051368,91.114752316705065],"hsluv":[192.17705063006116,99.9999999999914877,91.114752316705065]},"#ff0000":{"lch":[53.23711559542933,179.038096923620287,12.1770506300617765],"luv":[53.23711559542933,175.009822162883836,37.7650936255616],"rgb":[1,0,0],"xyz":[0.41239079926595,0.21263900587151,0.019330818715591],"hpluv":[12.1770506300617765,426.746789183125202,53.23711559542933],"hsluv":[12.1770506300617765,100.000000000002203,53.23711559542933]},"#ff0011":{"lch":[53.2810087118185294,177.689248384364731,11.7592124156573554],"luv":[53.2810087118185294,173.960033822228979,36.2129206771479346],"rgb":[1,0,0.0666666666666666657],"xyz":[0.413402464765587119,0.213043672071364848,0.0246589236803466325],"hpluv":[11.7592124156573554,423.182830024727082,53.2810087118185294],"hsluv":[11.7592124156573554,99.9999999999986073,53.2810087118185294]},"#ff0022":{"lch":[53.362228057366309,175.255817292919801,10.9800713678561319],"luv":[53.362228057366309,172.047495148921342,33.3805468497921751],"rgb":[1,0,0.133333333333333331],"xyz":[0.415277822904064176,0.213793815326755676,0.0345358098763258251],"hpluv":[10.9800713678561319,416.75211680728853,53.362228057366309],"hsluv":[10.9800713678561319,99.9999999999986215,53.362228057366309]},"#ff0033":{"lch":[53.4955416476677499,171.43316235878109,9.68478250033725],"luv":[53.4955416476677499,168.989928530586468,28.8397852204116347],"rgb":[1,0,0.2],"xyz":[0.418365573636521881,0.215028915619738775,0.0507979637339369683],"hpluv":[9.68478250033725,406.646064741178918,53.4955416476677499],"hsluv":[9.68478250033725,99.9999999999986215,53.4955416476677499]},"#ff0044":{"lch":[53.6871179383659722,166.29954793496961,7.78930386328567259],"luv":[53.6871179383659722,164.765128442936401,22.5386799204815809],"rgb":[1,0,0.266666666666666663],"xyz":[0.422823568880740797,0.216812113717426369,0.0742767386868236],"hpluv":[7.78930386328567259,393.061316669856922,53.6871179383659722],"hsluv":[7.78930386328567259,99.9999999999987637,53.6871179383659722]},"#ff0055":{"lch":[53.9417095924386558,160.100368719231,5.2128969892355661],"luv":[53.9417095924386558,159.438189183864722,14.5461986032050437],"rgb":[1,0,0.333333333333333315],"xyz":[0.428785982920102782,0.219197079333171202,0.105678785960797522],"hpluv":[5.2128969892355661,376.623098544524225,53.9417095924386558],"hsluv":[5.2128969892355661,99.9999999999988,53.9417095924386558]},"#ff0066":{"lch":[54.2629295430466669,153.227313284557312,1.88082466234467849],"luv":[54.2629295430466669,153.144763004983872,5.02902580538230204],"rgb":[1,0,0.4],"xyz":[0.436370978693610967,0.222231077642574493,0.145626430367941484],"hpluv":[1.88082466234467849,358.321012364802243,54.2629295430466669],"hsluv":[1.88082466234467849,99.99999999999892,54.2629295430466669]},"#ff0077":{"lch":[54.6533978532017244,146.184101175375929,357.735148851436577],"luv":[54.6533978532017244,146.06990602550718,-5.77702260269427281],"rgb":[1,0,0.466666666666666674],"xyz":[0.445684991713812872,0.225956682850655316,0.194680232274339393],"hpluv":[357.735148851436577,339.408176675868503,54.6533978532017244],"hsluv":[357.735148851436577,99.9999999999990479,54.6533978532017244]},"#ff0088":{"lch":[55.1148373309560782,139.538803635294983,352.754628092234327],"luv":[55.1148373309560782,138.424605854630585,-17.5984719211521572],"rgb":[1,0,0.533333333333333326],"xyz":[0.456825408815756673,0.230412849691432914,0.253353095677911533],"hpluv":[352.754628092234327,321.26675874055752,55.1148373309560782],"hsluv":[352.754628092234327,99.9999999999991616,55.1148373309560782]},"#ff0099":{"lch":[55.6481496721619493,133.863929319774144,346.981903482220218],"luv":[55.6481496721619493,130.423488026195145,-30.1540269949209758],"rgb":[1,0,0.6],"xyz":[0.469882372924829372,0.235635635335062071,0.322119773319029468],"hpluv":[346.981903482220218,305.247535929832054,55.6481496721619493],"hsluv":[346.981903482220218,99.9999999999993463,55.6481496721619493]},"#ff00aa":{"lch":[56.2534865150640258,129.667114810270476,340.549180922221581],"luv":[56.2534865150640258,122.266710865918853,-43.1788383036143273],"rgb":[1,0,0.66666666666666663],"xyz":[0.484940065890081928,0.241658712521163166,0.401423622936028068],"hpluv":[340.549180922221581,292.495864077812769,56.2534865150640258],"hsluv":[340.549180922221581,99.9999999999994742,56.2534865150640258]},"#ff00bb":{"lch":[56.9303217870161689,127.321325924901956,333.685619315648239],"luv":[56.9303217870161689,114.127678427447606,-56.4410582115202928],"rgb":[1,0,0.733333333333333282],"xyz":[0.502077657997418547,0.248513749364097924,0.491681608034669815],"hpluv":[333.685619315648239,283.789838362024682,56.9303217870161689],"hsluv":[333.685619315648239,99.9999999999995879,56.9303217870161689]},"#ff00cc":{"lch":[57.6775275187384153,127.012826563172382,326.690520651062286],"luv":[57.6775275187384153,106.146716951325558,-69.7505024499586312],"rgb":[1,0,0.8],"xyz":[0.521370033441140301,0.256230699541586726,0.593288118704939915],"hpluv":[326.690520651062286,279.434659423159303,57.6775275187384153],"hsluv":[326.690520651062286,99.9999999999997726,57.6775275187384153]},"#ff00dd":{"lch":[58.4934529509690151,128.727977043064641,319.874434183361473],"luv":[58.4934529509690151,98.4297766537384149,-82.9606602040687],"rgb":[1,0,0.866666666666666696],"xyz":[0.542888358991773901,0.264838029761840288,0.706617966604945913],"hpluv":[319.874434183361473,279.257606739571429,58.4934529509690151],"hsluv":[319.874434183361473,99.9999999999999716,58.4934529509690151]},"#ff00ee":{"lch":[59.3760054748790367,132.286429048213932,313.494468670954461],"luv":[59.3760054748790367,91.0507046157626,-95.9659757377649214],"rgb":[1,0,0.933333333333333348],"xyz":[0.56670053925794861,0.274362901868310305,0.832028782673469136],"hpluv":[313.494468670954461,282.711609251625362,59.3760054748790367],"hsluv":[313.494468670954461,100.000000000000156,59.3760054748790367]},"#ff00ff":{"lch":[60.3227313545512942,137.405400537897037,307.715012949243601],"luv":[60.3227313545512942,84.0556019897527875,-108.696365491768773],"rgb":[1,0,1],"xyz":[0.59287158766778,0.284831321232243,0.969862970965251],"hpluv":[307.715012949243601,289.042783730483336,60.3227313545512942],"hsluv":[307.715012949243601,100.000000000000384,60.3227313545512942]},"#ff1100":{"lch":[53.6695097624616864,176.771562285449363,12.5954542867932275],"luv":[53.6695097624616864,172.517389506501019,38.5478345786208934],"rgb":[1,0.0666666666666666657,0],"xyz":[0.414395199526878422,0.216647806393366865,0.019998952135900451],"hpluv":[12.5954542867932275,417.949777534481484,53.6695097624616864],"hsluv":[12.5954542867932275,100.000000000002245,53.6695097624616864]},"#ff1111":{"lch":[53.7128602445647658,175.445128796306847,12.1770506300617765],"luv":[53.7128602445647658,171.497694164414924,37.0072170615611569],"rgb":[1,0.0666666666666666657,0.0666666666666666657],"xyz":[0.415406865026515526,0.217052472593221718,0.0253270571006560807],"hpluv":[12.1770506300617765,414.478837946685644,53.7128602445647658],"hsluv":[12.1770506300617765,99.9999999999986215,53.7128602445647658]},"#ff1122":{"lch":[53.7930781791116743,173.051572118951754,11.3967197916969329],"luv":[53.7930781791116743,169.639425839354459,34.1952016185739538],"rgb":[1,0.0666666666666666657,0.133333333333333331],"xyz":[0.417282223164992583,0.217802615848612546,0.0352039432966352803],"hpluv":[11.3967197916969329,408.214548988049671,53.7930781791116743],"hsluv":[11.3967197916969329,99.9999999999987,53.7930781791116743]},"#ff1133":{"lch":[53.9247555399676912,169.290109899416,10.0990648343251674],"luv":[53.9247555399676912,166.667136068812482,29.6851320424264138],"rgb":[1,0.0666666666666666657,0.2],"xyz":[0.420369973897450289,0.219037716141595645,0.0514660971542464235],"hpluv":[10.0990648343251674,398.366425235699353,53.9247555399676912],"hsluv":[10.0990648343251674,99.9999999999987,53.9247555399676912]},"#ff1144":{"lch":[54.1139966850166445,164.235972949617775,8.19925898659400154],"luv":[54.1139966850166445,162.55716522781,23.4226993279181244],"rgb":[1,0.0666666666666666657,0.266666666666666663],"xyz":[0.424827969141669204,0.220820914239283239,0.074944872107133062],"hpluv":[8.19925898659400154,385.121711929848118,54.1139966850166445],"hsluv":[8.19925898659400154,99.9999999999988489,54.1139966850166445]},"#ff1155":{"lch":[54.365514290002,158.12888296709221,5.61535385404219856],"luv":[54.365514290002,157.370056367003059,15.4728467796533362],"rgb":[1,0.0666666666666666657,0.333333333333333315],"xyz":[0.430790383181031189,0.223205879855028072,0.106346919381106964],"hpluv":[5.61535385404219856,369.085538340858477,54.365514290002],"hsluv":[5.61535385404219856,99.9999999999988916,54.365514290002]},"#ff1166":{"lch":[54.6829025612910442,151.353597545298243,2.27091305216541839],"luv":[54.6829025612910442,151.234730451097789,5.99731567352495443],"rgb":[1,0.0666666666666666657,0.4],"xyz":[0.438375378954539374,0.226239878164431363,0.146294563788250925],"hpluv":[2.27091305216541839,351.221033033747858,54.6829025612910442],"hsluv":[2.27091305216541839,99.999999999999,54.6829025612910442]},"#ff1177":{"lch":[55.0687823252034292,144.407362773795285,358.105880212246802],"luv":[55.0687823252034292,144.328460520523464,-4.77303960367160496],"rgb":[1,0.0666666666666666657,0.466666666666666674],"xyz":[0.44768939197474128,0.229965483372512186,0.195348365694648834],"hpluv":[358.105880212246802,332.753927221166919,55.0687823252034292],"hsluv":[358.105880212246802,99.9999999999990905,55.0687823252034292]},"#ff1188":{"lch":[55.5248949860500716,137.85386672349216,353.096828842063303],"luv":[55.5248949860500716,136.85452147125136,-16.5689023019976744],"rgb":[1,0.0666666666666666657,0.533333333333333326],"xyz":[0.45882980907668508,0.234421650213289784,0.254021229098221],"hpluv":[353.096828842063303,315.043506786171235,55.5248949860500716],"hsluv":[353.096828842063303,99.9999999999992,55.5248949860500716]},"#ff1199":{"lch":[56.0521767726019249,132.264360312052816,347.28491936957397],"luv":[56.0521767726019249,129.020794472918823,-29.1117777254046715],"rgb":[1,0.0666666666666666657,0.6],"xyz":[0.47188677318575778,0.239644435856918941,0.322787906739338937],"hpluv":[347.28491936957397,299.426117704125659,56.0521767726019249],"hsluv":[347.28491936957397,99.9999999999993605,56.0521767726019249]},"#ff11aa":{"lch":[56.6508275614924912,128.148315107741439,340.802676353967],"luv":[56.6508275614924912,121.022209124101792,-42.1380536294115586],"rgb":[1,0.0666666666666666657,0.66666666666666663],"xyz":[0.486944466151010336,0.245667513043020036,0.402091756356337537],"hpluv":[340.802676353967,287.042344439162662,56.6508275614924912],"hsluv":[340.802676353967,99.9999999999995168,56.6508275614924912]},"#ff11bb":{"lch":[57.3203806938084455,125.882364893771992,333.882217516525884],"luv":[57.3203806938084455,113.02864145467457,-55.4156656746030762],"rgb":[1,0.0666666666666666657,0.733333333333333282],"xyz":[0.504082058258347,0.252522549885954795,0.492349741454979284],"hpluv":[333.882217516525884,278.673167271969135,57.3203806938084455],"hsluv":[333.882217516525884,99.9999999999996163,57.3203806938084455]},"#ff11cc":{"lch":[58.0597760671947754,125.656277294901628,326.828156543045054],"luv":[58.0597760671947754,105.178488239830273,-68.7530772780178694],"rgb":[1,0.0666666666666666657,0.8],"xyz":[0.523374433702068709,0.260239500063443596,0.593956252125249384],"hpluv":[326.828156543045054,274.630115267561905,58.0597760671947754],"hsluv":[326.828156543045054,99.9999999999997868,58.0597760671947754]},"#ff11dd":{"lch":[58.8674364673636177,127.458097444326981,319.957026901825429],"luv":[58.8674364673636177,97.5770916499376568,-82.0016938195011846],"rgb":[1,0.0666666666666666657,0.866666666666666696],"xyz":[0.544892759252702308,0.268846830283697158,0.707286100025255382],"hpluv":[319.957026901825429,274.746161939823423,58.8674364673636177],"hsluv":[319.957026901825429,100.000000000000028,58.8674364673636177]},"#ff11ee":{"lch":[59.7413458233107519,131.106916258937218,313.5305052972667],"luv":[59.7413458233107519,90.2986667085849319,-95.0535337669245877],"rgb":[1,0.0666666666666666657,0.933333333333333348],"xyz":[0.568704939518877,0.278371702390167175,0.832696916093778605],"hpluv":[313.5305052972667,278.477381794919836,59.7413458233107519],"hsluv":[313.5305052972667,100.000000000000199,59.7413458233107519]},"#ff11ff":{"lch":[60.6791274610807534,136.317870534400242,307.715012949243601],"luv":[60.6791274610807534,83.3903225409976,-107.83606045076894],"rgb":[1,0.0666666666666666657,1],"xyz":[0.594875987928708438,0.288840121754099899,0.97053110438556045],"hpluv":[307.715012949243601,285.070838096226908,60.6791274610807534],"hsluv":[307.715012949243601,100.000000000000398,60.6791274610807534]},"#ff2200":{"lch":[54.4571507543770679,172.725520469573979,13.3786813235288875],"luv":[54.4571507543770679,168.038102184023103,39.9662562154253393],"rgb":[1,0.133333333333333331,0],"xyz":[0.418110823261646336,0.224079053862902833,0.0212374933808230602],"hpluv":[13.3786813235288875,402.476865089738737,54.4571507543770679],"hsluv":[13.3786813235288875,100.00000000000216,54.4571507543770679]},"#ff2211":{"lch":[54.4995382972682876,171.437527349711331,12.9593558016228254],"luv":[54.4995382972682876,167.070909686171433,38.446546274251638],"rgb":[1,0.133333333333333331,0.0666666666666666657],"xyz":[0.41912248876128344,0.224483720062757686,0.0265655983455786934],"hpluv":[12.9593558016228254,399.164948195999784,54.4995382972682876],"hsluv":[12.9593558016228254,99.999999999998721,54.4995382972682876]},"#ff2222":{"lch":[54.5779789595956117,169.112342257331477,12.1770506300617924],"luv":[54.5779789595956117,165.307392407273255,35.6714216042562171],"rgb":[1,0.133333333333333331,0.133333333333333331],"xyz":[0.420997846899760497,0.225233863318148514,0.036442484541557886],"hpluv":[12.1770506300617924,393.185217729465933,54.5779789595956117],"hsluv":[12.1770506300617924,99.9999999999987494,54.5779789595956117]},"#ff2233":{"lch":[54.7067518227456,165.455769736233549,10.8753803895539445],"luv":[54.7067518227456,162.484163442906947,31.2171166072114978],"rgb":[1,0.133333333333333331,0.2],"xyz":[0.424085597632218203,0.226468963611131613,0.0527046383991690293],"hpluv":[10.8753803895539445,383.778210348001721,54.7067518227456],"hsluv":[10.8753803895539445,99.9999999999987779,54.7067518227456]},"#ff2244":{"lch":[54.8918465894738148,160.537768894747074,8.96806115251763103],"luv":[54.8918465894738148,158.575257224785304,25.0252480066910863],"rgb":[1,0.133333333333333331,0.266666666666666663],"xyz":[0.428543592876437118,0.228252161708819207,0.0761834133520556678],"hpluv":[8.96806115251763103,371.115171122776133,54.8918465894738148],"hsluv":[8.96806115251763103,99.9999999999988347,54.8918465894738148]},"#ff2255":{"lch":[55.1379036013317432,154.588213330392733,6.3708707633682522],"luv":[55.1379036013317432,153.633547891150499,17.1536778289841081],"rgb":[1,0.133333333333333331,0.333333333333333315],"xyz":[0.434506006915799103,0.23063712732456404,0.107585460626029583],"hpluv":[6.3708707633682522,355.76683037739258,55.1379036013317432],"hsluv":[6.3708707633682522,99.9999999999989342,55.1379036013317432]},"#ff2266":{"lch":[55.4484819892530254,147.979820726080618,3.00414546296194196],"luv":[55.4484819892530254,147.776458796099433,7.75535736170059753],"rgb":[1,0.133333333333333331,0.4],"xyz":[0.442091002689307289,0.23367112563396733,0.147533105033173545],"hpluv":[3.00414546296194196,338.650844053811227,55.4484819892530254],"hsluv":[3.00414546296194196,99.9999999999990763,55.4484819892530254]},"#ff2277":{"lch":[55.8262016697843961,141.198613687408425,358.803757025958646],"luv":[55.8262016697843961,141.167840095073672,-2.94778393674187145],"rgb":[1,0.133333333333333331,0.466666666666666674],"xyz":[0.451405015709509194,0.237396730842048154,0.196586906939571454],"hpluv":[358.803757025958646,320.945787006908631,55.8262016697843961],"hsluv":[358.803757025958646,99.9999999999991616,55.8262016697843961]},"#ff2288":{"lch":[56.2728344602164299,134.800794021339357,353.742009538390391],"luv":[56.2728344602164299,133.997535770156077,-14.694028593592142],"rgb":[1,0.133333333333333331,0.533333333333333326],"xyz":[0.462545432811453,0.241852897682825752,0.255259770343143622],"hpluv":[353.742009538390391,303.971583410200083,56.2728344602164299],"hsluv":[353.742009538390391,99.9999999999992752,56.2728344602164299]},"#ff2299":{"lch":[56.7893750973531866,129.355771045476672,347.857065824102108],"luv":[56.7893750973531866,126.461550291410035,-27.2101415039127161],"rgb":[1,0.133333333333333331,0.6],"xyz":[0.47560239692052575,0.247075683326454909,0.324026447984261501],"hpluv":[347.857065824102108,289.040064659782502,56.7893750973531866],"hsluv":[347.857065824102108,99.9999999999994316,56.7893750973531866]},"#ff22aa":{"lch":[57.3761062638205743,125.376808270539939,341.281866819384959],"luv":[57.3761062638205743,118.745473604842076,-40.2350164715945766],"rgb":[1,0.133333333333333331,0.66666666666666663],"xyz":[0.49066008988577825,0.253098760512556031,0.403330297601260102],"hpluv":[341.281866819384959,277.284417349873706,57.3761062638205743],"hsluv":[341.281866819384959,99.999999999999531,57.3761062638205743]},"#ff22bb":{"lch":[58.0326640845464112,123.247659375493754,334.254064951888324],"luv":[58.0326640845464112,111.01274832153284,-53.5364852379920606],"rgb":[1,0.133333333333333331,0.733333333333333282],"xyz":[0.507797681993114924,0.25995379735549079,0.493588282699901848],"hpluv":[334.254064951888324,269.491764983662165,58.0326640845464112],"hsluv":[334.254064951888324,99.9999999999997726,58.0326640845464112]},"#ff22cc":{"lch":[58.7581065478829316,123.164795236141373,327.088444575119183],"luv":[58.7581065478829316,103.398114188518221,-66.9208246199849128],"rgb":[1,0.133333333333333331,0.8],"xyz":[0.527090057436836679,0.267670747532979592,0.595194793370172],"hpluv":[327.088444575119183,265.985598747154427,58.7581065478829316],"hsluv":[327.088444575119183,99.9999999999998721,58.7581065478829316]},"#ff22dd":{"lch":[59.550985046801415,125.119413407905796,320.113090366201448],"luv":[59.550985046801415,96.0055877759378,-80.2358693312108358],"rgb":[1,0.133333333333333331,0.866666666666666696],"xyz":[0.548608382987470167,0.276278077753233098,0.708524641270178],"hpluv":[320.113090366201448,266.609166102550091,59.550985046801415],"hsluv":[320.113090366201448,100.000000000000028,59.550985046801415]},"#ff22ee":{"lch":[60.4094179672163705,128.929416765847606,313.598505937960113],"luv":[60.4094179672163705,88.9098108664153273,-93.3693742041783281],"rgb":[1,0.133333333333333331,0.933333333333333348],"xyz":[0.572420563253645,0.285802949859703115,0.833935457338701225],"hpluv":[313.598505937960113,270.823716236275,60.4094179672163705],"hsluv":[313.598505937960113,100.000000000000227,60.4094179672163705]},"#ff22ff":{"lch":[61.3311646171935223,134.305840538380238,307.715012949243601],"luv":[61.3311646171935223,82.1594946996257249,-106.244417422389745],"rgb":[1,0.133333333333333331,1],"xyz":[0.598591611663476297,0.296271369223635839,0.97176964563048307],"hpluv":[307.715012949243601,277.877263991976,61.3311646171935223],"hsluv":[307.715012949243601,100.000000000000398,61.3311646171935223]},"#ff3300":{"lch":[55.7168894472394811,166.476173059961667,14.689559134518138],"luv":[55.7168894472394811,161.034729269155179,42.2153072463082495],"rgb":[1,0.2,0],"xyz":[0.424228545350657182,0.236314498040924637,0.0232767340771599419],"hpluv":[14.689559134518138,379.144314271077917,55.7168894472394811],"hsluv":[14.689559134518138,100.000000000002203,55.7168894472394811]},"#ff3311":{"lch":[55.7578022303213,165.243627812887922,14.2690908575150317],"luv":[55.7578022303213,160.145669888681539,40.7286256663500339],"rgb":[1,0.2,0.0666666666666666657],"xyz":[0.425240210850294287,0.236719164240779489,0.0286048390419155751],"hpluv":[14.2690908575150317,376.06108995847427,55.7578022303213],"hsluv":[14.2690908575150317,99.9999999999988,55.7578022303213]},"#ff3322":{"lch":[55.8335204651182835,163.01701714894287,13.4842232594842422],"luv":[55.8335204651182835,158.523316810386802,38.0119179675594552],"rgb":[1,0.2,0.133333333333333331],"xyz":[0.427115568988771344,0.237469307496170318,0.0384817252378947677],"hpluv":[13.4842232594842422,370.490653647292163,55.8335204651182835],"hsluv":[13.4842232594842422,99.9999999999987494,55.8335204651182835]},"#ff3333":{"lch":[55.9578428172660267,159.511521097175432,12.1770506300617853],"luv":[55.9578428172660267,155.922585303490365,33.6462888742638455],"rgb":[1,0.2,0.2],"xyz":[0.430203319721229049,0.238704407789153417,0.0547438790955059179],"hpluv":[12.1770506300617853,361.718248261175631,55.9578428172660267],"hsluv":[12.1770506300617853,99.9999999999988773,55.9578428172660267]},"#ff3344":{"lch":[56.1365811585215368,154.789240798906889,10.2588910791084782],"luv":[56.1365811585215368,152.31463646984821,27.5673826135157078],"rgb":[1,0.2,0.266666666666666663],"xyz":[0.434661314965447965,0.240487605886841,0.0782226540483925564],"hpluv":[10.2588910791084782,349.892100101075414,56.1365811585215368],"hsluv":[10.2588910791084782,99.9999999999989626,56.1365811585215368]},"#ff3355":{"lch":[56.3742616664660403,149.065442517766684,7.64169944339336649],"luv":[56.3742616664660403,147.741595680550319,19.8223878173745902],"rgb":[1,0.2,0.333333333333333315],"xyz":[0.44062372900480995,0.242872571502585843,0.109624701322366458],"hpluv":[7.64169944339336649,335.533149366899124,56.3742616664660403],"hsluv":[7.64169944339336649,99.9999999999990195,56.3742616664660403]},"#ff3366":{"lch":[56.674385203130754,142.694983818340035,4.24028319431916056],"luv":[56.674385203130754,142.304390380845462,10.550776523662277],"rgb":[1,0.2,0.4],"xyz":[0.448208724778318135,0.245906569811989134,0.14957234572951042],"hpluv":[4.24028319431916056,319.492902958598108,56.674385203130754],"hsluv":[4.24028319431916056,99.9999999999991758,56.674385203130754]},"#ff3377":{"lch":[57.0395646827704468,136.14730874514737,359.983392279567909],"luv":[57.0395646827704468,136.147303025702882,-0.0394635770517579934],"rgb":[1,0.2,0.466666666666666674],"xyz":[0.457522737798520041,0.249632175020069957,0.198626147635908329],"hpluv":[359.983392279567909,302.881107814185,57.0395646827704468],"hsluv":[359.983392279567909,99.9999999999992895,57.0395646827704468]},"#ff3388":{"lch":[57.4716120619286954,129.967879448766553,354.83565117969431],"luv":[57.4716120619286954,129.440287861866665,-11.6987848363070146],"rgb":[1,0.2,0.533333333333333326],"xyz":[0.468663154900463841,0.254088341860847555,0.257299011039480496],"hpluv":[354.83565117969431,286.960407533356261,57.4716120619286954],"hsluv":[354.83565117969431,99.9999999999993889,57.4716120619286954]},"#ff3399":{"lch":[57.9716047421228353,124.724336507791776,348.82951213288959],"luv":[57.9716047421228353,122.361442957788952,-24.1627273832372573],"rgb":[1,0.2,0.6],"xyz":[0.481720119009536596,0.259311127504476713,0.326065688680598431],"hpluv":[348.82951213288959,273.007894976207297,57.9716047421228353],"hsluv":[348.82951213288959,99.9999999999995737,57.9716047421228353]},"#ff33aa":{"lch":[58.5399451724763935,120.937271340322638,342.098036856126953],"luv":[58.5399451724763935,115.081956962752116,-37.174813797329108],"rgb":[1,0.2,0.66666666666666663],"xyz":[0.496777811974789096,0.265334204690577835,0.405369538297597032],"hpluv":[342.098036856126953,262.148381504719794,58.5399451724763935],"hsluv":[342.098036856126953,99.9999999999996732,58.5399451724763935]},"#ff33bb":{"lch":[59.1764201449825862,119.003132790944747,334.888094830460091],"luv":[59.1764201449825862,107.755032536641394,-50.5034511403585498],"rgb":[1,0.2,0.733333333333333282],"xyz":[0.513915404082125771,0.272189241533512594,0.495627523396238778],"hpluv":[334.888094830460091,255.181409444549388,59.1764201449825862],"hsluv":[334.888094830460091,99.9999999999998295,59.1764201449825862]},"#ff33cc":{"lch":[59.8802624584280494,119.13012657470172,327.532171012183937],"luv":[59.8802624584280494,100.509254029343069,-63.9521454852723039],"rgb":[1,0.2,0.8],"xyz":[0.533207779525847525,0.279906191711001395,0.597234034066508879],"hpluv":[327.532171012183937,252.451080902073329,59.8802624584280494],"hsluv":[327.532171012183937,100.000000000000043,59.8802624584280494]},"#ff33dd":{"lch":[60.650215463767978,121.314823858854638,320.378757122173454],"luv":[60.650215463767978,93.4460015542912146,-77.3636302238999747],"rgb":[1,0.2,0.866666666666666696],"xyz":[0.554726105076481,0.288513521931254902,0.710563881966514876],"hpluv":[320.378757122173454,253.817084039055629,60.650215463767978],"hsluv":[320.378757122173454,100.000000000000171,60.650215463767978]},"#ff33ee":{"lch":[61.484599762034378,125.372817174433621,313.71398784253438],"luv":[61.484599762034378,86.6400000332951805,-90.6192787462169775],"rgb":[1,0.2,0.933333333333333348],"xyz":[0.578538285342655723,0.298038394037724919,0.8359746980350381],"hpluv":[313.71398784253438,258.747618308410438,61.484599762034378],"hsluv":[313.71398784253438,100.000000000000242,61.484599762034378]},"#ff33ff":{"lch":[62.3813806681475,131.007738376122177,307.715012949243658],"luv":[62.3813806681475,80.141932350642,-103.635409940481253],"rgb":[1,0.2,1],"xyz":[0.604709333752487144,0.308506813401657642,0.97380888632682],"hpluv":[307.715012949243658,266.490230971107223,62.3813806681475],"hsluv":[307.715012949243658,100.000000000000597,62.3813806681475]},"#ff4400":{"lch":[57.461133143380664,158.273971604467,16.6278363926044079],"luv":[57.461133143380664,151.655533944896689,45.2907177172089845],"rgb":[1,0.266666666666666663,0],"xyz":[0.433061115833623222,0.253979639006856939,0.0262209242381485352],"hpluv":[16.6278363926044079,349.522099776260404,57.461133143380664],"hsluv":[16.6278363926044079,100.000000000002203,57.461133143380664]},"#ff4411":{"lch":[57.500127691013958,157.107055615985729,16.2066010587584444],"luv":[57.500127691013958,150.863862649088418,43.84885256105823],"rgb":[1,0.266666666666666663,0.0666666666666666657],"xyz":[0.434072781333260327,0.254384305206711792,0.031549029202904165],"hpluv":[16.2066010587584444,346.709871357654038,57.500127691013958],"hsluv":[16.2066010587584444,99.9999999999990195,57.500127691013958]},"#ff4422":{"lch":[57.5723039440668174,154.996970095022306,15.4196600073807488],"luv":[57.5723039440668174,149.417734299680745,41.2116660108183908],"rgb":[1,0.266666666666666663,0.133333333333333331],"xyz":[0.435948139471737384,0.255134448462102592,0.0414259153988833645],"hpluv":[15.4196600073807488,341.624434338608523,57.5723039440668174],"hsluv":[15.4196600073807488,99.9999999999990195,57.5723039440668174]},"#ff4433":{"lch":[57.6908335218327437,151.669616752661852,14.1071803519879388],"luv":[57.6908335218327437,147.095485225188412,36.9674298845038223],"rgb":[1,0.266666666666666663,0.2],"xyz":[0.439035890204195089,0.256369548755085719,0.0576880692564945077],"hpluv":[14.1071803519879388,333.603886972203838,57.6908335218327437],"hsluv":[14.1071803519879388,99.9999999999991189,57.6908335218327437]},"#ff4444":{"lch":[57.8612930010941682,147.177084719743902,12.177050630061812],"luv":[57.8612930010941682,143.865668066403089,31.0445457111261],"rgb":[1,0.266666666666666663,0.266666666666666663],"xyz":[0.443493885448414,0.258152746852773285,0.0811668442093811393],"hpluv":[12.177050630061812,322.76868159643891,57.8612930010941682],"hsluv":[12.177050630061812,99.9999999999991616,57.8612930010941682]},"#ff4455":{"lch":[58.088054010202,141.716285969530816,9.53556562214303405],"luv":[58.088054010202,139.758186425649882,23.4766913344092778],"rgb":[1,0.266666666666666663,0.333333333333333315],"xyz":[0.449456299487776,0.260537712468518146,0.112568891483355055],"hpluv":[9.53556562214303405,309.579547415252762,58.088054010202],"hsluv":[9.53556562214303405,99.9999999999992184,58.088054010202]},"#ff4466":{"lch":[58.3745334436288772,135.619673907166316,6.08910281061040859],"luv":[58.3745334436288772,134.854526247228307,14.3858507333331573],"rgb":[1,0.266666666666666663,0.4],"xyz":[0.457041295261284175,0.263571710777921464,0.152516535890499016],"hpluv":[6.08910281061040859,294.807548797669426,58.3745334436288772],"hsluv":[6.08910281061040859,99.9999999999992468,58.3745334436288772]},"#ff4477":{"lch":[58.7233249761193292,129.336052383116169,1.75519751784143763],"luv":[58.7233249761193292,129.275370036155351,3.96145782045869943],"rgb":[1,0.266666666666666663,0.466666666666666674],"xyz":[0.466355308281486081,0.26729731598600226,0.201570337796896926],"hpluv":[1.75519751784143763,279.478426792191101,58.7233249761193292],"hsluv":[1.75519751784143763,99.99999999999946,58.7233249761193292]},"#ff4488":{"lch":[59.1362810655005831,123.398173767481396,356.485857706034096],"luv":[59.1362810655005831,123.16614811103635,-7.56367957014252212],"rgb":[1,0.266666666666666663,0.533333333333333326],"xyz":[0.477495725383429881,0.271753482826779857,0.260243201200469065],"hpluv":[356.485857706034096,264.785408966002421,59.1362810655005831],"hsluv":[356.485857706034096,99.9999999999995595,59.1362810655005831]},"#ff4499":{"lch":[59.6145739069951901,118.37348532064955,350.303370213710309],"luv":[59.6145739069951901,116.682328099077466,-19.9378117238896806],"rgb":[1,0.266666666666666663,0.6],"xyz":[0.490552689492502636,0.276976268470409,0.329009878841587],"hpluv":[350.303370213710309,251.965637795338,59.6145739069951901],"hsluv":[350.303370213710309,99.9999999999997158,59.6145739069951901]},"#ff44aa":{"lch":[60.1587486598557177,114.795436800176844,343.339450530546515],"luv":[60.1587486598557177,109.976338996192666,-32.9119609129858475],"rgb":[1,0.266666666666666663,0.66666666666666663],"xyz":[0.505610382457755136,0.282999345656510137,0.408313728458585601],"hpluv":[343.339450530546515,242.139230170638513,60.1587486598557177],"hsluv":[343.339450530546515,99.9999999999997726,60.1587486598557177]},"#ff44bb":{"lch":[60.768775409955694,113.081121999454581,335.854341209703],"luv":[60.768775409955694,103.187483930843442,-46.2567110015126133],"rgb":[1,0.266666666666666663,0.733333333333333282],"xyz":[0.522747974565091811,0.289854382499444896,0.498571713557227347],"hpluv":[335.854341209703,236.128794952899398,60.768775409955694],"hsluv":[335.854341209703,99.9999999999999716,60.768775409955694]},"#ff44cc":{"lch":[61.4441027606342232,113.457557937670586,328.208302422827],"luv":[61.4441027606342232,96.4354118722023088,-59.7731443895883743],"rgb":[1,0.266666666666666663,0.8],"xyz":[0.542040350008813565,0.297571332676933697,0.600178224227497559],"hpluv":[328.208302422827,234.310931883055929,61.4441027606342232],"hsluv":[328.208302422827,100.000000000000128,61.4441027606342232]},"#ff44dd":{"lch":[62.1837139115479403,115.929787300919912,320.782684481283354],"luv":[62.1837139115479403,89.8170022013310358,-73.2981698216444357],"rgb":[1,0.266666666666666663,0.866666666666666696],"xyz":[0.563558675559447,0.306178662897187204,0.713508072127503556],"hpluv":[320.782684481283354,236.568931830040128,62.1837139115479403],"hsluv":[320.782684481283354,100.000000000000384,62.1837139115479403]},"#ff44ee":{"lch":[62.986184892514558,120.309477517885213,313.888915695758442],"luv":[62.986184892514558,83.4060394378513195,-86.7052649261745643],"rgb":[1,0.266666666666666663,0.933333333333333348],"xyz":[0.587370855825621874,0.315703535003657221,0.83891888819602678],"hpluv":[313.888915695758442,242.378371703623515,62.986184892514558],"hsluv":[313.888915695758442,100.000000000000512,62.986184892514558]},"#ff44ff":{"lch":[63.8497439492436,126.288239910703226,307.715012949243771],"luv":[63.8497439492436,77.2548530724802447,-99.9019880507531468],"rgb":[1,0.266666666666666663,1],"xyz":[0.613541904235453184,0.326171954367589945,0.976753076487808514],"hpluv":[307.715012949243771,250.982289693600563,63.8497439492436],"hsluv":[307.715012949243771,100.000000000000711,63.8497439492436]},"#ff5500":{"lch":[59.6718499915998279,148.630700843778015,19.3008598736449528],"luv":[59.6718499915998279,140.27705963161867,49.1266910591374923],"rgb":[1,0.333333333333333315,0],"xyz":[0.444874372547969188,0.277606152435549203,0.030158676476263746],"hpluv":[19.3008598736449528,316.066414507984518,59.6718499915998279],"hsluv":[19.3008598736449528,100.00000000000226,59.6718499915998279]},"#ff5511":{"lch":[59.7086010657385486,147.530698996531413,18.8803784611224046],"luv":[59.7086010657385486,139.59299153240957,47.7399608445355526],"rgb":[1,0.333333333333333315,0.0666666666666666657],"xyz":[0.445886038047606292,0.278010818635404056,0.0354867814410193758],"hpluv":[18.8803784611224046,313.53413530658878,59.7086010657385486],"hsluv":[18.8803784611224046,99.9999999999992184,59.7086010657385486]},"#ff5522":{"lch":[59.7766335415963255,145.539064184811622,18.0939597274483681],"luv":[59.7766335415963255,138.341936048844929,45.2009727113036],"rgb":[1,0.333333333333333315,0.133333333333333331],"xyz":[0.447761396186083349,0.278760961890794856,0.0453636676369985753],"hpluv":[18.0939597274483681,308.949467849715688,59.7766335415963255],"hsluv":[18.0939597274483681,99.9999999999993,59.7766335415963255]},"#ff5533":{"lch":[59.8883826376776085,142.391759670631302,16.7797766500676033],"luv":[59.8883826376776085,136.328925827546385,41.1076295206398825],"rgb":[1,0.333333333333333315,0.2],"xyz":[0.450849146918541055,0.279996062183778,0.0616258214946097185],"hpluv":[16.7797766500676033,301.704368813615531,59.8883826376776085],"hsluv":[16.7797766500676033,99.9999999999992752,59.8883826376776085]},"#ff5544":{"lch":[60.0491441299879654,138.129067713899872,14.841281480974498],"luv":[60.0491441299879654,133.520956258941027,35.3806951204903228],"rgb":[1,0.333333333333333315,0.266666666666666663],"xyz":[0.45530714216275997,0.281779260281465549,0.0851045964474963501],"hpluv":[14.841281480974498,291.888903616465711,60.0491441299879654],"hsluv":[14.841281480974498,99.9999999999994458,60.0491441299879654]},"#ff5555":{"lch":[60.2631003442631936,132.926854505406169,12.1770506300618191],"luv":[60.2631003442631936,129.936061471805857,28.0386978637829927],"rgb":[1,0.333333333333333315,0.333333333333333315],"xyz":[0.461269556202121955,0.28416422589721041,0.116506643721470265],"hpluv":[12.1770506300618191,279.898508055628838,60.2631003442631936],"hsluv":[12.1770506300618191,99.99999999999946,60.2631003442631936]},"#ff5566":{"lch":[60.5335583680784168,127.091978224389294,8.68145952340772098],"luv":[60.5335583680784168,125.635857711143842,19.1833830742614],"rgb":[1,0.333333333333333315,0.4],"xyz":[0.468854551975630141,0.287198224206613728,0.156454288128614227],"hpluv":[8.68145952340772098,266.416588145649541,60.5335583680784168],"hsluv":[8.68145952340772098,99.9999999999995737,60.5335583680784168]},"#ff5577":{"lch":[60.8630749033481351,121.049870295691591,4.25532383082281918],"luv":[60.8630749033481351,120.716171483201308,8.98203991541407],"rgb":[1,0.333333333333333315,0.466666666666666674],"xyz":[0.478168564995832046,0.290923829414694524,0.205508090035012136],"hpluv":[4.25532383082281918,252.376995060411161,60.8630749033481351],"hsluv":[4.25532383082281918,99.9999999999997158,60.8630749033481351]},"#ff5588":{"lch":[61.2535329118914404,115.319895978664789,358.830706871579594],"luv":[61.2535329118914404,115.295882188952703,-2.35328680810625102],"rgb":[1,0.333333333333333315,0.533333333333333326],"xyz":[0.489308982097775846,0.295379996255472121,0.264180953438584276],"hpluv":[358.830706871579594,238.897951612134108,61.2535329118914404],"hsluv":[358.830706871579594,99.9999999999997868,61.2535329118914404]},"#ff5599":{"lch":[61.7061969251912075,110.472562823261683,352.412124726619879],"luv":[61.7061969251912075,109.505210454219565,-14.5875296097928366],"rgb":[1,0.333333333333333315,0.6],"xyz":[0.502365946206848601,0.300602781899101279,0.332947631079702211],"hpluv":[352.412124726619879,227.177321581811952,61.7061969251912075],"hsluv":[352.412124726619879,99.9999999999998721,61.7061969251912075]},"#ff55aa":{"lch":[62.2217597266614177,107.062368992166355,345.125792918237266],"luv":[62.2217597266614177,103.474894783269619,-27.4826673342684735],"rgb":[1,0.333333333333333315,0.66666666666666663],"xyz":[0.517423639172101102,0.306625859085202401,0.412251480696700812],"hpluv":[345.125792918237266,218.340291577764589,62.2217597266614177],"hsluv":[345.125792918237266,100.000000000000071,62.2217597266614177]},"#ff55bb":{"lch":[62.8003867495987862,105.538663220643826,337.249357740418191],"luv":[62.8003867495987862,97.3274002701012,-40.8140489422941855],"rgb":[1,0.333333333333333315,0.733333333333333282],"xyz":[0.534561231279437776,0.31348089592813716,0.502509465795342614],"hpluv":[337.249357740418191,213.249782655969199,62.8003867495987862],"hsluv":[337.249357740418191,100.000000000000284,62.8003867495987862]},"#ff55cc":{"lch":[63.441761241476712,106.157882562261193,329.184616986090759],"luv":[63.441761241476712,91.1707664760994447,-54.3818661895983837],"rgb":[1,0.333333333333333315,0.8],"xyz":[0.553853606723159531,0.321197846105625961,0.60411597646561277],"hpluv":[329.184616986090759,212.332436268611161,63.441761241476712],"hsluv":[329.184616986090759,100.000000000000441,63.441761241476712]},"#ff55dd":{"lch":[64.1451313698934769,108.938462409011748,321.364198961949114],"luv":[64.1451313698934769,85.0951546537234549,-68.0176686346904518],"rgb":[1,0.333333333333333315,0.866666666666666696],"xyz":[0.575371932273793,0.329805176325879468,0.717445824365618767],"hpluv":[321.364198961949114,215.504760823814451,64.1451313698934769],"hsluv":[321.364198961949114,100.000000000000597,64.1451313698934769]},"#ff55ee":{"lch":[64.9093593252901258,113.686114680552976,314.13939983200612],"luv":[64.9093593252901258,79.1717442713053288,-81.5865649491316418],"rgb":[1,0.333333333333333315,0.933333333333333348],"xyz":[0.599184112539967728,0.339330048432349485,0.842856640434142],"hpluv":[314.13939983200612,222.248801840624651,64.9093593252901258],"hsluv":[314.13939983200612,100.000000000000753,64.9093593252901258]},"#ff55ff":{"lch":[65.7329718140353378,120.074032289562709,307.715012949243885],"luv":[65.7329718140353378,73.4534088756767147,-94.9861566483116633],"rgb":[1,0.333333333333333315,1],"xyz":[0.625355160949799149,0.349798467796282209,0.980690828725923724],"hpluv":[307.715012949243885,231.795582155087629,65.7329718140353378],"hsluv":[307.715012949243885,100.000000000000981,65.7329718140353378]},"#ff6600":{"lch":[62.3097916023938438,138.227046243322206,22.8239093069931798],"luv":[62.3097916023938438,127.404056867086908,53.6183047751569717],"rgb":[1,0.4,0],"xyz":[0.459902430253815608,0.307662267847242543,0.03516802904487909],"hpluv":[22.8239093069931798,281.498480884542573,62.3097916023938438],"hsluv":[22.8239093069931798,100.000000000002359,62.3097916023938438]},"#ff6611":{"lch":[62.344110015411573,137.186959502953613,22.4076195476895244],"luv":[62.344110015411573,126.828705913080029,52.2947532174930245],"rgb":[1,0.4,0.0666666666666666657],"xyz":[0.460914095753452713,0.308066934047097396,0.0404961340096347197],"hpluv":[22.4076195476895244,279.226561167599414,62.344110015411573],"hsluv":[22.4076195476895244,99.9999999999995737,62.344110015411573]},"#ff6622":{"lch":[62.4076477973658257,135.300699513710725,21.6278909170268392],"luv":[62.4076477973658257,125.775148313603225,49.8687412673566115],"rgb":[1,0.4,0.133333333333333331],"xyz":[0.46278945389192977,0.308817077302488197,0.0503730202056139192],"hpluv":[21.6278909170268392,275.106945224361368,62.4076477973658257],"hsluv":[21.6278909170268392,99.9999999999996163,62.4076477973658257]},"#ff6633":{"lch":[62.5120380635233346,132.311574345484274,20.3215228987586443],"luv":[62.5120380635233346,124.076309265494103,45.9502141979128851],"rgb":[1,0.4,0.2],"xyz":[0.465877204624387475,0.310052177595471323,0.0666351740632250555],"hpluv":[20.3215228987586443,268.579898420339646,62.5120380635233346],"hsluv":[20.3215228987586443,99.9999999999995879,62.5120380635233346]},"#ff6644":{"lch":[62.6622654373265675,128.246261163642686,18.3868048135947362],"luv":[62.6622654373265675,121.699120282046835,40.4527826611364603],"rgb":[1,0.4,0.266666666666666663],"xyz":[0.470335199868606391,0.311835375693158889,0.0901139490161117],"hpluv":[18.3868048135947362,259.703586528718,62.6622654373265675],"hsluv":[18.3868048135947362,99.9999999999997726,62.6622654373265675]},"#ff6655":{"lch":[62.8622967709428764,123.257362768531593,15.7125644918265355],"luv":[62.8622967709428764,118.651528823693667,33.3795174388964284],"rgb":[1,0.4,0.333333333333333315],"xyz":[0.476297613907968376,0.31422034130890375,0.121515996290085609],"hpluv":[15.7125644918265355,248.806632458920831,62.8622967709428764],"hsluv":[15.7125644918265355,99.9999999999997158,62.8622967709428764]},"#ff6666":{"lch":[63.1153061541487119,117.623502253606588,12.1770506300618742],"luv":[63.1153061541487119,114.97702760078576,24.8107115273291683],"rgb":[1,0.4,0.4],"xyz":[0.483882609681476561,0.317254339618307069,0.161463640697229571],"hpluv":[12.1770506300618742,236.482353971627703,63.1153061541487119],"hsluv":[12.1770506300618742,99.9999999999999,63.1153061541487119]},"#ff6677":{"lch":[63.4237926928396121,111.744324598031497,7.65713975886231157],"luv":[63.4237926928396121,110.747917341816802,14.8893547314965815],"rgb":[1,0.4,0.466666666666666674],"xyz":[0.493196622701678467,0.320979944826387864,0.21051744260362748],"hpluv":[7.65713975886231157,223.569519019308729,63.4237926928396121],"hsluv":[7.65713975886231157,100.000000000000071,63.4237926928396121]},"#ff6688":{"lch":[63.7896518301749751,106.125321016318935,2.05404070639815961],"luv":[63.7896518301749751,106.057131857198982,3.80375380925921824],"rgb":[1,0.4,0.533333333333333326],"xyz":[0.504337039803622322,0.325436111667165462,0.26919030600719962],"hpluv":[2.05404070639815961,211.109662635719985,63.7896518301749751],"hsluv":[2.05404070639815961,100.000000000000128,63.7896518301749751]},"#ff6699":{"lch":[64.2142253202301276,101.344202045456129,355.341285926877504],"luv":[64.2142253202301276,101.009378125853075,-8.23121004826552394],"rgb":[1,0.4,0.6],"xyz":[0.517394003912695,0.330658897310794619,0.337956983648317555],"hpluv":[355.341285926877504,200.265890662959123,64.2142253202301276],"hsluv":[355.341285926877504,100.000000000000199,64.2142253202301276]},"#ff66aa":{"lch":[64.6983418323177233,97.9876087444390436,347.629516841099075],"luv":[64.6983418323177233,95.7126081968365838,-20.9920961224008664],"rgb":[1,0.4,0.66666666666666663],"xyz":[0.532451696877947578,0.336681974496895742,0.417260833265316156],"hpluv":[347.629516841099075,192.184047560801417,64.6983418323177233],"hsluv":[347.629516841099075,100.000000000000441,64.6983418323177233]},"#ff66bb":{"lch":[65.2423543089962408,96.5541832870936787,339.215698562051898],"luv":[65.2423543089962408,90.270720679111,-34.2623306024503123],"rgb":[1,0.4,0.733333333333333282],"xyz":[0.549589288985284141,0.3435370113398305,0.507518818363957847],"hpluv":[339.215698562051898,187.793604034801348,65.2423543089962408],"hsluv":[339.215698562051898,100.000000000000597,65.2423543089962408]},"#ff66cc":{"lch":[65.8461771980182533,97.3465701370285,330.562118792095362],"luv":[65.8461771980182533,84.7780628468697159,-47.8438583036069218],"rgb":[1,0.4,0.8],"xyz":[0.568881664429005895,0.351253961517319302,0.609125329034228],"hpluv":[330.562118792095362,187.598522894675455,65.8461771980182533],"hsluv":[330.562118792095362,100.000000000000711,65.8461771980182533]},"#ff66dd":{"lch":[66.5093249736543157,100.405273498350255,322.181562409870594],"luv":[66.5093249736543157,79.3159229397089831,-61.5646271368605298],"rgb":[1,0.4,0.866666666666666696],"xyz":[0.590399989979639495,0.359861291737572808,0.722455176934234],"hpluv":[322.181562409870594,191.563741116159406,66.5093249736543157],"hsluv":[322.181562409870594,100.000000000000952,66.5093249736543157]},"#ff66ee":{"lch":[67.2309523334132706,105.527911758853008,314.488878023448478],"luv":[67.2309523334132706,73.9508789773533408,-75.2821868615750702],"rgb":[1,0.4,0.933333333333333348],"xyz":[0.614212170245814204,0.369386163844042825,0.847865993002757223],"hpluv":[314.488878023448478,199.176184031939982,67.2309523334132706],"hsluv":[314.488878023448478,100.000000000001066,67.2309523334132706]},"#ff66ff":{"lch":[68.0098958254125137,112.360313920932768,307.715012949244056],"luv":[68.0098958254125137,68.7346624616611592,-88.8841173702707437],"rgb":[1,0.4,1],"xyz":[0.640383218655645625,0.379854583207975549,0.985700181294539179],"hpluv":[307.715012949244056,209.642901019847784,68.0098958254125137],"hsluv":[307.715012949244056,100.000000000001421,68.0098958254125137]},"#ff7700":{"lch":[65.3236824647912755,127.817378582796977,27.3102887077963814],"luv":[65.3236824647912755,113.570196302134065,58.6437786953806466],"rgb":[1,0.466666666666666674,0],"xyz":[0.478356168307233265,0.344569743954078356,0.0413192750626848],"hpluv":[27.3102887077963814,248.289625700463205,65.3236824647912755],"hsluv":[27.3102887077963814,100.00000000000226,65.3236824647912755]},"#ff7711":{"lch":[65.3555057958206476,126.824695098806032,26.9045059733925385],"luv":[65.3555057958206476,113.097436843789765,57.3887886809793],"rgb":[1,0.466666666666666674,0.0666666666666666657],"xyz":[0.479367833806870369,0.344974410153933209,0.0466473800274404271],"hpluv":[26.9045059733925385,246.24134425049084,65.3555057958206476],"hsluv":[26.9045059733925385,99.9999999999999716,65.3555057958206476]},"#ff7722":{"lch":[65.4144320044565291,125.020679344179442,26.1430666348463],"luv":[65.4144320044565291,112.230643754756542,55.0858681158159058],"rgb":[1,0.466666666666666674,0.133333333333333331],"xyz":[0.481243191945347426,0.345724553409324,0.0565242662234196266],"hpluv":[26.1430666348463,242.520026060215031,65.4144320044565291],"hsluv":[26.1430666348463,100.000000000000156,65.4144320044565291]},"#ff7733":{"lch":[65.511267747206432,122.151716277204869,24.8632302030062533],"luv":[65.511267747206432,110.829965834679456,51.3591322215488688],"rgb":[1,0.466666666666666674,0.2],"xyz":[0.484330942677805132,0.346959653702307136,0.0727864200810307699],"hpluv":[24.8632302030062533,236.604443239770575,65.511267747206432],"hsluv":[24.8632302030062533,100.000000000000128,65.511267747206432]},"#ff7744":{"lch":[65.6506715027637853,118.22870540382597,22.9581907744090898],"luv":[65.6506715027637853,108.863777518532288,46.1162089276663139],"rgb":[1,0.466666666666666674,0.266666666666666663],"xyz":[0.488788937922024047,0.348742851799994702,0.0962651950339174084],"hpluv":[22.9581907744090898,228.519406804146513,65.6506715027637853],"hsluv":[22.9581907744090898,100.000000000000199,65.6506715027637853]},"#ff7755":{"lch":[65.8363783536997857,113.378413750733145,20.3056908730066645],"luv":[65.8363783536997857,106.332452226692425,39.3455754576116092],"rgb":[1,0.466666666666666674,0.333333333333333315],"xyz":[0.494751351961386032,0.351127817415739563,0.12766724230789131],"hpluv":[20.3056908730066645,218.526329281612362,65.8363783536997857],"hsluv":[20.3056908730066645,100.000000000000171,65.8363783536997857]},"#ff7766":{"lch":[66.0714111968285351,107.847817312906827,16.7638759706376135],"luv":[66.0714111968285351,103.264450834403533,31.1063481146080676],"rgb":[1,0.466666666666666674,0.4],"xyz":[0.502336347734894217,0.354161815725142881,0.167614886715035272],"hpluv":[16.7638759706376135,207.127185394700234,66.0714111968285351],"hsluv":[16.7638759706376135,100.000000000000426,66.0714111968285351]},"#ff7777":{"lch":[66.3581913431115851,102.006782949974053,12.1770506300619488],"luv":[66.3581913431115851,99.7116772923406671,21.5166256497442419],"rgb":[1,0.466666666666666674,0.466666666666666674],"xyz":[0.511650360755096067,0.357887420933223677,0.216668688621433181],"hpluv":[12.1770506300619488,195.062523033846361,66.3581913431115851],"hsluv":[12.1770506300619488,100.000000000000355,66.3581913431115851]},"#ff7788":{"lch":[66.6986047917809,96.3441833198397291,6.39999172914420456],"luv":[66.6986047917809,95.7437601312525,10.7393694179903871],"rgb":[1,0.466666666666666674,0.533333333333333326],"xyz":[0.52279077785704,0.362343587774001274,0.275341552025005376],"hpluv":[6.39999172914420456,183.293927388427107,66.6986047917809],"hsluv":[6.39999172914420456,100.000000000000639,66.6986047917809]},"#ff7799":{"lch":[67.0940474565320244,91.4474963932601,359.352586865695173],"luv":[67.0940474565320244,91.4416585161261679,-1.0332881570442134],"rgb":[1,0.466666666666666674,0.6],"xyz":[0.535847741966112623,0.367566373417630432,0.344108229666123255],"hpluv":[359.352586865695173,172.952623850798517,67.0940474565320244],"hsluv":[359.352586865695173,100.000000000000782,67.0940474565320244]},"#ff77aa":{"lch":[67.5454605183692,87.9484746627524,351.107126776790835],"luv":[67.5454605183692,86.8912550098467449,-13.5957345634056814],"rgb":[1,0.466666666666666674,0.66666666666666663],"xyz":[0.550905434931365234,0.373589450603731554,0.423412079283121856],"hpluv":[351.107126776790835,165.223368139110704,67.5454605183692],"hsluv":[351.107126776790835,100.000000000000938,67.5454605183692]},"#ff77bb":{"lch":[68.0533617234635244,86.4195813509952,341.973592157308417],"luv":[68.0533617234635244,82.1775887588569,-26.7429980866295693],"rgb":[1,0.466666666666666674,0.733333333333333282],"xyz":[0.568043027038701798,0.380444487446666313,0.513670064381763658],"hpluv":[341.973592157308417,161.139458954487083,68.0533617234635244],"hsluv":[341.973592157308417,100.000000000001037,68.0533617234635244]},"#ff77cc":{"lch":[68.6178757233526682,87.2373067072756214,332.49967924393593],"luv":[68.6178757233526682,77.3802105983984347,-40.2821385887937],"rgb":[1,0.466666666666666674,0.8],"xyz":[0.587335402482423552,0.388161437624155115,0.615276575052033814],"hpluv":[332.49967924393593,161.325977991170333,68.6178757233526682],"hsluv":[332.49967924393593,100.000000000001265,68.6178757233526682]},"#ff77dd":{"lch":[69.238765020261809,90.480647802514838,323.326201907778],"luv":[69.238765020261809,72.5699004301545756,-54.0403291840472],"rgb":[1,0.466666666666666674,0.866666666666666696],"xyz":[0.608853728033057151,0.396768767844408621,0.728606422952039812],"hpluv":[323.326201907778,165.823361543811586,69.238765020261809],"hsluv":[323.326201907778,100.00000000000145,69.238765020261809]},"#ff77ee":{"lch":[69.9154621504300593,95.9376886025569604,314.973456368277198],"luv":[69.9154621504300593,67.8067552495039791,-67.8696105553513149],"rgb":[1,0.466666666666666674,0.933333333333333348],"xyz":[0.632665908299231861,0.406293639950878638,0.854017239020563],"hpluv":[314.973456368277198,174.122680701596721,69.9154621504300593],"hsluv":[314.973456368277198,100.000000000001535,69.9154621504300593]},"#ff77ff":{"lch":[70.6471031550122,103.213892868752552,307.715012949244283],"luv":[70.6471031550122,63.1394826173239494,-81.6487196221654],"rgb":[1,0.466666666666666674,1],"xyz":[0.658836956709063282,0.416762059314811362,0.99185142731234488],"hpluv":[307.715012949244283,185.388643374650655,70.6471031550122],"hsluv":[307.715012949244283,100.000000000001975,70.6471031550122]},"#ff8800":{"lch":[68.6580440198892603,118.150361410828182,32.8458067740872153],"luv":[68.6580440198892603,99.2620471866307383,64.0823992202883375],"rgb":[1,0.533333333333333326,0],"xyz":[0.500428538032203774,0.388714483404019873,0.0486767316376747472],"hpluv":[32.8458067740872153,218.364961888913399,68.6580440198892603],"hsluv":[32.8458067740872153,100.000000000002245,68.6580440198892603]},"#ff8811":{"lch":[68.6874112197728408,117.19102013872596,32.4606037779481582],"luv":[68.6874112197728408,98.8811760474647485,62.89871401408422],"rgb":[1,0.533333333333333326,0.0666666666666666657],"xyz":[0.501440203531840933,0.389119149603874726,0.0540048366024303769],"hpluv":[32.4606037779481582,216.499308154785638,68.6874112197728408],"hsluv":[32.4606037779481582,100.000000000000739,68.6874112197728408]},"#ff8822":{"lch":[68.7417963707939492,115.443262249268372,31.7362513605757321],"luv":[68.7417963707939492,98.1820090833864754,60.724294076614548],"rgb":[1,0.533333333333333326,0.133333333333333331],"xyz":[0.503315561670317879,0.389869292859265526,0.0638817227984095765],"hpluv":[31.7362513605757321,213.101761826290613,68.7417963707939492],"hsluv":[31.7362513605757321,100.000000000000668,68.7417963707939492]},"#ff8833":{"lch":[68.8311889682804292,112.651741292777714,30.5141745142023382],"luv":[68.8311889682804292,97.0498776480180823,57.1990914683060439],"rgb":[1,0.533333333333333326,0.2],"xyz":[0.506403312402775696,0.391104393152248653,0.0801438766560207128],"hpluv":[30.5141745142023382,207.678703624478942,68.8311889682804292],"hsluv":[30.5141745142023382,100.000000000000824,68.8311889682804292]},"#ff8844":{"lch":[68.9599197258043688,108.808998086617962,28.6842020071901302],"luv":[68.9599197258043688,95.4557990826346554,52.2263198599069725],"rgb":[1,0.533333333333333326,0.266666666666666663],"xyz":[0.510861307646994556,0.392887591249936219,0.103622651608907351],"hpluv":[28.6842020071901302,200.2199693629492,68.9599197258043688],"hsluv":[28.6842020071901302,100.000000000000838,68.9599197258043688]},"#ff8855":{"lch":[69.1314852187197602,104.012526361958052,26.1137258191789492],"luv":[69.1314852187197602,93.395152113439849,45.7815596272609682],"rgb":[1,0.533333333333333326,0.333333333333333315],"xyz":[0.516823721686356485,0.39527255686568108,0.135024698882881267],"hpluv":[26.1137258191789492,190.918970683811096,69.1314852187197602],"hsluv":[26.1137258191789492,100.000000000000867,69.1314852187197602]},"#ff8866":{"lch":[69.3487452092138881,98.4723154092605171,22.6389332988698087],"luv":[69.3487452092138881,90.8849122177262529,37.9042165627661802],"rgb":[1,0.533333333333333326,0.4],"xyz":[0.524408717459864726,0.398306555175084398,0.174972343290025228],"hpluv":[22.6389332988698087,180.183437843423292,69.3487452092138881],"hsluv":[22.6389332988698087,100.000000000001066,69.3487452092138881]},"#ff8877":{"lch":[69.6140261744794344,92.5206854303452246,18.0637242730473773],"luv":[69.6140261744794344,87.9605480867009248,28.6883114314535526],"rgb":[1,0.533333333333333326,0.466666666666666674],"xyz":[0.533722730480066576,0.402032160383165194,0.224026145196423138],"hpluv":[18.0637242730473773,168.648085666048672,69.6140261744794344],"hsluv":[18.0637242730473773,100.000000000001108,69.6140261744794344]},"#ff8888":{"lch":[69.9291829132988596,86.6211090413054,12.1770506300619186],"luv":[69.9291829132988596,84.672173963834382,18.2712749359175248],"rgb":[1,0.533333333333333326,0.533333333333333326],"xyz":[0.544863147582010487,0.406488327223942791,0.282699008599995305],"hpluv":[12.1770506300619186,157.182652238587849,69.9291829132988596],"hsluv":[12.1770506300619186,100.000000000001251,69.9291829132988596]},"#ff8899":{"lch":[70.29563969089034,81.3665448969888274,4.80888772903122597],"luv":[70.29563969089034,81.0801238487794791,6.82115423812421362],"rgb":[1,0.533333333333333326,0.6],"xyz":[0.557920111691083132,0.411711112867571949,0.351465686241113184],"hpluv":[4.80888772903122597,146.878021536398364,70.29563969089034],"hsluv":[4.80888772903122597,100.00000000000135,70.29563969089034]},"#ff88aa":{"lch":[70.7144212664750427,77.4442353273614827,355.944797831634332],"luv":[70.7144212664750427,77.2503443699940533,-5.47666688388778589],"rgb":[1,0.533333333333333326,0.66666666666666663],"xyz":[0.572977804656335743,0.417734190053673071,0.430769535858111841],"hpluv":[355.944797831634332,138.969799542374091,70.7144212664750427],"hsluv":[355.944797831634332,100.000000000001648,70.7144212664750427]},"#ff88bb":{"lch":[71.1861792611668847,75.5334875912487718,345.875835641341098],"luv":[71.1861792611668847,73.2500487000805,-18.431986141845023],"rgb":[1,0.533333333333333326,0.733333333333333282],"xyz":[0.590115396763672306,0.42458922689660783,0.521027520956753532],"hpluv":[345.875835641341098,134.642814203514433,71.1861792611668847],"hsluv":[345.875835641341098,100.000000000001776,71.1861792611668847]},"#ff88cc":{"lch":[71.711216864189268,76.1313589407537563,335.260476444218114],"luv":[71.711216864189268,69.1440007334156377,-31.8604924121286039],"rgb":[1,0.533333333333333326,0.8],"xyz":[0.609407772207394061,0.432306177074096631,0.622634031627023687],"hpluv":[335.260476444218114,134.714956877670915,71.711216864189268],"hsluv":[335.260476444218114,100.000000000001933,71.711216864189268]},"#ff88dd":{"lch":[72.2895135005839649,79.3885839073469413,324.950129439258774],"luv":[72.2895135005839649,64.9916618916399784,-45.5920074067441803],"rgb":[1,0.533333333333333326,0.866666666666666696],"xyz":[0.63092609775802766,0.440913507294350138,0.735963879527029685],"hpluv":[324.950129439258774,139.354847315526115,72.2895135005839649],"hsluv":[324.950129439258774,100.000000000002245,72.2895135005839649]},"#ff88ee":{"lch":[72.9207502525545124,85.0855243828499,315.651995307064169],"luv":[72.9207502525545124,60.845281511842515,-59.4760302748021203],"rgb":[1,0.533333333333333326,0.933333333333333348],"xyz":[0.654738278024202369,0.450438379400820155,0.861374695595552908],"hpluv":[315.651995307064169,148.062090862911901,72.9207502525545124],"hsluv":[315.651995307064169,100.000000000002444,72.9207502525545124]},"#ff88ff":{"lch":[73.6043362991539709,92.7672005781522842,307.715012949244624],"luv":[73.6043362991539709,56.7488822053271349,-73.3847250560567375],"rgb":[1,0.533333333333333326,1],"xyz":[0.68090932643403379,0.460906798764752879,0.999208883887334753],"hpluv":[307.715012949244624,159.930161835956909,73.6043362991539709],"hsluv":[307.715012949244624,100.000000000002771,73.6043362991539709]},"#ff9900":{"lch":[72.2588108283115389,109.907462524380705,39.4434130396340095],"luv":[72.2588108283115389,84.8763034831777077,69.8259509464759418],"rgb":[1,0.6,0],"xyz":[0.526298138484671219,0.440453684308955595,0.057299931788497],"hpluv":[39.4434130396340095,193.008172097547572,72.2588108283115389],"hsluv":[39.4434130396340095,100.000000000002288,72.2588108283115389]},"#ff9911":{"lch":[72.2858317740783889,108.970035258541955,39.0927051304156805],"luv":[72.2858317740783889,84.5745536570817791,68.7139975401902348],"rgb":[1,0.6,0.0666666666666666657],"xyz":[0.527309803984308378,0.440858350508810448,0.0626280367532526389],"hpluv":[39.0927051304156805,191.2904264008464,72.2858317740783889],"hsluv":[39.0927051304156805,100.000000000001506,72.2858317740783889]},"#ff9922":{"lch":[72.3358777005795304,107.257428554778556,38.4317580680427469],"luv":[72.3358777005795304,84.0200042697796,66.6692947517044274],"rgb":[1,0.6,0.133333333333333331],"xyz":[0.529185162122785324,0.441608493764201249,0.0725049229492318315],"hpluv":[38.4317580680427469,188.15378179700545,72.3358777005795304],"hsluv":[38.4317580680427469,100.00000000000145,72.3358777005795304]},"#ff9933":{"lch":[72.418154282067718,104.508625212907305,37.3122251519614778],"luv":[72.418154282067718,83.1203251002183237,63.3487513620113845],"rgb":[1,0.6,0.2],"xyz":[0.532272912855243141,0.442843594057184375,0.0887670768068429816],"hpluv":[37.3122251519614778,183.123470124205028,72.418154282067718],"hsluv":[37.3122251519614778,100.00000000000162,72.418154282067718]},"#ff9944":{"lch":[72.5366731246789556,100.695423976150749,35.6250099256014607],"luv":[72.5366731246789556,81.8499313718691326,58.6528528219818952],"rgb":[1,0.6,0.266666666666666663],"xyz":[0.536730908099462,0.444626792154871942,0.11224585175972962],"hpluv":[35.6250099256014607,176.153561585765658,72.5366731246789556],"hsluv":[35.6250099256014607,100.000000000001748,72.5366731246789556]},"#ff9955":{"lch":[72.6946936633514582,95.8821930466240673,33.2320443565807508],"luv":[72.6946936633514582,80.201421842029859,52.5464259293328269],"rgb":[1,0.6,0.333333333333333315],"xyz":[0.54269332213882393,0.447011757770616802,0.143647899033703508],"hpluv":[33.2320443565807508,167.368827825995851,72.6946936633514582],"hsluv":[33.2320443565807508,100.000000000001705,72.6946936633514582]},"#ff9966":{"lch":[72.8949069034106,90.2347392462793749,29.9516480142673025],"luv":[72.8949069034106,78.1836232693519406,45.0514064077924345],"rgb":[1,0.6,0.4],"xyz":[0.550278317912332171,0.450045756080020121,0.183595543440847497],"hpluv":[29.9516480142673025,157.078197331028889,72.8949069034106],"hsluv":[29.9516480142673025,100.000000000001819,72.8949069034106]},"#ff9977":{"lch":[73.1395321193821,84.0351966301436,25.5464816978182121],"luv":[73.1395321193821,75.8195571045914,36.2396058633438045],"rgb":[1,0.6,0.466666666666666674],"xyz":[0.559592330932534,0.453771361288100916,0.232649345347245406],"hpluv":[25.5464816978182121,145.796926659053128,73.1395321193821],"hsluv":[25.5464816978182121,100.000000000002018,73.1395321193821]},"#ff9988":{"lch":[73.430374185650777,77.702838567593929,19.7240568661095921],"luv":[73.430374185650777,73.1439295084068419,26.2239718107454713],"rgb":[1,0.6,0.533333333333333326],"xyz":[0.570732748034477932,0.458227528128878514,0.291322208750817546],"hpluv":[19.7240568661095921,134.276641294628575,73.430374185650777],"hsluv":[19.7240568661095921,100.000000000002203,73.430374185650777]},"#ff9999":{"lch":[73.76886125649402,71.8160022700114098,12.1770506300620251],"luv":[73.76886125649402,70.2001752793754,15.1483851545719261],"rgb":[1,0.6,0.6],"xyz":[0.583789712143550577,0.463450313772507672,0.360088886391935481],"hpluv":[12.1770506300620251,123.534275619879125,73.76886125649402],"hsluv":[12.1770506300620251,100.000000000002331,73.76886125649402]},"#ff99aa":{"lch":[74.1560723225582592,67.1124973440613,2.7130535693684088],"luv":[74.1560723225582592,67.0372720786985923,3.17670458229478481],"rgb":[1,0.6,0.66666666666666663],"xyz":[0.598847405108803188,0.469473390958608794,0.439392736008934082],"hpluv":[2.7130535693684088,114.840746523486033,74.1560723225582592],"hsluv":[2.7130535693684088,100.00000000000253,74.1560723225582592]},"#ff99bb":{"lch":[74.5927597146433925,64.4136927281220864,351.502648062184],"luv":[74.5927597146433925,63.7066038913843187,-9.51800564715024322],"rgb":[1,0.6,0.733333333333333282],"xyz":[0.615984997216139751,0.476328427801543552,0.529650721107575828],"hpluv":[351.502648062184,109.577363966618833,74.5927597146433925],"hsluv":[351.502648062184,100.000000000002615,74.5927597146433925]},"#ff99cc":{"lch":[75.0793694015197,64.4152606478183145,339.305696269483292],"luv":[75.0793694015197,60.259134450288677,-22.7631834247409977],"rgb":[1,0.6,0.8],"xyz":[0.635277372659861506,0.484045377979032354,0.631257231777846],"hpluv":[339.305696269483292,108.869813431806975,75.0793694015197],"hsluv":[339.305696269483292,100.000000000002871,75.0793694015197]},"#ff99dd":{"lch":[75.6160606971696296,67.4118390527965232,327.324068761847229],"luv":[75.6160606971696296,56.7430830794555,-36.3947601601954887],"rgb":[1,0.6,0.866666666666666696],"xyz":[0.656795698210495105,0.49265270819928586,0.744587079677852],"hpluv":[327.324068761847229,113.125745227459021,75.6160606971696296],"hsluv":[327.324068761847229,100.00000000000324,75.6160606971696296]},"#ff99ee":{"lch":[76.202726253448489,73.1905233351813393,316.627151984536795],"luv":[76.202726253448489,53.2022056350908201,-50.2630880631028845],"rgb":[1,0.6,0.933333333333333348],"xyz":[0.680607878476669814,0.502177580305755877,0.869997895746375205],"hpluv":[316.627151984536795,123.107716827744753,76.202726253448489],"hsluv":[316.627151984536795,100.000000000003524,76.202726253448489]},"#ff99ff":{"lch":[76.8390127436129,81.2030526869262275,307.715012949245],"luv":[76.8390127436129,49.6746958291708154,-64.2367524082209229],"rgb":[1,0.6,1],"xyz":[0.706778926886501235,0.512645999669688601,1.00783208403815694],"hpluv":[307.715012949245,141.150312559224801,76.8390127436129],"hsluv":[307.715012949245,100.000000000003752,76.8390127436129]},"#ee0000":{"lch":[49.7142799595632,167.190689697178925,12.1770506300617765],"luv":[49.7142799595632,163.428976145092918,35.2660811203203934],"rgb":[0.933333333333333348,0,0],"xyz":[0.352591085030832,0.181804778219026603,0.0165277071108199],"hpluv":[12.1770506300617765,426.746789183125202,49.7142799595632],"hsluv":[12.1770506300617765,100.000000000002217,49.7142799595632]},"#ee0011":{"lch":[49.7630000621001756,165.722449822455,11.6881730851639158],"luv":[49.7630000621001756,162.286136628676445,33.5729092170260728],"rgb":[0.933333333333333348,0,0.0666666666666666657],"xyz":[0.353602750530469079,0.182209444418881455,0.0218558120755755342],"hpluv":[11.6881730851639158,422.585038037937124,49.7630000621001756],"hsluv":[11.6881730851639158,99.9999999999963762,49.7630000621001756]},"#ee0022":{"lch":[49.8531236873270558,163.0858535413212,10.7756858750078184],"luv":[49.8531236873270558,160.210108449799208,30.4912573667411486],"rgb":[0.933333333333333348,0,0.133333333333333331],"xyz":[0.355478108668946136,0.182959587674272284,0.0317326982715547268],"hpluv":[10.7756858750078184,415.110044299310516,49.8531236873270558],"hsluv":[10.7756858750078184,99.9999999999964473,49.8531236873270558]},"#ee0033":{"lch":[50.000975779064234,158.977402767524836,9.25647316775448559],"luv":[50.000975779064234,156.907230803998146,25.5721628363475],"rgb":[0.933333333333333348,0,0.2],"xyz":[0.358565859401403841,0.184194687967255383,0.047994852129165877],"hpluv":[9.25647316775448559,403.456061197389261,50.000975779064234],"hsluv":[9.25647316775448559,99.9999999999965183,50.000975779064234]},"#ee0044":{"lch":[50.2132784041556164,153.529579514286212,7.02933300215353],"luv":[50.2132784041556164,152.375594335021788,18.7885613308314312],"rgb":[0.933333333333333348,0,0.266666666666666663],"xyz":[0.363023854645622757,0.185977886064942977,0.0714736270820525155],"hpluv":[7.02933300215353,387.983100931209492,50.2132784041556164],"hsluv":[7.02933300215353,99.9999999999966462,50.2132784041556164]},"#ee0055":{"lch":[50.4951150037793326,147.071833727726926,3.99754465361350508],"luv":[50.4951150037793326,146.714013644902735,10.2529252527975352],"rgb":[0.933333333333333348,0,0.333333333333333315],"xyz":[0.368986268684984742,0.188362851680687809,0.102875674356026417],"hpluv":[3.99754465361350508,369.589367027053072,50.4951150037793326],"hsluv":[3.99754465361350508,99.999999999996831,50.4951150037793326]},"#ee0066":{"lch":[50.8502318550204109,140.098840030056522,0.0757634158231174915],"luv":[50.8502318550204109,140.0987175463531,0.185255592479522613],"rgb":[0.933333333333333348,0,0.4],"xyz":[0.376571264458492927,0.1913968499900911,0.142823318763170393],"hpluv":[0.0757634158231174915,349.60765112382461,50.8502318550204109],"hsluv":[0.0757634158231174915,99.9999999999970584,50.8502318550204109]},"#ee0077":{"lch":[51.2812017254514956,133.219993530026585,355.209470699020642],"luv":[51.2812017254514956,132.754613083251769,-11.1256182415379214],"rgb":[0.933333333333333348,0,0.466666666666666674],"xyz":[0.385885277478694833,0.195122455198171924,0.191877120669568302],"hpluv":[355.209470699020642,329.648072606093592,51.2812017254514956],"hsluv":[355.209470699020642,99.9999999999973284,51.2812017254514956]},"#ee0088":{"lch":[51.7895361854883163,127.090944021268115,349.407446028193533],"luv":[51.7895361854883163,124.925218603260163,-23.3623160055840167],"rgb":[0.933333333333333348,0,0.533333333333333326],"xyz":[0.397025694580638633,0.199578622038949521,0.250549984073140442],"hpluv":[349.407446028193533,311.395197619459395,51.7895361854883163],"hsluv":[349.407446028193533,99.9999999999974705,51.7895361854883163]},"#ee0099":{"lch":[52.3757812732210652,122.329563392952366,342.780178840499048],"luv":[52.3757812732210652,116.846263825073436,-36.2142611415956637],"rgb":[0.933333333333333348,0,0.6],"xyz":[0.410082658689711388,0.204801407682578679,0.319316661714258376],"hpluv":[342.780178840499048,296.374093031221,52.3757812732210652],"hsluv":[342.780178840499048,99.9999999999978,52.3757812732210652]},"#ee00aa":{"lch":[53.0396114453995722,119.424239873739239,335.563712743666827],"luv":[53.0396114453995722,108.726436909364494,-49.403552366347],"rgb":[0.933333333333333348,0,0.66666666666666663],"xyz":[0.425140351654963888,0.210824484868679773,0.398620511331257],"hpluv":[335.563712743666827,285.713971708863653,53.0396114453995722],"hsluv":[335.563712743666827,99.999999999998,53.0396114453995722]},"#ee00bb":{"lch":[53.779927529436435,118.655378520732356,328.101249142938343],"luv":[53.779927529436435,100.736423933687789,-62.6998544252744381],"rgb":[0.933333333333333348,0,0.733333333333333282],"xyz":[0.442277943762300563,0.217679521711614532,0.488878496429898723],"hpluv":[328.101249142938343,279.966806180862307,53.779927529436435],"hsluv":[328.101249142938343,99.9999999999982094,53.779927529436435]},"#ee00cc":{"lch":[54.5949595671901,120.061129768120921,320.773339602207614],"luv":[54.5949595671901,93.0053918954961,-75.9254368414351575],"rgb":[0.933333333333333348,0,0.8],"xyz":[0.461570319206022317,0.225396471889103334,0.590485007100168824],"hpluv":[320.773339602207614,279.054611328209262,54.5949595671901],"hsluv":[320.773339602207614,99.9999999999984,54.5949595671901]},"#ee00dd":{"lch":[55.4823728661035744,123.466264594666441,313.907226483092529],"luv":[55.4823728661035744,85.6229535549924634,-88.9529556421808252],"rgb":[0.933333333333333348,0,0.866666666666666696],"xyz":[0.483088644756655805,0.234003802109356868,0.703814855000174822],"hpluv":[313.907226483092529,282.379138449157608,55.4823728661035744],"hsluv":[313.907226483092529,99.9999999999986215,55.4823728661035744]},"#ee00ee":{"lch":[56.4393743497109597,128.559742977308588,307.715012949243601],"luv":[56.4393743497109597,78.644409501394918,-101.698890694877051],"rgb":[0.933333333333333348,0,0.933333333333333348],"xyz":[0.506900825022830626,0.243528674215826912,0.829225671068698],"hpluv":[307.715012949243601,289.042783730483393,56.4393743497109597],"hsluv":[307.715012949243601,99.9999999999988489,56.4393743497109597]},"#ee00ff":{"lch":[57.4628159598150745,134.982567880189606,302.284502363601803],"luv":[57.4628159598150745,72.0973885084188879,-114.115118199983058],"rgb":[0.933333333333333348,0,1],"xyz":[0.533071873432661936,0.253997093579759636,0.96705985936047989],"hpluv":[302.284502363601803,298.078126285043766,57.4628159598150745],"hsluv":[302.284502363601803,99.9999999999989484,57.4628159598150745]},"#ee1100":{"lch":[50.1937733395544683,164.746074066243921,12.6667024036514828],"luv":[50.1937733395544683,160.736507742479517,36.1253927174799117],"rgb":[0.933333333333333348,0.0666666666666666657,0],"xyz":[0.354595485291760382,0.185813578740883473,0.0171958405311293527],"hpluv":[12.6667024036514828,416.489977947977081,50.1937733395544683],"hsluv":[12.6667024036514828,100.000000000002245,50.1937733395544683]},"#ee1111":{"lch":[50.2417909300708345,163.305921695383518,12.1770506300617907],"luv":[50.2417909300708345,159.631613634988071,34.4466542507197317],"rgb":[0.933333333333333348,0.0666666666666666657,0.0666666666666666657],"xyz":[0.355607150791397486,0.186218244940738326,0.0225239454958849825],"hpluv":[12.1770506300617907,412.454596338970589,50.2417909300708345],"hsluv":[12.1770506300617907,96.6508962208003197,50.2417909300708345]},"#ee1122":{"lch":[50.3306190654122219,160.718934991358793,11.2629010575952293],"luv":[50.3306190654122219,157.623701713525833,31.390201064696047],"rgb":[0.933333333333333348,0.0666666666666666657,0.133333333333333331],"xyz":[0.357482508929874543,0.186968388196129154,0.032400831691864182],"hpluv":[11.2629010575952293,405.204351077732667,50.3306190654122219],"hsluv":[11.2629010575952293,96.6948337079543592,50.3306190654122219]},"#ee1133":{"lch":[50.4763571232054318,156.685700791802191,9.74029685215880647],"luv":[50.4763571232054318,154.427033260746356,26.5084935615454427],"rgb":[0.933333333333333348,0.0666666666666666657,0.2],"xyz":[0.360570259662332249,0.188203488489112253,0.0486629855494753252],"hpluv":[9.74029685215880647,393.895198182016713,50.4763571232054318],"hsluv":[9.74029685215880647,96.7647175585846,50.4763571232054318]},"#ee1144":{"lch":[50.6856484752898382,151.333831494518165,7.50679337730589413],"luv":[50.6856484752898382,150.036806479185287,19.7708183022028514],"rgb":[0.933333333333333348,0.0666666666666666657,0.266666666666666663],"xyz":[0.365028254906551164,0.189986686586799847,0.0721417605023619568],"hpluv":[7.50679337730589413,378.870112575267399,50.6856484752898382],"hsluv":[7.50679337730589413,96.8605546889772455,50.6856484752898382]},"#ee1155":{"lch":[50.9635312364098496,144.984673036864649,4.46374659640210858],"luv":[50.9635312364098496,144.544902405536135,11.283909082431693],"rgb":[0.933333333333333348,0.0666666666666666657,0.333333333333333315],"xyz":[0.370990668945913149,0.19237165220254468,0.103543807776335872],"hpluv":[4.46374659640210858,360.995599227985224,50.9635312364098496],"hsluv":[4.46374659640210858,96.9801964566503,50.9635312364098496]},"#ee1166":{"lch":[51.3137360134299598,138.123816003378664,0.523151936541392],"luv":[51.3137360134299598,138.118058344046318,1.26115288756691357],"rgb":[0.933333333333333348,0.0666666666666666657,0.4],"xyz":[0.378575664719421334,0.19540565051194797,0.143491452183479834],"hpluv":[0.523151936541392,341.565705345826359,51.3137360134299598],"hsluv":[0.523151936541392,97.1198273857598764,51.3137360134299598]},"#ee1177":{"lch":[51.7388469835676119,131.353183798903302,355.627348241097309],"luv":[51.7388469835676119,130.970848560864681,-10.014775152519368],"rgb":[0.933333333333333348,0.0666666666666666657,0.466666666666666674],"xyz":[0.38788967773962324,0.199131255720028794,0.192545254089877743],"hpluv":[355.627348241097309,322.153744971780554,51.7388469835676119],"hsluv":[355.627348241097309,97.2745732157476,51.7388469835676119]},"#ee1188":{"lch":[52.2404115410600411,125.324707533591734,349.782339698165117],"luv":[52.2404115410600411,123.337180279157977,-22.2311106147846438],"rgb":[0.933333333333333348,0.0666666666666666657,0.533333333333333326],"xyz":[0.39903009484156704,0.203587422560806391,0.251218117493449911],"hpluv":[349.782339698165117,304.417375015566734,52.2404115410600411],"hsluv":[349.782339698165117,97.4391430985313605,52.2404115410600411]},"#ee1199":{"lch":[52.819032808459994,120.657103381490217,343.097768544337384],"luv":[52.819032808459994,115.44498939014953,-35.079780802050081],"rgb":[0.933333333333333348,0.0666666666666666657,0.6],"xyz":[0.412087058950639795,0.208810208204435549,0.31998479513456779],"hpluv":[343.097768544337384,289.869003225703352,52.819032808459994],"hsluv":[343.097768544337384,97.6083995478766298,52.819032808459994]},"#ee11aa":{"lch":[53.4744599034404615,117.843047501566133,335.812437212199143],"luv":[53.4744599034404615,107.497497568615216,-48.2832461723726496],"rgb":[0.933333333333333348,0.0666666666666666657,0.66666666666666663],"xyz":[0.427144751915892296,0.214833285390536644,0.399288644751566446],"hpluv":[335.812437212199143,279.638449078323276,53.4744599034404615],"hsluv":[335.812437212199143,97.7777799659692,53.4744599034404615]},"#ee11bb":{"lch":[54.205681814132376,117.167943285093472,328.276238054291071],"luv":[54.205681814132376,99.6622453247977376,-61.6097702517929662],"rgb":[0.933333333333333348,0.0666666666666666657,0.733333333333333282],"xyz":[0.44428234402322897,0.221688322233471402,0.489546629850208137],"hpluv":[328.276238054291071,274.285798241860448,54.205681814132376],"hsluv":[328.276238054291071,97.9435422525978652,54.205681814132376]},"#ee11cc":{"lch":[55.0110259993956703,118.672848043699901,320.878255441103249],"luv":[55.0110259993956703,92.0672263164348266,-74.8790404666182781],"rgb":[0.933333333333333348,0.0666666666666666657,0.8],"xyz":[0.463574719466950724,0.229405272410960204,0.591153140520478293],"hpluv":[320.878255441103249,273.741691636115945,55.0110259993956703],"hsluv":[320.878255441103249,98.102849778989,55.0110259993956703]},"#ee11dd":{"lch":[55.8882602794840864,122.182226882396691,313.952719233652829],"luv":[55.8882602794840864,84.8023500190691522,-87.9605479586430334],"rgb":[0.933333333333333348,0.0666666666666666657,0.866666666666666696],"xyz":[0.485093045017584212,0.238012602631213738,0.704482988420484291],"hpluv":[313.952719233652829,277.412976370396279,55.8882602794840864],"hsluv":[313.952719233652829,98.2537358693348608,55.8882602794840864]},"#ee11ee":{"lch":[56.83469533821048,127.382376320214306,307.715012949243601],"luv":[56.83469533821048,77.9241738866570302,-100.767519176899128],"rgb":[0.933333333333333348,0.0666666666666666657,0.933333333333333348],"xyz":[0.508905225283758922,0.247537474737683783,0.829893804489007514],"hpluv":[307.715012949243601,284.403630900032795,56.83469533821048],"hsluv":[307.715012949243601,98.3949944120453495,56.83469533821048]},"#ee11ff":{"lch":[57.8472847680859275,133.910906422249354,302.2526850652647],"luv":[57.8472847680859275,71.4621107907268254,-113.248830369952643],"rgb":[0.933333333333333348,0.0666666666666666657,1],"xyz":[0.535076273693590343,0.258005894101616451,0.967727992780789359],"hpluv":[302.2526850652647,293.746227206253536,57.8472847680859275],"hsluv":[302.2526850652647,99.99999999999892,57.8472847680859275]},"#ee2200":{"lch":[51.0646940471157222,160.407609402057773,13.5847947923325787],"luv":[51.0646940471157222,155.919944837816502,37.677207378671163],"rgb":[0.933333333333333348,0.133333333333333331,0],"xyz":[0.358311109026528296,0.19324482621041944,0.018434381776051962],"hpluv":[13.5847947923325787,398.605749597291435,51.0646940471157222],"hsluv":[13.5847947923325787,100.000000000002203,51.0646940471157222]},"#ee2211":{"lch":[51.1114738997186322,159.015005648229618,13.0939108674416342],"luv":[51.1114738997186322,154.880623331235768,36.0244991337056817],"rgb":[0.933333333333333348,0.133333333333333331,0.0666666666666666657],"xyz":[0.3593227745261654,0.193649492410274293,0.0237624867408075952],"hpluv":[13.0939108674416342,394.783534202752207,51.1114738997186322],"hsluv":[13.0939108674416342,96.7702863870018462,51.1114738997186322]},"#ee2222":{"lch":[51.1980191888258105,156.511980987808,12.1770506300618031],"luv":[51.1980191888258105,152.990533465747774,33.0135860305098348],"rgb":[0.933333333333333348,0.133333333333333331,0.133333333333333331],"xyz":[0.361198132664642457,0.194399635665665121,0.0336393729367867877],"hpluv":[12.1770506300618031,387.912483642854795,51.1980191888258105],"hsluv":[12.1770506300618031,90.899918517349,51.1980191888258105]},"#ee2233":{"lch":[51.340031013958,152.605977320930094,10.6487510890373542],"luv":[51.340031013958,149.977869701108148,28.1996970549978769],"rgb":[0.933333333333333348,0.133333333333333331,0.2],"xyz":[0.364285883397100163,0.19563473595864822,0.0499015267943979379],"hpluv":[10.6487510890373542,377.185287566809563,51.340031013958],"hsluv":[10.6487510890373542,91.0856949770771,51.340031013958]},"#ee2244":{"lch":[51.5440125284501391,147.416232714385046,8.4042516634418849],"luv":[51.5440125284501391,145.833202035739902,21.5458314229178391],"rgb":[0.933333333333333348,0.133333333333333331,0.266666666666666663],"xyz":[0.368743878641319078,0.197417934056335814,0.0733803017472845764],"hpluv":[8.4042516634418849,362.916246958463432,51.5440125284501391],"hsluv":[8.4042516634418849,91.3409150161676848,51.5440125284501391]},"#ee2255":{"lch":[51.8149196409757,141.25016266814734,5.34127242035781613],"luv":[51.8149196409757,140.636840571385164,13.1486701942394504],"rgb":[0.933333333333333348,0.133333333333333331,0.333333333333333315],"xyz":[0.374706292680681063,0.199802899672080647,0.104782349021258478],"hpluv":[5.34127242035781613,345.918233291596209,51.8149196409757],"hsluv":[5.34127242035781613,91.6602615743055082,51.8149196409757]},"#ee2266":{"lch":[52.1564522427987924,134.577740656965489,1.36671179444129165],"luv":[52.1564522427987924,134.539455426625494,3.20986196595936],"rgb":[0.933333333333333348,0.133333333333333331,0.4],"xyz":[0.382291288454189249,0.202836897981483938,0.144729993428402454],"hpluv":[1.36671179444129165,327.419481975304109,52.1564522427987924],"hsluv":[1.36671179444129165,92.0339967122243365,52.1564522427987924]},"#ee2277":{"lch":[52.5712108639856694,127.988129961564283,356.416786702014292],"luv":[52.5712108639856694,127.737923683219179,-7.99901644943552803],"rgb":[0.933333333333333348,0.133333333333333331,0.466666666666666674],"xyz":[0.391605301474391154,0.206562503189564761,0.193783795334800363],"hpluv":[356.416786702014292,308.930679724572485,52.5712108639856694],"hsluv":[356.416786702014292,92.4494947830095,52.5712108639856694]},"#ee2288":{"lch":[53.0608018273771194,122.127216672078461,350.491948161024197],"luv":[53.0608018273771194,120.449481512132621,-20.1737318195523763],"rgb":[0.933333333333333348,0.133333333333333331,0.533333333333333326],"xyz":[0.402745718576334955,0.211018670030342359,0.25245665873837253],"hpluv":[350.491948161024197,292.063965437042782,53.0608018273771194],"hsluv":[350.491948161024197,92.892885362452958,53.0608018273771194]},"#ee2299":{"lch":[53.6259244704506557,117.615935516390621,343.699890485995525],"luv":[53.6259244704506557,112.888334232708232,-33.0110933105844282],"rgb":[0.933333333333333348,0.133333333333333331,0.6],"xyz":[0.415802682685407654,0.216241455673971517,0.32122333637949041],"hpluv":[343.699890485995525,278.311211390643507,53.6259244704506557],"hsluv":[343.699890485995525,93.3505397228777412,53.6259244704506557]},"#ee22aa":{"lch":[54.266455218013121,114.955451111725907,336.284451026203612],"luv":[54.266455218013121,105.247863162980167,-46.2346519390706305],"rgb":[0.933333333333333348,0.133333333333333331,0.66666666666666663],"xyz":[0.43086037565066021,0.222264532860072611,0.400527185996489],"hpluv":[336.284451026203612,268.805062052359688,54.266455218013121],"hsluv":[336.284451026203612,93.8102001508292,54.266455218013121]},"#ee22bb":{"lch":[54.981534566577821,114.440827463928798,328.608334651454868],"luv":[54.981534566577821,97.6897319326175,-59.6105633722921],"rgb":[0.933333333333333348,0.133333333333333331,0.733333333333333282],"xyz":[0.447997967757996884,0.22911956970300737,0.490785171095130757],"hpluv":[328.608334651454868,264.121319791368,54.981534566577821],"hsluv":[328.608334651454868,94.2616688954678636,54.981534566577821]},"#ee22cc":{"lch":[55.7696584616915629,116.118636638570607,321.077185717181408],"luv":[55.7696584616915629,90.3394913251054419,-72.9541916679335856],"rgb":[0.933333333333333348,0.133333333333333331,0.8],"xyz":[0.467290343201718583,0.236836519880496171,0.592391681765400913],"hpluv":[321.077185717181408,264.206361207665168,55.7696584616915629],"hsluv":[321.077185717181408,94.6970823725699518,55.7696584616915629]},"#ee22dd":{"lch":[56.6287730491083749,119.812596042269817,314.038835862099],"luv":[56.6287730491083749,83.2872216309056,-86.1295354880806201],"rgb":[0.933333333333333348,0.133333333333333331,0.866666666666666696],"xyz":[0.488808668752352182,0.245443850100749705,0.70572152966540691],"hpluv":[314.038835862099,268.475495638829329,56.6287730491083749],"hsluv":[314.038835862099,95.1108639535381,56.6287730491083749]},"#ee22ee":{"lch":[57.5563705104872128,125.203701850491953,307.715012949243658],"luv":[57.5563705104872128,76.5914038981754,-99.0440498261932163],"rgb":[0.933333333333333348,0.133333333333333331,0.933333333333333348],"xyz":[0.512620849018526892,0.254968722207219722,0.831132345733930133],"hpluv":[307.715012949243658,276.03432908057755,57.5563705104872128],"hsluv":[307.715012949243658,95.4994708803944263,57.5563705104872128]},"#ee22ff":{"lch":[58.5495832280214046,131.922896299071255,302.192710378625122],"luv":[58.5495832280214046,70.2843784028787582,-111.641196341030223],"rgb":[0.933333333333333348,0.133333333333333331,1],"xyz":[0.538791897428358313,0.265437141571152446,0.968966534025712],"hpluv":[302.192710378625122,285.914180736870946,58.5495832280214046],"hsluv":[302.192710378625122,99.9999999999989,58.5495832280214046]},"#ee3300":{"lch":[52.4512471844783761,153.77210005382733,15.1254552240259841],"luv":[52.4512471844783761,148.444942331914945,40.1242800687903269],"rgb":[0.933333333333333348,0.2,0],"xyz":[0.364428831115539142,0.205480270388441244,0.0204736224723888437],"hpluv":[15.1254552240259841,372.015515114283232,52.4512471844783761],"hsluv":[15.1254552240259841,100.000000000002174,52.4512471844783761]},"#ee3311":{"lch":[52.4961529429458693,152.446596739109111,14.6331501802662043],"luv":[52.4961529429458693,147.501711829562538,38.5124637576621893],"rgb":[0.933333333333333348,0.2,0.0666666666666666657],"xyz":[0.365440496615176247,0.205884936588296097,0.0258017274371444769],"hpluv":[14.6331501802662043,368.493287978140756,52.4961529429458693],"hsluv":[14.6331501802662043,96.9493433827183395,52.4961529429458693]},"#ee3322":{"lch":[52.5792408568970302,150.061966488521733,13.7129404445972121],"luv":[52.5792408568970302,145.784540850223095,35.5733247742160685],"rgb":[0.933333333333333348,0.2,0.133333333333333331],"xyz":[0.367315854753653304,0.206635079843686925,0.0356786136331236695],"hpluv":[13.7129404445972121,362.155969729293304,52.5792408568970302],"hsluv":[13.7129404445972121,91.3983957113456,52.5792408568970302]},"#ee3333":{"lch":[52.7156069212027916,146.335083442311,12.177050630061796],"luv":[52.7156069212027916,143.042611430097821,30.8669396171076365],"rgb":[0.933333333333333348,0.2,0.2],"xyz":[0.370403605486111,0.207870180136670024,0.0519407674907348127],"hpluv":[12.177050630061796,352.248031751653059,52.7156069212027916],"hsluv":[12.177050630061796,82.5426319963487316,52.7156069212027916]},"#ee3344":{"lch":[52.9115382124740705,141.372894204534333,9.91688783885485314],"luv":[52.9115382124740705,139.260586308771792,24.3471623953096028],"rgb":[0.933333333333333348,0.2,0.266666666666666663],"xyz":[0.374861600730329925,0.209653378234357618,0.0754195424436214512],"hpluv":[9.91688783885485314,339.043238938553714,52.9115382124740705],"hsluv":[9.91688783885485314,83.0163224279527867,52.9115382124740705]},"#ee3355":{"lch":[53.1718605143623222,135.462446214194244,6.82400118051175664],"luv":[53.1718605143623222,134.502806079917804,16.0956357737583851],"rgb":[0.933333333333333348,0.2,0.333333333333333315],"xyz":[0.38082401476969191,0.212038343850102451,0.106821589717595367],"hpluv":[6.82400118051175664,323.278173463789,53.1718605143623222],"hsluv":[6.82400118051175664,83.6110915378108,53.1718605143623222]},"#ee3366":{"lch":[53.5002196972096158,129.050901787066266,2.79642975700151464],"luv":[53.5002196972096158,128.89722530875369,6.29607494868134765],"rgb":[0.933333333333333348,0.2,0.4],"xyz":[0.388409010543200095,0.215072342159505742,0.146769234124739328],"hpluv":[2.79642975700151464,306.086943567777439,53.5002196972096158],"hsluv":[2.79642975700151464,84.310080928774866,53.5002196972096158]},"#ee3377":{"lch":[53.8992319384372252,122.709031404530748,357.759441587930837],"luv":[53.8992319384372252,122.615219389586755,-4.79732866099687261],"rgb":[0.933333333333333348,0.2,0.466666666666666674],"xyz":[0.397723023563402,0.218797947367586565,0.195823036031137238],"hpluv":[357.759441587930837,288.89051161323988,53.8992319384372252],"hsluv":[357.759441587930837,85.0909052409050872,53.8992319384372252]},"#ee3388":{"lch":[54.3705825415329,117.074862235921088,351.703100554939169],"luv":[54.3705825415329,115.849509832295894,-16.8942131860788436],"rgb":[0.933333333333333348,0.2,0.533333333333333326],"xyz":[0.408863440665345801,0.223254114208364163,0.254495899434709405],"hpluv":[351.703100554939169,273.2366774905733,54.3705825415329],"hsluv":[351.703100554939169,85.9285066952877,54.3705825415329]},"#ee3399":{"lch":[54.9151057717267292,112.774715889061866,344.730687431692274],"luv":[54.9151057717267292,108.793611621096844,-29.6999430015709507],"rgb":[0.933333333333333348,0.2,0.6],"xyz":[0.4219204047744185,0.22847689985199332,0.323262577075827284],"hpluv":[344.730687431692274,260.590898768244074,54.9151057717267292],"hsluv":[344.730687431692274,86.7978129198036896,54.9151057717267292]},"#ee33aa":{"lch":[55.5328602544255,110.325325240584178,337.093995035693695],"luv":[55.5328602544255,101.625579555338021,-42.9408776049389047],"rgb":[0.933333333333333348,0.2,0.66666666666666663],"xyz":[0.436978097739671056,0.234499977038094415,0.402566426692825885],"hpluv":[337.093995035693695,252.095155701888757,55.5328602544255],"hsluv":[337.093995035693695,87.6758366884225779,55.5328602544255]},"#ee33bb":{"lch":[56.2232062298057826,110.03895679054483,329.178007243031175],"luv":[56.2232062298057826,94.4974163460242664,-56.3809392922602726],"rgb":[0.933333333333333348,0.2,0.733333333333333282],"xyz":[0.454115689847007731,0.241355013881029173,0.492824411791467631],"hpluv":[329.178007243031175,248.353441541401367,56.2232062298057826],"hsluv":[329.178007243031175,88.5430404155392665,56.2232062298057826]},"#ee33cc":{"lch":[56.9848866198670123,111.971807156825847,321.417898872172259],"luv":[56.9848866198670123,87.5300782585605788,-69.8295854062993726],"rgb":[0.933333333333333348,0.2,0.8],"xyz":[0.47340806529072943,0.249071964058517975,0.594430922461737787],"hpluv":[321.417898872172259,249.337916143678171,56.9848866198670123],"hsluv":[321.417898872172259,89.3839737673679764,56.9848866198670123]},"#ee33dd":{"lch":[57.8161114567543848,115.945977330727956,314.185904182223908],"luv":[57.8161114567543848,80.813036999634221,-83.1427850752753557],"rgb":[0.933333333333333348,0.2,0.866666666666666696],"xyz":[0.494926390841363029,0.257679294278771509,0.707760770361743785],"hpluv":[314.185904182223908,254.475591939392586,57.8161114567543848],"hsluv":[314.185904182223908,90.1873197259471482,57.8161114567543848]},"#ee33ee":{"lch":[58.7146439354817886,121.632779311923699,307.715012949243715],"luv":[58.7146439354817886,74.4069479563921448,-96.2192241652253415],"rgb":[0.933333333333333348,0.2,0.933333333333333348],"xyz":[0.518738571107537738,0.267204166385241526,0.833171586430267],"hpluv":[307.715012949243715,262.87151341613469,58.7146439354817886],"hsluv":[307.715012949243715,90.9455375510239747,58.7146439354817886]},"#ee33ff":{"lch":[59.6778857977730581,128.651158016084139,302.091050100274117],"luv":[59.6778857977730581,68.3480180420837229,-108.993893813362092],"rgb":[0.933333333333333348,0.2,1],"xyz":[0.544909619517369159,0.27767258574917425,0.971005774722048853],"hpluv":[302.091050100274117,273.551812848380507,59.6778857977730581],"hsluv":[302.091050100274117,99.9999999999986784,59.6778857977730581]},"#ee4400":{"lch":[54.3591594970822598,145.188828472067655,17.4116852889838647],"luv":[54.3591594970822598,138.536177662057611,43.4456372018905412],"rgb":[0.933333333333333348,0.266666666666666663,0],"xyz":[0.373261401598505183,0.223145411354373546,0.023417812633377437],"hpluv":[17.4116852889838647,338.922026437804789,54.3591594970822598],"hsluv":[17.4116852889838647,100.000000000002217,54.3591594970822598]},"#ee4411":{"lch":[54.4016650840252112,143.940172045268554,16.9187727396215735],"luv":[54.4016650840252112,137.710194578710485,41.8888462184768713],"rgb":[0.933333333333333348,0.266666666666666663,0.0666666666666666657],"xyz":[0.374273067098142287,0.223550077554228399,0.0287459175981330667],"hpluv":[16.9187727396215735,335.744689025208913,54.4016650840252112],"hsluv":[16.9187727396215735,97.1754310281257574,54.4016650840252112]},"#ee4422":{"lch":[54.4803236312215944,141.690847159829417,15.9963876830432117],"luv":[54.4803236312215944,136.204446081142294,39.0467032744039173],"rgb":[0.933333333333333348,0.266666666666666663,0.133333333333333331],"xyz":[0.376148425236619344,0.224300220809619227,0.0386228037941122662],"hpluv":[15.9963876830432117,330.020900264600868,54.4803236312215944],"hsluv":[15.9963876830432117,92.0288025918740118,54.4803236312215944]},"#ee4433":{"lch":[54.6094526105793534,138.167821982121467,14.4538486850626899],"luv":[54.6094526105793534,133.794673004457735,34.4867004352900608],"rgb":[0.933333333333333348,0.266666666666666663,0.2],"xyz":[0.37923617596907705,0.225535321102602326,0.0548849576517234095],"hpluv":[14.4538486850626899,321.054243711338643,54.6094526105793534],"hsluv":[14.4538486850626899,83.7991355104008591,54.6094526105793534]},"#ee4444":{"lch":[54.7950558424119549,133.462657054844783,12.1770506300618084],"luv":[54.7950558424119549,130.459808710538397,28.151716454753565],"rgb":[0.933333333333333348,0.266666666666666663,0.266666666666666663],"xyz":[0.383694171213295965,0.22731851920028992,0.078363732604610048],"hpluv":[12.1770506300618084,309.070617226475065,54.7950558424119549],"hsluv":[12.1770506300618084,79.6495466444067546,54.7950558424119549]},"#ee4455":{"lch":[55.04178262974213,127.837203216659944,9.0482956458548145],"luv":[55.04178262974213,126.246413461005446,20.1045670057943724],"rgb":[0.933333333333333348,0.266666666666666663,0.333333333333333315],"xyz":[0.38965658525265795,0.229703484816034753,0.109765779878583963],"hpluv":[9.0482956458548145,294.716259365516066,55.04178262974213],"hsluv":[9.0482956458548145,80.0457187830871106,55.04178262974213]},"#ee4466":{"lch":[55.3531965298607105,121.710491561886229,4.95183922571805102],"luv":[55.3531965298607105,121.256220070521849,10.5058483924504795],"rgb":[0.933333333333333348,0.266666666666666663,0.4],"xyz":[0.397241581026166135,0.232737483125438044,0.149713424285727925],"hpluv":[4.95183922571805102,279.013127650855779,55.3531965298607105],"hsluv":[4.95183922571805102,80.511500113091131,55.3531965298607105]},"#ee4477":{"lch":[55.7319177265462855,115.631099927359429,359.795147057523252],"luv":[55.7319177265462855,115.63036086114974,-0.41342173536332294],"rgb":[0.933333333333333348,0.266666666666666663,0.466666666666666674],"xyz":[0.406555594046368041,0.236463088333518867,0.198767226192125834],"hpluv":[359.795147057523252,263.275227085929203,55.7319177265462855],"hsluv":[359.795147057523252,81.0316034214938412,55.7319177265462855]},"#ee4488":{"lch":[56.1797144871475069,110.229334232011354,353.550243523911263],"luv":[56.1797144871475069,109.531664472369371,-12.3822697089333467],"rgb":[0.933333333333333348,0.266666666666666663,0.533333333333333326],"xyz":[0.417696011148311841,0.240919255174296465,0.257440089595698],"hpluv":[353.550243523911263,248.975712077739217,56.1797144871475069],"hsluv":[353.550243523911263,81.5885451367485217,56.1797144871475069]},"#ee4499":{"lch":[56.6975745677487,106.142668326601637,346.310852745323245],"luv":[56.6975745677487,103.127575819694869,-25.1190992084518889],"rgb":[0.933333333333333348,0.266666666666666663,0.6],"xyz":[0.430752975257384541,0.246142040817925623,0.326206767236815909],"hpluv":[346.310852745323245,237.55536706581762,56.6975745677487],"hsluv":[346.310852745323245,82.1643886194057,56.6975745677487]},"#ee44aa":{"lch":[57.2857706939250164,103.913945498461985,338.339047623856459],"luv":[57.2857706939250164,96.5759938315173798,-38.356035828954532],"rgb":[0.933333333333333348,0.266666666666666663,0.66666666666666663],"xyz":[0.445810668222637096,0.252165118004026745,0.405510616853814509],"hpluv":[338.339047623856459,230.179372132151769,57.2857706939250164],"hsluv":[338.339047623856459,82.742186475039972,57.2857706939250164]},"#ee44bb":{"lch":[57.9439265752057224,103.883653730246948,330.054621671216069],"luv":[57.9439265752057224,90.015359877018625,-51.8560362788815183],"rgb":[0.933333333333333348,0.266666666666666663,0.733333333333333282],"xyz":[0.462948260329973771,0.259020154846961503,0.495768601952456256],"hpluv":[330.054621671216069,227.498543532010189,57.9439265752057224],"hsluv":[330.054621671216069,83.3069826860278,57.9439265752057224]},"#ee44cc":{"lch":[58.6710858878032866,106.123661593235155,321.940977409416575],"luv":[58.6710858878032866,83.5592367986741493,-65.4223623509468837],"rgb":[0.933333333333333348,0.266666666666666663,0.8],"xyz":[0.48224063577369547,0.266737105024450305,0.597375112622726356],"hpluv":[321.940977409416575,229.523641905846944,58.6710858878032866],"hsluv":[321.940977409416575,83.8463488142865288,58.6710858878032866]},"#ee44dd":{"lch":[59.4657843936948041,110.45324904546132,314.41066654104867],"luv":[59.4657843936948041,77.2947793232282407,-78.9014405069524116],"rgb":[0.933333333333333348,0.266666666666666663,0.866666666666666696],"xyz":[0.503758961324329069,0.275344435244703811,0.710704960522732354],"hpluv":[314.41066654104867,235.695163072106425,59.4657843936948041],"hsluv":[314.41066654104867,84.3505154479208699,59.4657843936948041]},"#ee44ee":{"lch":[60.3261240941145189,116.527805305600168,307.715012949243771],"luv":[60.3261240941145189,71.28406005268711,-92.180866733529669],"rgb":[0.933333333333333348,0.266666666666666663,0.933333333333333348],"xyz":[0.527571141590503778,0.284869307351173828,0.836115776591255577],"hpluv":[307.715012949243771,245.111377339321677,60.3261240941145189],"hsluv":[307.715012949243771,84.8122051950840898,60.3261240941145189]},"#ee44ff":{"lch":[61.2498476847862321,123.946828366557639,301.937515996566106],"luv":[61.2498476847862321,65.5671420475233617,-105.184438705774298],"rgb":[0.933333333333333348,0.266666666666666663,1],"xyz":[0.553742190000335199,0.295337726715106552,0.973949964883037422],"hpluv":[301.937515996566106,256.785047727470896,61.2498476847862321],"hsluv":[301.937515996566106,99.9999999999986073,61.2498476847862321]},"#ee5500":{"lch":[56.7595334156469136,135.29504726150742,20.5772435658132551],"luv":[56.7595334156469136,126.663115619922038,47.5521288161507414],"rgb":[0.933333333333333348,0.333333333333333315,0],"xyz":[0.385074658312851148,0.24677192478306581,0.0273555648714926478],"hpluv":[20.5772435658132551,302.470071141489655,56.7595334156469136],"hsluv":[20.5772435658132551,100.000000000002331,56.7595334156469136]},"#ee5511":{"lch":[56.7992830001534799,134.121232245619609,20.0864579205919],"luv":[56.7992830001534799,125.963368804879124,46.0622910677426],"rgb":[0.933333333333333348,0.333333333333333315,0.0666666666666666657],"xyz":[0.386086323812488252,0.247176590982920663,0.0326836698362482775],"hpluv":[20.0864579205919,299.636011805134103,56.7992830001534799],"hsluv":[20.0864579205919,97.4301566790671245,56.7992830001534799]},"#ee5522":{"lch":[56.8728535321199331,132.003018379302972,19.1666168944474329],"luv":[56.8728535321199331,124.685803630375247,43.3387498007741385],"rgb":[0.933333333333333348,0.333333333333333315,0.133333333333333331],"xyz":[0.387961681950965309,0.247926734238311491,0.042560556032227477],"hpluv":[19.1666168944474329,294.522290528054612,56.8728535321199331],"hsluv":[19.1666168944474329,92.7404035063857748,56.8728535321199331]},"#ee5533":{"lch":[56.9936637318031813,128.675597773649343,17.6241311186411558],"luv":[56.9936637318031813,122.635981466153211,38.9592801812266671],"rgb":[0.933333333333333348,0.333333333333333315,0.2],"xyz":[0.391049432683423,0.24916183453129459,0.0588227098898386203],"hpluv":[17.6241311186411558,286.489655583397507,56.9936637318031813],"hsluv":[17.6241311186411558,85.2217597168545353,56.9936637318031813]},"#ee5544":{"lch":[57.1673833238913431,124.212647444540593,15.3377586553938237],"luv":[57.1673833238913431,119.788604494467549,32.8553194848226298],"rgb":[0.933333333333333348,0.333333333333333315,0.266666666666666663],"xyz":[0.39550742792764193,0.250945032628982156,0.0823014848427252588],"hpluv":[15.3377586553938237,275.712737821839653,57.1673833238913431],"hsluv":[15.3377586553938237,78.8138286806830308,57.1673833238913431]},"#ee5555":{"lch":[57.3984455800741813,118.847398490007407,12.1770506300618084],"luv":[57.3984455800741813,116.173386735287238,25.068871978930396],"rgb":[0.933333333333333348,0.333333333333333315,0.333333333333333315],"xyz":[0.401469841967003915,0.253329998244727,0.113703532116699174],"hpluv":[12.1770506300618084,262.741620924066638,57.3984455800741813],"hsluv":[12.1770506300618084,79.1862648733910817,57.3984455800741813]},"#ee5566":{"lch":[57.6903015433249777,112.967028718059339,8.00617638558467881],"luv":[57.6903015433249777,111.865945908872092,15.7340307391382019],"rgb":[0.933333333333333348,0.333333333333333315,0.4],"xyz":[0.409054837740512101,0.256363996554130336,0.153651176523843136],"hpluv":[8.00617638558467881,248.478160638648092,57.6903015433249777],"hsluv":[8.00617638558467881,79.626682914648967,57.6903015433249777]},"#ee5577":{"lch":[58.0455538260385,107.095574323644513,2.70497781295448236],"luv":[58.0455538260385,106.976246145051803,5.05418642558356],"rgb":[0.933333333333333348,0.333333333333333315,0.466666666666666674],"xyz":[0.418368850760714,0.260089601762211131,0.202704978430241045],"hpluv":[2.70497781295448236,234.121819944652458,58.0455538260385],"hsluv":[2.70497781295448236,80.121743738144815,58.0455538260385]},"#ee5588":{"lch":[58.4660405277881523,101.857434077675435,356.214905006905212],"luv":[58.4660405277881523,101.63524992227579,-6.72405012805051783],"rgb":[0.933333333333333348,0.333333333333333315,0.533333333333333326],"xyz":[0.429509267862657806,0.264545768602988729,0.261377841833813185],"hpluv":[356.214905006905212,221.069268787819283,58.4660405277881523],"hsluv":[356.214905006905212,80.6557447307456385,58.4660405277881523]},"#ee5599":{"lch":[58.9528982622070714,97.9100075268454475,348.609359498013816],"luv":[58.9528982622070714,95.9815181358717808,-19.3369529719717974],"rgb":[0.933333333333333348,0.333333333333333315,0.6],"xyz":[0.442566231971730506,0.269768554246617887,0.33014451947493112],"hpluv":[348.609359498013816,210.746926462762332,58.9528982622070714],"hsluv":[348.609359498013816,81.2121283261168685,58.9528982622070714]},"#ee55aa":{"lch":[59.5066178042993812,95.8379147411847327,340.160257686713578],"luv":[59.5066178042993812,90.1495111294489817,-32.5264745255299346],"rgb":[0.933333333333333348,0.333333333333333315,0.66666666666666663],"xyz":[0.457623924936983062,0.275791631432719,0.40944836909192972],"hpluv":[340.160257686713578,204.36730380296666,59.5066178042993812],"hsluv":[340.160257686713578,81.7747968800248515,59.5066178042993812]},"#ee55bb":{"lch":[60.1270988419473156,96.02691270708236,331.338718337462637],"luv":[60.1270988419473156,84.2607812264238305,-46.0574501157669],"rgb":[0.933333333333333348,0.333333333333333315,0.733333333333333282],"xyz":[0.474761517044319736,0.282646668275653767,0.499706354190571467],"hpluv":[331.338718337462637,202.657202566236862,60.1270988419473156],"hsluv":[331.338718337462637,82.3290961128101202,60.1270988419473156]},"#ee55cc":{"lch":[60.8137066481247359,98.5745380895967855,322.704854800823],"luv":[60.8137066481247359,78.4184921400445774,-59.728382282288],"rgb":[0.933333333333333348,0.333333333333333315,0.8],"xyz":[0.494053892488041435,0.290363618453142569,0.601312864860841567],"hpluv":[322.704854800823,205.68499115665557,60.8137066481247359],"hsluv":[322.704854800823,82.862416210457269,60.8137066481247359]},"#ee55dd":{"lch":[61.5653314057239669,103.296154527471415,314.73674606959],"luv":[61.5653314057239669,72.7050419742243577,-73.3762387404091925],"rgb":[0.933333333333333348,0.333333333333333315,0.866666666666666696],"xyz":[0.515572218038675,0.298970948673396075,0.714642712760847565],"hpluv":[314.73674606959,212.905685416828703,61.5653314057239669],"hsluv":[314.73674606959,83.3644351442966496,61.5653314057239669]},"#ee55ee":{"lch":[62.3804497031794796,109.822432229930158,307.715012949243942],"luv":[62.3804497031794796,67.1821530808003473,-86.8764923804219364],"rgb":[0.933333333333333348,0.333333333333333315,0.933333333333333348],"xyz":[0.539384398304849744,0.308495820779866092,0.840053528829370788],"hpluv":[307.715012949243942,223.399338603574023,62.3804497031794796],"hsluv":[307.715012949243942,83.8270760150894318,62.3804497031794796]},"#ee55ff":{"lch":[63.2571870514493355,117.722992850638121,301.718618818209791],"luv":[63.2571870514493355,61.8926401270512301,-100.139922827085911],"rgb":[0.933333333333333348,0.333333333333333315,1],"xyz":[0.565555446714681165,0.318964240143798816,0.977887717121152633],"hpluv":[301.718618818209791,236.15152010236153,63.2571870514493355],"hsluv":[301.718618818209791,99.9999999999986358,63.2571870514493355]},"#ee6600":{"lch":[59.6010827175637274,124.896403377083828,24.7633991985742],"luv":[59.6010827175637274,113.411584725929117,52.315619335764687],"rgb":[0.933333333333333348,0.4,0],"xyz":[0.400102716018697624,0.276828040194759151,0.032364917440108],"hpluv":[24.7633991985742,265.910269095548301,59.6010827175637274],"hsluv":[24.7633991985742,100.000000000002458,59.6010827175637274]},"#ee6611":{"lch":[59.6379025762155521,123.785593795891074,24.2806773941880323],"luv":[59.6379025762155521,112.835768380983566,50.9014990474188],"rgb":[0.933333333333333348,0.4,0.0666666666666666657],"xyz":[0.401114381518334728,0.277232706394614,0.0376930224048636284],"hpluv":[24.2806773941880323,263.38259338209491,59.6379025762155521],"hsluv":[24.2806773941880323,97.6946368166697425,59.6379025762155521]},"#ee6622":{"lch":[59.7060621192549235,121.776511986799889,23.3741045361832462],"luv":[59.7060621192549235,111.782804083827386,48.312768320888857],"rgb":[0.933333333333333348,0.4,0.133333333333333331],"xyz":[0.402989739656811785,0.277982849650004804,0.0475699086008428279],"hpluv":[23.3741045361832462,258.812011755725052,59.7060621192549235],"hsluv":[23.3741045361832462,93.4807634058905847,59.7060621192549235]},"#ee6633":{"lch":[59.818019190990654,118.60827278102343,21.848413141726418],"luv":[59.818019190990654,110.088842330137865,44.1403349161252621],"rgb":[0.933333333333333348,0.4,0.2],"xyz":[0.406077490389269491,0.279217949942987931,0.0638320624584539642],"hpluv":[21.848413141726418,251.606745577849637,59.818019190990654],"hsluv":[21.848413141726418,86.7067277856042722,59.818019190990654]},"#ee6644":{"lch":[59.9790782653121,114.334087778781978,19.5741908506499591],"luv":[59.9790782653121,107.726545105393242,38.3050271878496318],"rgb":[0.933333333333333348,0.4,0.266666666666666663],"xyz":[0.410535485633488406,0.281001148040675497,0.0873108374113406],"hpluv":[19.5741908506499591,241.888527179759762,59.9790782653121],"hsluv":[19.5741908506499591,77.7164494297015551,59.9790782653121]},"#ee6655":{"lch":[60.1934276072459227,109.155383321287928,16.4048569251700904],"luv":[60.1934276072459227,104.711671726378157,30.827966398783424],"rgb":[0.933333333333333348,0.4,0.333333333333333315],"xyz":[0.416497899672850391,0.283386113656420358,0.118712884685314518],"hpluv":[16.4048569251700904,230.109957101660228,60.1934276072459227],"hsluv":[16.4048569251700904,78.0627041699660822,60.1934276072459227]},"#ee6666":{"lch":[60.4643778553048179,103.423697151150392,12.1770506300619203],"luv":[60.4643778553048179,101.096711576265875,21.8155000143976636],"rgb":[0.933333333333333348,0.4,0.4],"xyz":[0.424082895446358576,0.286420111965823676,0.15866052909245848],"hpluv":[12.1770506300619203,217.050003231938149,60.4643778553048179],"hsluv":[12.1770506300619203,78.4746058088251601,60.4643778553048179]},"#ee6677":{"lch":[60.7944870758990845,97.6355083856116,6.72933164538236728],"luv":[60.7944870758990845,96.9628770314166388,11.4408468002682859],"rgb":[0.933333333333333348,0.4,0.466666666666666674],"xyz":[0.433396908466560482,0.290145717173904472,0.207714330998856389],"hpluv":[6.72933164538236728,203.79002370037793,60.7944870758990845],"hsluv":[6.72933164538236728,78.9407958828298177,60.7944870758990845]},"#ee6688":{"lch":[61.1856375663111294,92.4106294683140419,359.951978350089689],"luv":[61.1856375663111294,92.4105970103857,-0.0774526573243247418],"rgb":[0.933333333333333348,0.4,0.533333333333333326],"xyz":[0.444537325568504282,0.294601884014682069,0.266387194402428529],"hpluv":[359.951978350089689,191.6512981090967,61.1856375663111294],"hsluv":[359.951978350089689,79.4474583444281706,61.1856375663111294]},"#ee6699":{"lch":[61.6390913266860281,88.437141466109523,351.875732288608958],"luv":[61.6390913266860281,87.5495765855601746,-12.4979850530316181],"rgb":[0.933333333333333348,0.4,0.6],"xyz":[0.457594289677577,0.299824669658311227,0.335153872043546464],"hpluv":[351.875732288608958,182.061365307506776,61.6390913266860281],"hsluv":[351.875732288608958,79.9795786975914353,61.6390913266860281]},"#ee66aa":{"lch":[62.1555369290736337,86.3639450462453624,342.77320214224],"luv":[62.1555369290736337,82.489654306882187,-25.5770978862333536],"rgb":[0.933333333333333348,0.4,0.66666666666666663],"xyz":[0.472651982642829538,0.305847746844412349,0.414457721660545064],"hpluv":[342.77320214224,176.316102232879075,62.1555369290736337],"hsluv":[342.77320214224,80.5221008496243,62.1555369290736337]},"#ee66bb":{"lch":[62.735134131647655,86.6495273870251168,333.187217955259598],"luv":[62.735134131647655,77.3334216921159765,-39.0855790002422907],"rgb":[0.933333333333333348,0.4,0.733333333333333282],"xyz":[0.489789574750166212,0.312702783687347108,0.504715706759186755],"hpluv":[333.187217955259598,175.264796900814019,62.735134131647655],"hsluv":[333.187217955259598,81.0608551813628679,62.735134131647655]},"#ee66cc":{"lch":[63.3775592853136516,89.4351699392481549,323.800511847500275],"luv":[63.3775592853136516,72.1711045195964545,-52.8202735176909144],"rgb":[0.933333333333333348,0.4,0.8],"xyz":[0.509081950193887911,0.320419733864835909,0.606322217429456911],"hpluv":[323.800511847500275,179.065596131410075,63.3775592853136516],"hsluv":[323.800511847500275,81.5831918811758072,63.3775592853136516]},"#ee66dd":{"lch":[64.0820526997291751,94.5324861988586918,315.200217206616742],"luv":[64.0820526997291751,67.0777383779463179,-66.6105694393704795],"rgb":[0.933333333333333348,0.4,0.866666666666666696],"xyz":[0.53060027574452151,0.329027064085089416,0.719652065329462909],"hpluv":[315.200217206616742,187.190580763285084,64.0820526997291751],"hsluv":[315.200217206616742,82.0783141076240241,64.0820526997291751]},"#ee66ee":{"lch":[64.8474680131467,101.534802649490857,307.715012949244169],"luv":[64.8474680131467,62.1123254704966499,-80.32045302236628],"rgb":[0.933333333333333348,0.4,0.933333333333333348],"xyz":[0.55441245601069622,0.338551936191559433,0.845062881397986132],"hpluv":[307.715012949244169,198.683239249207219,64.8474680131467],"hsluv":[307.715012949244169,82.5373501246235,64.8474680131467]},"#ee66ff":{"lch":[65.6723229483953759,109.966867844968618,301.415067453827589],"luv":[65.6723229483953759,57.3184789471434897,-93.8472375449520797],"rgb":[0.933333333333333348,0.4,1],"xyz":[0.580583504420527641,0.349020355555492157,0.982897069689768088],"hpluv":[301.415067453827589,212.480364902930489,65.6723229483953759],"hsluv":[301.415067453827589,99.9999999999984794,65.6723229483953759]},"#ee7700":{"lch":[62.8217158048736763,114.851740825540901,30.0981414692213356],"luv":[62.8217158048736763,99.3660150566978,57.5961580525066097],"rgb":[0.933333333333333348,0.466666666666666674,0],"xyz":[0.418556454072115225,0.313735516301594908,0.0385161634579137],"hpluv":[30.0981414692213356,231.988851559171735,62.8217158048736763],"hsluv":[30.0981414692213356,100.000000000002203,62.8217158048736763]},"#ee7711":{"lch":[62.8555901763931075,113.786950077776382,29.6341042910547],"luv":[62.8555901763931075,98.9037041004629458,56.2630191441096059],"rgb":[0.933333333333333348,0.466666666666666674,0.0666666666666666657],"xyz":[0.419568119571752329,0.314140182501449761,0.0438442684226693288],"hpluv":[29.6341042910547,229.71421718860654,62.8555901763931075],"hsluv":[29.6341042910547,97.9532933827149463,62.8555901763931075]},"#ee7722":{"lch":[62.9183073649527955,111.855609649988921,28.7604537228304977],"luv":[62.9183073649527955,98.0569879769147406,53.8191835600085398],"rgb":[0.933333333333333348,0.466666666666666674,0.133333333333333331],"xyz":[0.421443477710229386,0.314890325756840561,0.0537211546186485284],"hpluv":[28.7604537228304977,225.59011469442973,62.9183073649527955],"hsluv":[28.7604537228304977,94.206312745702121,62.9183073649527955]},"#ee7733":{"lch":[63.0213536795682501,108.794922632811733,27.2836719807386174],"luv":[63.0213536795682501,96.6912591797812411,49.8711899688373208],"rgb":[0.933333333333333348,0.466666666666666674,0.2],"xyz":[0.424531228442687092,0.316125426049823688,0.0699833084762596647],"hpluv":[27.2836719807386174,219.058559128587405,63.0213536795682501],"hsluv":[27.2836719807386174,88.1668112455654,63.0213536795682501]},"#ee7744":{"lch":[63.1696562136619235,104.634411539935968,25.0668522383795889],"luv":[63.1696562136619235,94.7793214210065571,44.3310309972846497],"rgb":[0.933333333333333348,0.466666666666666674,0.266666666666666663],"xyz":[0.428989223686906,0.317908624147511254,0.0934620834291463],"hpluv":[25.0668522383795889,210.186756956079222,63.1696562136619235],"hsluv":[25.0668522383795889,79.7210233436604199,63.1696562136619235]},"#ee7755":{"lch":[63.3671413614491286,99.5393983003294096,21.9455950678528],"luv":[63.3671413614491286,92.3266881357997278,37.2004633286522051],"rgb":[0.933333333333333348,0.466666666666666674,0.333333333333333315],"xyz":[0.434951637726268,0.320293589763256115,0.124864130703120219],"hpluv":[21.9455950678528,199.328877993420377,63.3671413614491286],"hsluv":[21.9455950678528,76.6090179557391,63.3671413614491286]},"#ee7766":{"lch":[63.6169573916324822,93.8195852400781263,17.7221756586824775],"luv":[63.6169573916324822,89.367258373090749,28.5588463614608763],"rgb":[0.933333333333333348,0.466666666666666674,0.4],"xyz":[0.442536633499776177,0.323327588072659433,0.16481177511026418],"hpluv":[17.7221756586824775,187.13711975631665,63.6169573916324822],"hsluv":[17.7221756586824775,76.9903860669667,63.6169573916324822]},"#ee7777":{"lch":[63.9215909451051232,87.936547917610838,12.1770506300618937],"luv":[63.9215909451051232,85.9580160709841863,18.5487447771187846],"rgb":[0.933333333333333348,0.466666666666666674,0.466666666666666674],"xyz":[0.451850646519978083,0.327053193280740229,0.21386557701666209],"hpluv":[12.1770506300618937,174.56660414904394,63.9215909451051232],"hsluv":[12.1770506300618937,77.4248320836617268,63.9215909451051232]},"#ee7788":{"lch":[64.2829374304473,82.5014209284754543,5.11726519711922112],"luv":[64.2829374304473,82.1725895095950847,7.35866757674724514],"rgb":[0.933333333333333348,0.466666666666666674,0.533333333333333326],"xyz":[0.462991063621921883,0.331509360121517827,0.272538440420234229],"hpluv":[5.11726519711922112,162.85647909200884,64.2829374304473],"hsluv":[5.11726519711922112,77.9003779592442669,64.2829374304473]},"#ee7799":{"lch":[64.7023501026032477,78.2413537817778177,356.48599323172067],"luv":[64.7023501026032477,78.0942478632934893,-4.79561177242263259],"rgb":[0.933333333333333348,0.466666666666666674,0.6],"xyz":[0.476048027730994638,0.336732145765147,0.341305118061352164],"hpluv":[356.48599323172067,153.446019679421255,64.7023501026032477],"hsluv":[356.48599323172067,78.4035888028378167,64.7023501026032477]},"#ee77aa":{"lch":[65.1806796634753596,75.8992199041959,346.522692233148291],"luv":[65.1806796634753596,73.8091300431969302,-17.6890899803221124],"rgb":[0.933333333333333348,0.466666666666666674,0.66666666666666663],"xyz":[0.491105720696247139,0.342755222951248106,0.420608967678350765],"hpluv":[346.522692233148291,147.76029654451807,65.1806796634753596],"hsluv":[346.522692233148291,78.9205551316135256,65.1806796634753596]},"#ee77bb":{"lch":[65.7183104585581646,76.0514193956389875,335.85959217762661],"luv":[65.7183104585581646,69.4004166910179094,-31.1030634376174824],"rgb":[0.933333333333333348,0.466666666666666674,0.733333333333333282],"xyz":[0.508243312803583813,0.349610259794182865,0.510866952776992456],"hpluv":[335.85959217762661,146.845370988132231,65.7183104585581646],"hsluv":[335.85959217762661,79.4377328719524627,65.7183104585581646]},"#ee77cc":{"lch":[66.3151963922866,78.9180750862202416,325.378996221060731],"luv":[66.3151963922866,64.9439055461397459,-44.8369457894756067],"rgb":[0.933333333333333348,0.466666666666666674,0.8],"xyz":[0.527535688247305568,0.357327209971671667,0.612473463447262612],"hpluv":[325.378996221060731,151.008971652655617,66.3151963922866],"hsluv":[325.378996221060731,79.9425706591808307,66.3151963922866]},"#ee77dd":{"lch":[66.9708980107196652,84.3115421117289543,315.859798591258766],"luv":[66.9708980107196652,60.5051526262217152,-58.7159487612646842],"rgb":[0.933333333333333348,0.466666666666666674,0.866666666666666696],"xyz":[0.549054013797939056,0.365934540191925173,0.725803311347268609],"hpluv":[315.859798591258766,159.749768323538632,66.9708980107196652],"hsluv":[315.859798591258766,80.4238985377879345,66.9708980107196652]},"#ee77ee":{"lch":[67.6846211881785251,91.7687338274624409,307.715012949244453],"luv":[67.6846211881785251,56.1380858067324056,-72.5948746830766112],"rgb":[0.933333333333333348,0.466666666666666674,0.933333333333333348],"xyz":[0.572866194064113765,0.37545941229839519,0.851214127415791832],"hpluv":[307.715012949244453,172.045795420537047,67.6846211881785251],"hsluv":[307.715012949244453,80.8720902094370757,67.6846211881785251]},"#ee77ff":{"lch":[68.4552572311626761,100.746525491660947,300.997699928034137],"luv":[68.4552572311626761,51.8848298156272918,-86.3587102361150585],"rgb":[0.933333333333333348,0.466666666666666674,1],"xyz":[0.599037242473945186,0.385927831662327914,0.989048315707573789],"hpluv":[300.997699928034137,186.750854251257437,68.4552572311626761],"hsluv":[300.997699928034137,99.9999999999982,68.4552572311626761]},"#ee8800":{"lch":[66.3576417146455,105.981377873447272,36.6492300119340797],"luv":[66.3576417146455,85.0293774107247771,63.2618165491550428],"rgb":[0.933333333333333348,0.533333333333333326,0],"xyz":[0.440628823797085678,0.35788025575153648,0.045873620032903642],"hpluv":[36.6492300119340797,202.664622836431278,66.3576417146455],"hsluv":[36.6492300119340797,100.000000000002288,66.3576417146455]},"#ee8811":{"lch":[66.3886714607036907,104.946342152180421,36.2201184819273792],"luv":[66.3886714607036907,84.6657638625926552,62.0116373004794923],"rgb":[0.933333333333333348,0.533333333333333326,0.0666666666666666657],"xyz":[0.441640489296722782,0.358284921951391333,0.0512017249976592717],"hpluv":[36.2201184819273792,200.591559481147556,66.3886714607036907],"hsluv":[36.2201184819273792,98.1954604930108701,66.3886714607036907]},"#ee8822":{"lch":[66.4461305943750773,103.062674429887437,35.4099902294173745],"luv":[66.4461305943750773,83.9988395226221201,59.7169140151578],"rgb":[0.933333333333333348,0.533333333333333326,0.133333333333333331],"xyz":[0.443515847435199839,0.359035065206782134,0.0610786111936384712],"hpluv":[35.4099902294173745,196.820821024497235,66.4461305943750773],"hsluv":[35.4099902294173745,94.8869488142181581,66.4461305943750773]},"#ee8833":{"lch":[66.5405621290638578,100.059958052790449,34.0337853874148877],"luv":[66.5405621290638578,82.920456825626232,56.0017235927220369],"rgb":[0.933333333333333348,0.533333333333333326,0.2],"xyz":[0.446603598167657545,0.36027016549976526,0.0773407650512496214],"hpluv":[34.0337853874148877,190.815292572549708,66.5405621290638578],"hsluv":[34.0337853874148877,89.5408718212573689,66.5405621290638578]},"#ee8844":{"lch":[66.6765193585480347,95.9403990837829639,31.9512880443390657],"luv":[66.6765193585480347,81.4052672986078107,50.7714745934935223],"rgb":[0.933333333333333348,0.533333333333333326,0.266666666666666663],"xyz":[0.45106159341187646,0.362053363597452826,0.10081954000413626],"hpluv":[31.9512880443390657,182.586190035925256,66.6765193585480347],"hsluv":[31.9512880443390657,82.0371002457568608,66.6765193585480347]},"#ee8855":{"lch":[66.8576614114874559,90.8274017958005,28.983496619036984],"luv":[66.8576614114874559,79.4521157428502391,44.0111147434430805],"rgb":[0.933333333333333348,0.533333333333333326,0.333333333333333315],"xyz":[0.457024007451238445,0.364438329213197687,0.132221587278110175],"hpluv":[28.983496619036984,172.387208051834335,66.8576614114874559],"hsluv":[28.983496619036984,74.7174368883009663,66.8576614114874559]},"#ee8866":{"lch":[67.0869600103699213,84.978663004295683,24.8971939400565283],"luv":[67.0869600103699213,77.081139807049837,35.7752854921339249],"rgb":[0.933333333333333348,0.533333333333333326,0.4],"xyz":[0.464609003224746631,0.367472327522601,0.172169231685254109],"hpluv":[24.8971939400565283,160.735241770302764,67.0869600103699213],"hsluv":[24.8971939400565283,75.0669061044520447,67.0869600103699213]},"#ee8877":{"lch":[67.3668077908477727,78.8051510957513841,19.4009345351312952],"luv":[67.3668077908477727,74.3303771171996743,26.1772205713113095],"rgb":[0.933333333333333348,0.533333333333333326,0.466666666666666674],"xyz":[0.473923016244948536,0.371197932730681801,0.221223033591652019],"hpluv":[19.4009345351312952,148.438980876884,67.3668077908477727],"hsluv":[19.4009345351312952,75.4672397967126329,67.3668077908477727]},"#ee8888":{"lch":[67.6990830402889117,72.8916076032019191,12.177050630062066],"luv":[67.6990830402889117,71.2515799877231757,15.3752661190709663],"rgb":[0.933333333333333348,0.533333333333333326,0.533333333333333326],"xyz":[0.485063433346892336,0.375654099571459399,0.279895896995224214],"hpluv":[12.177050630062066,136.626224949154164,67.6990830402889117],"hsluv":[12.177050630062066,75.9081099773692927,67.6990830402889117]},"#ee8899":{"lch":[68.0851935471165319,67.9986383575237312,2.99916583787236446],"luv":[68.0851935471165319,67.9055003914663615,3.55778513430191889],"rgb":[0.933333333333333348,0.533333333333333326,0.6],"xyz":[0.498120397455965036,0.380876885215088556,0.348662574636342093],"hpluv":[2.99916583787236446,126.732168582193651,68.0851935471165319],"hsluv":[2.99916583787236446,76.3775584855855385,68.0851935471165319]},"#ee88aa":{"lch":[68.5261104708773274,64.9933943358063573,351.976176804910949],"luv":[68.5261104708773274,64.3571165389368,-9.07209226602857832],"rgb":[0.933333333333333348,0.533333333333333326,0.66666666666666663],"xyz":[0.513178090421217648,0.386899962401189679,0.427966424253340694],"hpluv":[351.976176804910949,120.351764916629207,68.5261104708773274],"hsluv":[351.976176804910949,76.8628030471707859,68.5261104708773274]},"#ee88bb":{"lch":[69.0223979406526098,64.6433047463018,339.810246341231903],"luv":[69.0223979406526098,60.6712812589502875,-22.3103670727442456],"rgb":[0.933333333333333348,0.533333333333333326,0.733333333333333282],"xyz":[0.530315682528554211,0.393754999244124437,0.51822440935198244],"hpluv":[339.810246341231903,118.842788638920595,69.0223979406526098],"hsluv":[339.810246341231903,77.3509666785266887,69.0223979406526098]},"#ee88cc":{"lch":[69.5742414545850778,67.3203562589766307,327.709288072293873],"luv":[69.5742414545850778,56.9091584539883399,-35.9635656031820687],"rgb":[0.933333333333333348,0.533333333333333326,0.8],"xyz":[0.549608057972276,0.401471949421613239,0.619830920022252596],"hpluv":[327.709288072293873,122.782720563937247,69.5742414545850778],"hsluv":[327.709288072293873,77.8296635442389686,69.5742414545850778]},"#ee88dd":{"lch":[70.1814766713242,72.856404222049747,316.817937357318669],"luv":[70.1814766713242,53.1256441200966663,-49.8570112721525547],"rgb":[0.933333333333333348,0.533333333333333326,0.866666666666666696],"xyz":[0.571126383522909564,0.410079279641866745,0.733160767922258594],"hpluv":[316.817937357318669,131.729959343498166,70.1814766713242],"hsluv":[316.817937357318669,78.2874043120714163,70.1814766713242]},"#ee88ee":{"lch":[70.8436192863675558,80.7013698438951224,307.715012949244851],"luv":[70.8436192863675558,49.367799206375345,-63.839889537812887],"rgb":[0.933333333333333348,0.533333333333333326,0.933333333333333348],"xyz":[0.594938563789084274,0.419604151748336762,0.858571583990781817],"hpluv":[307.715012949244851,144.550464850223619,70.8436192863675558],"hsluv":[307.715012949244851,78.7138135635212848,70.8436192863675558]},"#ee88ff":{"lch":[71.5598961203093182,90.2054153167292583,300.42003582834775],"luv":[71.5598961203093182,45.674190228859068,-77.7874366424399426],"rgb":[0.933333333333333348,0.533333333333333326,1],"xyz":[0.621109612198915695,0.430072571112269486,0.996405772282563662],"hpluv":[300.42003582834775,159.956626210428567,71.5598961203093182],"hsluv":[300.42003582834775,99.99999999999784,71.5598961203093182]},"#ee9900":{"lch":[70.1492527845175715,98.9919938823364731,44.3502140795235036],"luv":[70.1492527845175715,70.7872313214223112,69.1995862317686772],"rgb":[0.933333333333333348,0.6,0],"xyz":[0.466498424249553179,0.409619456656472147,0.0544968201837259],"hpluv":[44.3502140795235036,179.06732625175573,70.1492527845175715],"hsluv":[44.3502140795235036,100.000000000002217,70.1492527845175715]},"#ee9911":{"lch":[70.1776126165771785,97.9766822185852533,43.9766782844564119],"luv":[70.1776126165771785,70.5062245085518526,68.0316291449155273],"rgb":[0.933333333333333348,0.6,0.0666666666666666657],"xyz":[0.467510089749190283,0.410024122856327,0.0598249251484815267],"hpluv":[43.9766782844564119,177.15910010767405,70.1776126165771785],"hsluv":[43.9766782844564119,98.4152296143538337,70.1776126165771785]},"#ee9922":{"lch":[70.2301348691785,96.1222676294158447,43.2696050504519505],"luv":[70.2301348691785,69.9901292501651824,65.8852953379296622],"rgb":[0.933333333333333348,0.6,0.133333333333333331],"xyz":[0.46938544788766734,0.410774266111717801,0.0697018113444607262],"hpluv":[43.2696050504519505,173.676009463775955,70.2301348691785],"hsluv":[43.2696050504519505,95.5057584668238,70.2301348691785]},"#ee9933":{"lch":[70.3164728806357573,93.1473438817036339,42.0626701373461103],"luv":[70.3164728806357573,69.1537511222041417,62.4034163964169508],"rgb":[0.933333333333333348,0.6,0.2],"xyz":[0.472473198620125046,0.412009366404700927,0.0859639652020718625],"hpluv":[42.0626701373461103,168.094198140054317,70.3164728806357573],"hsluv":[42.0626701373461103,90.7937976503380213,70.3164728806357573]},"#ee9944":{"lch":[70.4408210614760719,89.024296887742608,40.221678197216157],"luv":[70.4408210614760719,67.9746586813449483,57.4871395488729533],"rgb":[0.933333333333333348,0.6,0.266666666666666663],"xyz":[0.476931193864343961,0.413792564502388494,0.109442740154958501],"hpluv":[40.221678197216157,160.370125602871781,70.4408210614760719],"hsluv":[40.221678197216157,84.1577311163605657,70.4408210614760719]},"#ee9955":{"lch":[70.6065752665828654,83.8291063606938138,37.5652459120346904],"luv":[70.6065752665828654,66.4479455240540631,51.1076276974862154],"rgb":[0.933333333333333348,0.6,0.333333333333333315],"xyz":[0.482893607903705946,0.416177530118133354,0.140844787428932416],"hpluv":[37.5652459120346904,150.656896294971034,70.6065752665828654],"hsluv":[37.5652459120346904,75.5772228053980797,70.6065752665828654]},"#ee9966":{"lch":[70.8165243284349373,77.7550236522342,33.8383101580563],"luv":[70.8165243284349373,64.5842808158336652,43.297971946282189],"rgb":[0.933333333333333348,0.6,0.4],"xyz":[0.490478603677214131,0.419211528427536673,0.180792431836076378],"hpluv":[33.8383101580563,139.326323276972687,70.8165243284349373],"hsluv":[33.8383101580563,72.525293376848623,70.8165243284349373]},"#ee9977":{"lch":[71.0729506656700778,71.1378337295946,28.6840524218341386],"luv":[71.0729506656700778,62.4077841236731601,34.1446901949989154],"rgb":[0.933333333333333348,0.6,0.466666666666666674],"xyz":[0.499792616697416037,0.422937133635617468,0.229846233742474287],"hpluv":[28.6840524218341386,127.009327518651787,71.0729506656700778],"hsluv":[28.6840524218341386,72.8885787597460677,71.0729506656700778]},"#ee9988":{"lch":[71.3776900371935312,64.4963091800695878,21.6331741754282376],"luv":[71.3776900371935312,59.9533946760230378,23.7773918811996943],"rgb":[0.933333333333333348,0.6,0.533333333333333326],"xyz":[0.510933033799359837,0.427393300476395066,0.288519097146046455],"hpluv":[21.6331741754282376,114.659937381049531,71.3776900371935312],"hsluv":[21.6331741754282376,73.2902809537896189,71.3776900371935312]},"#ee9999":{"lch":[71.732171153908709,58.5818834203282179,12.1770506300621602],"luv":[71.732171153908709,57.263818011494017,12.3568690136061505],"rgb":[0.933333333333333348,0.6,0.6],"xyz":[0.523989997908432592,0.432616086120024224,0.35728577478716439],"hpluv":[12.1770506300621602,103.630759412975706,71.732171153908709],"hsluv":[12.1770506300621602,73.7196701825771186,71.732171153908709]},"#ee99aa":{"lch":[72.1374451439022408,54.3863410009709725,0.0659165211073427237],"luv":[72.1374451439022408,54.3863050092105,0.0625693137293968082],"rgb":[0.933333333333333348,0.6,0.66666666666666663],"xyz":[0.539047690873685093,0.438639163306125346,0.436589624404162935],"hpluv":[0.0659165211073427237,95.6683780017161,72.1374451439022408],"hsluv":[0.0659165211073427237,74.1649147609968082,72.1374451439022408]},"#ee99bb":{"lch":[72.5942101669252366,52.9692652640659247,345.882936464906891],"luv":[72.5942101669252366,51.3695627363271683,-12.9194073739288822],"rgb":[0.933333333333333348,0.6,0.733333333333333282],"xyz":[0.556185282981021767,0.445494200149060104,0.526847609502804737],"hpluv":[345.882936464906891,92.5894045166522091,72.5942101669252366],"hsluv":[345.882936464906891,74.6136876066909878,72.5942101669252366]},"#ee99cc":{"lch":[73.1028341171650737,55.013164482536844,331.314039518972208],"luv":[73.1028341171650737,48.2610582375421515,-26.4067893575727517],"rgb":[0.933333333333333348,0.6,0.8],"xyz":[0.575477658424743521,0.453211150326548906,0.628454120173074893],"hpluv":[331.314039518972208,95.4930444317639342,73.1028341171650737],"hsluv":[331.314039518972208,75.0536815693659491,73.1028341171650737]},"#ee99dd":{"lch":[73.6633770412179274,60.4388711558699896,318.269971219550712],"luv":[73.6633770412179274,45.1048908137830935,-40.2294167403973049],"rgb":[0.933333333333333348,0.6,0.866666666666666696],"xyz":[0.596995983975377,0.461818480546802412,0.74178396807308089],"hpluv":[318.269971219550712,104.112780668711437,73.6633770412179274],"hsluv":[318.269971219550712,75.472992612571872,73.6633770412179274]},"#ee99ee":{"lch":[74.2756141069900337,68.5596754700476083,307.71501294924542],"luv":[74.2756141069900337,41.9403078139404499,-54.2350410807456953],"rgb":[0.933333333333333348,0.6,0.933333333333333348],"xyz":[0.620808164241551719,0.471343352653272429,0.867194784141604114],"hpluv":[307.71501294924542,117.128296895720368,74.2756141069900337],"hsluv":[307.71501294924542,75.8603506282489235,74.2756141069900337]},"#ee99ff":{"lch":[74.9390594560707,78.5455210447045857,299.603294913962486],"luv":[74.9390594560707,38.8008486558083519,-68.2927010724659],"rgb":[0.933333333333333348,0.6,1],"xyz":[0.64697921265138314,0.481811772017205153,1.00502897243338585],"hpluv":[299.603294913962486,133.000267199001968,74.9390594560707],"hsluv":[299.603294913962486,99.9999999999973284,74.9390594560707]},"#dd0000":{"lch":[46.1435564305616239,155.182233977468201,12.1770506300617765],"luv":[46.1435564305616239,151.69070515099267,32.7330981276182555],"rgb":[0.866666666666666696,0,0],"xyz":[0.298181282529475455,0.153749723804264049,0.0139772476185688679],"hpluv":[12.1770506300617765,426.746789183125316,46.1435564305616239],"hsluv":[12.1770506300617765,100.000000000002217,46.1435564305616239]},"#dd0011":{"lch":[46.1980288678146636,153.577384001942391,11.5987087531524224],"luv":[46.1980288678146636,150.441300178721519,30.8776306962803169],"rgb":[0.866666666666666696,0,0.0666666666666666657],"xyz":[0.29919294802911256,0.154154390004118902,0.0193053525833244977],"hpluv":[11.5987087531524224,421.835520233675084,46.1980288678146636],"hsluv":[11.5987087531524224,99.9999999999964473,46.1980288678146636]},"#dd0022":{"lch":[46.2987546285526292,150.712226421231577,10.5179424282654246],"luv":[46.2987546285526292,148.17992816752087,27.5115263319381462],"rgb":[0.866666666666666696,0,0.133333333333333331],"xyz":[0.301068306167589617,0.15490453325950973,0.0291822387793036972],"hpluv":[10.5179424282654246,413.065099977246746,46.2987546285526292],"hsluv":[10.5179424282654246,99.9999999999964615,46.2987546285526292]},"#dd0033":{"lch":[46.4638920568500637,146.293058552209629,8.71533624525386585],"luv":[46.4638920568500637,144.603865814948932,22.1671146505918131],"rgb":[0.866666666666666696,0,0.2],"xyz":[0.304156056900047322,0.156139633552492829,0.0454443926369148404],"hpluv":[8.71533624525386585,399.528220173505417,46.4638920568500637],"hsluv":[8.71533624525386585,99.9999999999966,46.4638920568500637]},"#dd0044":{"lch":[46.7007828741672242,140.527307525302433,6.06736355557067153],"luv":[46.7007828741672242,139.740117429456177,14.853408400522655],"rgb":[0.866666666666666696,0,0.266666666666666663],"xyz":[0.308614052144266238,0.157922831650180423,0.0689231675898014789],"hpluv":[6.06736355557067153,381.835137536210595,46.7007828741672242],"hsluv":[6.06736355557067153,99.9999999999967315,46.7007828741672242]},"#dd0055":{"lch":[47.0148448700731194,133.854751810486647,2.4577968894866693],"luv":[47.0148448700731194,133.731616129679537,5.74015936982693],"rgb":[0.866666666666666696,0,0.333333333333333315],"xyz":[0.314576466183628223,0.160307797265925256,0.10032521486377538],"hpluv":[2.4577968894866693,361.275168455412427,47.0148448700731194],"hsluv":[2.4577968894866693,99.9999999999969873,47.0148448700731194]},"#dd0066":{"lch":[47.4099042919878073,126.898325188331157,357.792852491951692],"luv":[47.4099042919878073,126.80418183984473,-4.88716722969802841],"rgb":[0.866666666666666696,0,0.4],"xyz":[0.322161461957136408,0.163341795575328547,0.140272859270919342],"hpluv":[357.792852491951692,339.645713706877359,47.4099042919878073],"hsluv":[357.792852491951692,99.9999999999972857,47.4099042919878073]},"#dd0077":{"lch":[47.8883827301537,120.388643903007392,352.036106438093952],"luv":[47.8883827301537,119.227564738695264,-16.6797298325047478],"rgb":[0.866666666666666696,0,0.466666666666666674],"xyz":[0.331475474977338314,0.16706740078340937,0.189326661177317251],"hpluv":[352.036106438093952,319.002934776287759,47.8883827301537],"hsluv":[352.036106438093952,99.9999999999974136,47.8883827301537]},"#dd0088":{"lch":[48.4514347566520058,115.064311489444805,345.260130057314882],"luv":[48.4514347566520058,111.277652945923506,-29.2759241252361342],"rgb":[0.866666666666666696,0,0.533333333333333326],"xyz":[0.342615892079282114,0.171523567624186968,0.247999524580889419],"hpluv":[345.260130057314882,301.351479235409442,48.4514347566520058],"hsluv":[345.260130057314882,99.9999999999976836,48.4514347566520058]},"#dd0099":{"lch":[49.0990738312553816,111.554442433955828,337.69359677942],"luv":[49.0990738312553816,103.206522936464793,-42.3415546492536166],"rgb":[0.866666666666666696,0,0.6],"xyz":[0.355672856188354869,0.176746353267816125,0.316766202222007354],"hpluv":[337.69359677942,288.305479360883112,49.0990738312553816],"hsluv":[337.69359677942,99.9999999999979252,49.0990738312553816]},"#dd00aa":{"lch":[49.8303011832281442,110.265023964610052,329.72204926251294],"luv":[49.8303011832281442,95.2237329190616606,-55.5951094870335041],"rgb":[0.866666666666666696,0,0.66666666666666663],"xyz":[0.370730549153607369,0.18276943045391722,0.396070051839005954],"hpluv":[329.72204926251294,280.791263168904948,49.8303011832281442],"hsluv":[329.72204926251294,99.9999999999981526,49.8303011832281442]},"#dd00bb":{"lch":[50.6432416523731064,111.311454300018838,321.811503537589374],"luv":[50.6432416523731064,87.4886923962170613,-68.8183737179635244],"rgb":[0.866666666666666696,0,0.733333333333333282],"xyz":[0.387868141260944044,0.189624467296851978,0.486328036937647701],"hpluv":[321.811503537589374,278.905890401213071,50.6432416523731064],"hsluv":[321.811503537589374,99.9999999999984,50.6432416523731064]},"#dd00cc":{"lch":[51.5352850119508901,114.534817141075266,314.3830496716472],"luv":[51.5352850119508901,80.1116001600253753,-81.8557014345352201],"rgb":[0.866666666666666696,0,0.8],"xyz":[0.407160516704665798,0.19734141747434078,0.587934547607917857],"hpluv":[314.3830496716472,282.014975724645751,51.5352850119508901],"hsluv":[314.3830496716472,99.9999999999986215,51.5352850119508901]},"#dd00dd":{"lch":[52.5032286812834883,119.593841400887641,307.715012949243601],"luv":[52.5032286812834883,73.1596596193909647,-94.6062952735996419],"rgb":[0.866666666666666696,0,0.866666666666666696],"xyz":[0.428678842255299286,0.205948747694594314,0.701264395507923854],"hpluv":[307.715012949243601,289.042783730483222,52.5032286812834883],"hsluv":[307.715012949243601,99.9999999999987779,52.5032286812834883]},"#dd00ee":{"lch":[53.5434168792756111,126.080010820296707,301.921476351261958],"luv":[53.5434168792756111,66.6656277920787659,-107.01337860068783],"rgb":[0.866666666666666696,0,0.933333333333333348],"xyz":[0.452491022521474051,0.215473619801064359,0.826675211576447078],"hpluv":[301.921476351261958,298.799235277631283,53.5434168792756111],"hsluv":[301.921476351261958,99.999999999998991,53.5434168792756111]},"#dd00ff":{"lch":[54.6518715304170399,133.605457484958208,296.990855958497434],"luv":[54.6518715304170399,60.6366090811706258,-119.053013019000375],"rgb":[0.866666666666666696,0,1],"xyz":[0.478662070931305417,0.225942039164997055,0.964509399868228923],"hpluv":[296.990855958497434,310.211923209940835,54.6518715304170399],"hsluv":[296.990855958497434,99.99999999999919,54.6518715304170399]},"#dd1100":{"lch":[46.6790301132195,152.538998994032681,12.7564763340959253],"luv":[46.6790301132195,148.773935032481603,33.6817824506429915],"rgb":[0.866666666666666696,0.0666666666666666657,0],"xyz":[0.300185682790403863,0.157758524326120919,0.0146453810388783197],"hpluv":[12.7564763340959253,414.665968881342394,46.6790301132195],"hsluv":[12.7564763340959253,100.000000000002373,46.6790301132195]},"#dd1111":{"lch":[46.7325769897078942,150.969760125239,12.1770506300617818],"luv":[46.7325769897078942,147.573010021229663,31.8445471870185592],"rgb":[0.866666666666666696,0.0666666666666666657,0.0666666666666666657],"xyz":[0.301197348290040967,0.158163190525975772,0.0199734860036339529],"hpluv":[12.1770506300617818,409.92986676092562,46.7325769897078942],"hsluv":[12.1770506300617818,96.0592738250283,46.7325769897078942]},"#dd1122":{"lch":[46.8315975390355774,148.166934443607602,11.093898425687982],"luv":[46.8315975390355774,145.398162733087418,28.509905932130728],"rgb":[0.866666666666666696,0.0666666666666666657,0.133333333333333331],"xyz":[0.303072706428518,0.1589133337813666,0.0298503721996131455],"hpluv":[11.093898425687982,401.468660625611221,46.8315975390355774],"hsluv":[11.093898425687982,96.1199649520447821,46.8315975390355774]},"#dd1133":{"lch":[46.9939567691892393,143.840838530693645,9.28627571582045697],"luv":[46.9939567691892393,141.955717705878527,23.2112265902085468],"rgb":[0.866666666666666696,0.0666666666666666657,0.2],"xyz":[0.30616045716097573,0.160148434074349699,0.0461125260572242957],"hpluv":[9.28627571582045697,388.400266865181436,46.9939567691892393],"hsluv":[9.28627571582045697,96.2159198798013477,46.9939567691892393]},"#dd1144":{"lch":[47.2268997120704555,138.191174032002039,6.62861883301083665],"luv":[47.2268997120704555,137.267398010546174,15.951865839373701],"rgb":[0.866666666666666696,0.0666666666666666657,0.266666666666666663],"xyz":[0.310618452405194645,0.161931632172037293,0.0695913010101109342],"hpluv":[6.62861883301083665,371.304486157060069,47.2268997120704555],"hsluv":[6.62861883301083665,96.346372634165391,47.2268997120704555]},"#dd1155":{"lch":[47.5357948285950442,131.646215003298352,3.00154982487266553],"luv":[47.5357948285950442,131.465612026054913,6.89338663571585908],"rgb":[0.866666666666666696,0.0666666666666666657,0.333333333333333315],"xyz":[0.31658086644455663,0.164316597787782126,0.100993348284084836],"hpluv":[3.00154982487266553,351.420379681935685,47.5357948285950442],"hsluv":[3.00154982487266553,96.5074087268808114,47.5357948285950442]},"#dd1166":{"lch":[47.9244613368761776,124.817323026056556,358.307054390798669],"luv":[47.9244613368761776,124.762840903711279,-3.68750010524401839],"rgb":[0.866666666666666696,0.0666666666666666657,0.4],"xyz":[0.324165862218064815,0.167350596097185417,0.140940992691228811],"hpluv":[358.307054390798669,330.488955339688346,47.9244613368761776],"hsluv":[358.307054390798669,96.6928417837132912,47.9244613368761776]},"#dd1177":{"lch":[48.3953520744879313,118.427317384197096,352.504166614065639],"luv":[48.3953520744879313,117.415279069986227,-15.4493282615978131],"rgb":[0.866666666666666696,0.0666666666666666657,0.466666666666666674],"xyz":[0.333479875238266721,0.17107620130526624,0.189994794597626721],"hpluv":[352.504166614065639,310.51856077863863,48.3953520744879313],"hsluv":[352.504166614065639,96.8952584834877229,48.3953520744879313]},"#dd1188":{"lch":[48.949686611979061,113.213254375126112,345.662599129740954],"luv":[48.949686611979061,109.687147393784173,-28.0351683216148473],"rgb":[0.866666666666666696,0.0666666666666666657,0.533333333333333326],"xyz":[0.344620292340210521,0.175532368146043838,0.248667658001198888],"hpluv":[345.662599129740954,293.48552443008623,48.949686611979061],"hsluv":[345.662599129740954,97.1070447043031209,48.949686611979061]},"#dd1199":{"lch":[49.5875717372425,109.808639676001164,338.012756373247385],"luv":[49.5875717372425,101.821953610845213,-41.1123717433662961],"rgb":[0.866666666666666696,0.0666666666666666657,0.6],"xyz":[0.357677256449283276,0.180755153789673,0.317434335642316767],"hpluv":[338.012756373247385,280.997849503034615,49.5875717372425],"hsluv":[338.012756373247385,97.321211179253126,49.5875717372425]},"#dd11aa":{"lch":[50.3081241313593779,108.626384639058173,329.948207544292131],"luv":[50.3081241313593779,94.0240738412992556,-54.3982074892042462],"rgb":[0.866666666666666696,0.0666666666666666657,0.66666666666666663],"xyz":[0.372734949414535777,0.18677823097577409,0.396738185259315368],"hpluv":[329.948207544292131,273.991145484396441,50.3081241313593779],"hsluv":[329.948207544292131,97.5319211216277751,50.3081241313593779]},"#dd11bb":{"lch":[51.1095995740137,109.78676639377484,321.947120969557943],"luv":[51.1095995740137,86.4507346157054855,-67.6712979010019495],"rgb":[0.866666666666666696,0.0666666666666666657,0.733333333333333282],"xyz":[0.389872541521872451,0.193633267818708849,0.486996170357957114],"hpluv":[321.947120969557943,272.57551535007633,51.1095995740137],"hsluv":[321.947120969557943,97.7347175386083791,51.1095995740137]},"#dd11cc":{"lch":[51.9895276454598303,113.13117809908816,314.441471026924035],"luv":[51.9895276454598303,79.2122218564644527,-80.7718228508547469],"rgb":[0.866666666666666696,0.0666666666666666657,0.8],"xyz":[0.409164916965594205,0.20135021799619765,0.588602681028227326],"hpluv":[314.441471026924035,276.12502270002949,51.9895276454598303],"hsluv":[314.441471026924035,97.9265130550616,51.9895276454598303]},"#dd11dd":{"lch":[52.9448482611329325,118.314931067086022,307.715012949243601],"luv":[52.9448482611329325,72.3773062506166553,-93.594596282658145],"rgb":[0.866666666666666696,0.0666666666666666657,0.866666666666666696],"xyz":[0.430683242516227693,0.209957548216451184,0.701932528928233324],"hpluv":[307.715012949243601,283.566663729067216,52.9448482611329325],"hsluv":[307.715012949243601,98.1054292618058525,52.9448482611329325]},"#dd11ee":{"lch":[53.9720454332022257,124.924845967379298,301.881652150577509],"luv":[53.9720454332022257,65.9811112999591103,-106.078791902980541],"rgb":[0.866666666666666696,0.0666666666666666657,0.933333333333333348],"xyz":[0.454495422782402458,0.219482420322921229,0.827343344996756547],"hpluv":[301.881652150577509,293.71036424495378,53.9720454332022257],"hsluv":[301.881652150577509,98.2705657762439841,53.9720454332022257]},"#dd11ff":{"lch":[55.067273793018515,132.56906123155207,296.926443611211937],"luv":[55.067273793018515,60.0334023394080774,-118.197066796810802],"rgb":[0.866666666666666696,0.0666666666666666657,1],"xyz":[0.480666471192233824,0.229950839686853925,0.965177533288538392],"hpluv":[296.926443611211937,305.483621811531123,55.067273793018515],"hsluv":[296.926443611211937,99.9999999999990763,55.067273793018515]},"#dd2200":{"lch":[47.6481385708110494,147.881667770992,13.8451074484812633],"luv":[47.6481385708110494,143.585141583480663,35.3877772568702937],"rgb":[0.866666666666666696,0.133333333333333331,0],"xyz":[0.303901306525171777,0.165189771795656887,0.0158839222838009289],"hpluv":[13.8451074484812633,393.829031299888356,47.6481385708110494],"hsluv":[13.8451074484812633,100.000000000002302,47.6481385708110494]},"#dd2211":{"lch":[47.7000692420668,146.371743885583,13.2640103652051735],"luv":[47.7000692420668,142.467011758872331,33.583298953557744],"rgb":[0.866666666666666696,0.133333333333333331,0.0666666666666666657],"xyz":[0.304912972024808882,0.16559443799551174,0.0212120272485565586],"hpluv":[13.2640103652051735,389.383517616197651,47.7000692420668],"hsluv":[13.2640103652051735,96.2235359913314596,47.7000692420668]},"#dd2222":{"lch":[47.796111526211412,143.672697420673273,12.1770506300617871],"luv":[47.796111526211412,140.440127868319678,30.3053537920670948],"rgb":[0.866666666666666696,0.133333333333333331,0.133333333333333331],"xyz":[0.306788330163285938,0.166344581250902568,0.0310889134445357582],"hpluv":[12.1770506300617871,381.435408792809369,47.796111526211412],"hsluv":[12.1770506300617871,89.3821391188339618,47.796111526211412]},"#dd2233":{"lch":[47.9536166692339805,139.501418135148583,10.3611027729364178],"luv":[47.9536166692339805,137.226679529052944,25.0895214611231978],"rgb":[0.866666666666666696,0.133333333333333331,0.2],"xyz":[0.309876080895743644,0.167579681543885667,0.0473510673021469],"hpluv":[10.3611027729364178,369.144652707036585,47.9536166692339805],"hsluv":[10.3611027729364178,89.634195646670733,47.9536166692339805]},"#dd2244":{"lch":[48.1796580724099073,134.044487106872765,7.68678657448498281],"luv":[48.1796580724099073,132.839973125453383,17.9294747210675],"rgb":[0.866666666666666696,0.133333333333333331,0.266666666666666663],"xyz":[0.314334076139962559,0.169362879641573261,0.0708298422550335399],"hpluv":[7.68678657448498281,353.040533161258963,48.1796580724099073],"hsluv":[7.68678657448498281,89.9776949827144819,48.1796580724099073]},"#dd2255":{"lch":[48.4795139291676236,127.710640494506933,4.02871777991100277],"luv":[48.4795139291676236,127.395062601571667,8.9724979943620351],"rgb":[0.866666666666666696,0.133333333333333331,0.333333333333333315],"xyz":[0.320296490179324544,0.171747845257318094,0.102231889529007441],"hpluv":[4.02871777991100277,334.278275235680212,48.4795139291676236],"hsluv":[4.02871777991100277,90.4030378986951746,48.4795139291676236]},"#dd2266":{"lch":[48.8569858046774499,121.091623353111601,359.280669781128381],"luv":[48.8569858046774499,121.082080247128843,-1.52022673298942879],"rgb":[0.866666666666666696,0.133333333333333331,0.4],"xyz":[0.32788148595283273,0.174781843566721384,0.142179533936151403],"hpluv":[359.280669781128381,314.504423311283745,48.8569858046774499],"hsluv":[359.280669781128381,90.8946273178398627,48.8569858046774499]},"#dd2277":{"lch":[49.3145747506863046,114.897314975199777,353.392641366134796],"luv":[49.3145747506863046,114.134166521370943,-13.2206286152450421],"rgb":[0.866666666666666696,0.133333333333333331,0.466666666666666674],"xyz":[0.337195498973034635,0.178507448774802208,0.191233335842549312],"hpluv":[353.392641366134796,295.64729776044,49.3145747506863046],"hsluv":[353.392641366134796,91.4334620569677128,49.3145747506863046]},"#dd2288":{"lch":[49.8536069462695934,109.863045744465836,346.42832123602642],"luv":[49.8536069462695934,106.795352255968297,-25.780643063628979],"rgb":[0.866666666666666696,0.133333333333333331,0.533333333333333326],"xyz":[0.348335916074978436,0.182963615615579805,0.24990619924612148],"hpluv":[346.42832123602642,279.636833718457694,49.8536069462695934],"hsluv":[346.42832123602642,91.999736258284841,49.8536069462695934]},"#dd2299":{"lch":[50.4743452384724947,106.631383564155598,338.620922954440232],"luv":[50.4743452384724947,99.2939711585852507,-38.8710593162073792],"rgb":[0.866666666666666696,0.133333333333333331,0.6],"xyz":[0.361392880184051135,0.188186401259208963,0.318672876887239387],"hpluv":[338.620922954440232,268.07337181170567,50.4743452384724947],"hsluv":[338.620922954440232,92.5749897333771088,50.4743452384724947]},"#dd22aa":{"lch":[51.176101525576982,105.62881092572934,330.379319008457628],"luv":[51.176101525576982,91.8248770713425699,-52.2076397514415902],"rgb":[0.866666666666666696,0.133333333333333331,0.66666666666666663],"xyz":[0.376450573149303691,0.194209478445310058,0.397976726504238],"hpluv":[330.379319008457628,261.911470041672374,51.176101525576982],"hsluv":[330.379319008457628,93.1435427232804898,51.176101525576982]},"#dd22bb":{"lch":[51.9573548685870321,106.984993341056935,322.205396597718504],"luv":[51.9573548685870321,84.5409044706425306,-65.5638945721781425],"rgb":[0.866666666666666696,0.133333333333333331,0.733333333333333282],"xyz":[0.393588165256640365,0.201064515288244816,0.488234711602879734],"hpluv":[322.205396597718504,261.285408571692301,51.9573548685870321],"hsluv":[322.205396597718504,93.6931794305449301,51.9573548685870321]},"#dd22cc":{"lch":[52.8158750154556174,110.541708291411879,314.55250800555325],"luv":[52.8158750154556174,77.5519304210182838,-78.7728846745956],"rgb":[0.866666666666666696,0.133333333333333331,0.8],"xyz":[0.412880540700362064,0.208781465465733618,0.58984122227315],"hpluv":[314.55250800555325,265.583456637160452,52.8158750154556174],"hsluv":[314.55250800555325,94.2152138812719073,52.8158750154556174]},"#dd22dd":{"lch":[53.7488483860564088,115.947384169062644,307.715012949243658],"luv":[53.7488483860564088,70.9289965118926204,-91.721716891171],"rgb":[0.866666666666666696,0.133333333333333331,0.866666666666666696],"xyz":[0.434398866250995663,0.217388795685987152,0.703171070173155943],"hpluv":[307.715012949243658,273.735496610715643,53.7488483860564088],"hsluv":[307.715012949243658,94.704144859729837,53.7488483860564088]},"#dd22ee":{"lch":[54.7530025006588374,122.779599443276055,301.806367069585178],"luv":[54.7530025006588374,64.7110170709106,-104.342293961267828],"rgb":[0.866666666666666696,0.133333333333333331,0.933333333333333348],"xyz":[0.458211046517170373,0.226913667792457197,0.828581886241679166],"hpluv":[301.806367069585178,284.549350776984397,54.7530025006588374],"hsluv":[301.806367069585178,95.1571011878196629,54.7530025006588374]},"#dd22ff":{"lch":[55.8247247862810525,130.638613434108407,296.804995701950531],"luv":[55.8247247862810525,58.9121835814083425,-116.601037498200881],"rgb":[0.866666666666666696,0.133333333333333331,1],"xyz":[0.484382094927001794,0.237382087156389893,0.966416074533461],"hpluv":[296.804995701950531,296.950662194199822,55.8247247862810525],"hsluv":[296.804995701950531,99.9999999999989768,55.8247247862810525]},"#dd3300":{"lch":[49.1823134049741526,140.84390252957769,15.6779143459349193],"luv":[49.1823134049741526,135.603943521894649,38.06015476941716],"rgb":[0.866666666666666696,0.2,0],"xyz":[0.310019028614182623,0.17742521597367869,0.0179231629801378106],"hpluv":[15.6779143459349193,363.386194305474646,49.1823134049741526],"hsluv":[15.6779143459349193,100.000000000002331,49.1823134049741526]},"#dd3311":{"lch":[49.2318310772226226,139.415415721210906,15.0950854994101622],"luv":[49.2318310772226226,134.60488288385605,36.3067988748864323],"rgb":[0.866666666666666696,0.2,0.0666666666666666657],"xyz":[0.311030694113819728,0.177829882173533543,0.0232512679448934403],"hpluv":[15.0950854994101622,359.338818773581409,49.2318310772226226],"hsluv":[15.0950854994101622,96.4660724045404834,49.2318310772226226]},"#dd3322":{"lch":[49.3234253076193,136.858666305461554,14.0037238091571297],"luv":[49.3234253076193,132.791226888227897,33.117738516222083],"rgb":[0.866666666666666696,0.2,0.133333333333333331],"xyz":[0.312906052252296785,0.178580025428924372,0.0331281541408726399],"hpluv":[14.0037238091571297,352.093818956611813,49.3234253076193],"hsluv":[14.0037238091571297,90.0546185843159321,49.3234253076193]},"#dd3333":{"lch":[49.4736766963079901,132.899088309008249,12.1770506300618315],"luv":[49.4736766963079901,129.908920002044738,28.0328410488111714],"rgb":[0.866666666666666696,0.2,0.2],"xyz":[0.31599380298475449,0.179815125721907471,0.0493903079984837831],"hpluv":[12.1770506300618315,340.868713502871344,49.4736766963079901],"hsluv":[12.1770506300618315,79.876105021286179,49.4736766963079901]},"#dd3344":{"lch":[49.6893958667399289,127.704341644457742,9.47932118493828391],"luv":[49.6893958667399289,125.960552293014786,21.031836364974712],"rgb":[0.866666666666666696,0.2,0.266666666666666663],"xyz":[0.320451798228973406,0.181598323819595064,0.0728690829513704286],"hpluv":[9.47932118493828391,326.122882655454703,49.6893958667399289],"hsluv":[9.47932118493828391,80.502956859434363,49.6893958667399289]},"#dd3355":{"lch":[49.9757165444531495,121.655077778432485,5.77481987360355742],"luv":[49.9757165444531495,121.037681249067731,12.2408197080725127],"rgb":[0.866666666666666696,0.2,0.333333333333333315],"xyz":[0.326414212268335391,0.183983289435339897,0.10427113022534433],"hpluv":[5.77481987360355742,308.89475746512926,49.9757165444531495],"hsluv":[5.77481987360355742,81.2827465905028674,49.9757165444531495]},"#dd3366":{"lch":[50.3364012453720164,115.314978813651479,0.942739432835561],"luv":[50.3364012453720164,115.29936949267524,1.8972963354308543],"rgb":[0.866666666666666696,0.2,0.4],"xyz":[0.333999208041843576,0.187017287744743188,0.144218774632488278],"hpluv":[0.942739432835561,290.698564526315124,50.3364012453720164],"hsluv":[0.942739432835561,82.1889615211792375,50.3364012453720164]},"#dd3377":{"lch":[50.77400791740952,109.376176789803836,354.916348657894],"luv":[50.77400791740952,108.945933542464203,-9.69183231981436],"rgb":[0.866666666666666696,0.2,0.466666666666666674],"xyz":[0.343313221062045482,0.190742892952824,0.193272576538886187],"hpluv":[354.916348657894,273.35096965093777,50.77400791740952],"hsluv":[354.916348657894,83.1884512053650269,50.77400791740952]},"#dd3388":{"lch":[51.2900053848270545,104.574014460431073,347.747121452304157],"luv":[51.2900053848270545,102.191864987712989,-22.1934051173651383],"rgb":[0.866666666666666696,0.2,0.533333333333333326],"xyz":[0.354453638163989282,0.195199059793601609,0.251945439942458382],"hpluv":[347.747121452304157,258.720214242298141,51.2900053848270545],"hsluv":[347.747121452304157,84.245872474104587,51.2900053848270545]},"#dd3399":{"lch":[51.8848727297214509,101.568582070491487,339.671486537323062],"luv":[51.8848727297214509,95.2425012264059347,-35.2851643605103433],"rgb":[0.866666666666666696,0.2,0.6],"xyz":[0.367510602273062,0.200421845437230767,0.320712117583576262],"hpluv":[339.671486537323062,248.403642764366595,51.8848727297214509],"hsluv":[339.671486537323062,85.3275173092541763,51.8848727297214509]},"#dd33aa":{"lch":[52.5581975758694284,100.811065681036794,331.124654782349864],"luv":[52.5581975758694284,88.2774684157494,-48.6822301651504219],"rgb":[0.866666666666666696,0.2,0.66666666666666663],"xyz":[0.382568295238314537,0.206444922623331861,0.400015967200574862],"hpluv":[331.124654782349864,243.392431352391867,52.5581975758694284],"hsluv":[331.124654782349864,86.4040244757801,52.5581975758694284]},"#dd33bb":{"lch":[53.3087788146031301,102.447919096954379,322.651217662355],"luv":[53.3087788146031301,81.4417156804123579,-62.1516136100020091],"rgb":[0.866666666666666696,0.2,0.733333333333333282],"xyz":[0.399705887345651212,0.21329995946626662,0.490273952299216609],"hpluv":[322.651217662355,243.861776984359892,53.3087788146031301],"hsluv":[322.651217662355,87.4518397844355633,53.3087788146031301]},"#dd33cc":{"lch":[54.1347343907921612,106.321268361530926,314.743497623169446],"luv":[54.1347343907921612,74.8431687457043751,-75.5163041872859253],"rgb":[0.866666666666666696,0.2,0.8],"xyz":[0.418998262789372911,0.221016909643755421,0.59188046296948682],"hpluv":[314.743497623169446,249.220329072313831,54.1347343907921612],"hsluv":[314.743497623169446,88.4535853271675734,54.1347343907921612]},"#dd33dd":{"lch":[55.033612168624586,112.066789743934578,307.715012949243715],"luv":[55.033612168624586,68.5551036430149,-88.6519211749340741],"rgb":[0.866666666666666696,0.2,0.866666666666666696],"xyz":[0.44051658834000651,0.229624239864008955,0.705210310869492818],"hpluv":[307.715012949243715,258.397459164480438,55.033612168624586],"hsluv":[307.715012949243715,89.3976510430439077,55.033612168624586]},"#dd33ee":{"lch":[56.0025007026426351,119.245240694744666,301.678101579798295],"luv":[56.0025007026426351,62.6212128139869506,-101.479116738632214],"rgb":[0.866666666666666696,0.2,0.933333333333333348],"xyz":[0.464328768606181219,0.239149111970479,0.830621126938016],"hpluv":[301.678101579798295,270.192295422478139,56.0025007026426351],"hsluv":[301.678101579798295,90.277343199481848,56.0025007026426351]},"#dd33ff":{"lch":[57.0381364623091116,127.442655532056975,296.59904001960814],"luv":[57.0381364623091116,57.0616979163907772,-113.954346472440875],"rgb":[0.866666666666666696,0.2,1],"xyz":[0.49049981701601264,0.249617531334411696,0.968455315229797886],"hpluv":[296.59904001960814,283.523336448078851,57.0381364623091116],"hsluv":[296.59904001960814,99.9999999999989626,57.0381364623091116]},"#dd4400":{"lch":[51.2775121999195278,131.902040393952689,18.409420821930695],"luv":[51.2775121999195278,125.151834557466444,41.6553305951168156],"rgb":[0.866666666666666696,0.266666666666666663,0],"xyz":[0.318851599097148664,0.19509035693961102,0.0208673531411264039],"hpluv":[18.409420821930695,326.410329295551833,51.2775121999195278],"hsluv":[18.409420821930695,100.000000000002245,51.2775121999195278]},"#dd4411":{"lch":[51.3239968707682124,130.563017922041524,17.8265447991253865],"luv":[51.3239968707682124,124.294382399750674,39.9700907276414128],"rgb":[0.866666666666666696,0.266666666666666663,0.0666666666666666657],"xyz":[0.319863264596785768,0.195495023139465873,0.0261954581058820371],"hpluv":[17.8265447991253865,322.804096021626094,51.3239968707682124],"hsluv":[17.8265447991253865,96.7659447415066154,51.3239968707682124]},"#dd4422":{"lch":[51.4099976690743148,128.162025810787327,16.7333496749677373],"luv":[51.4099976690743148,122.735013936090269,36.9001519513490237],"rgb":[0.866666666666666696,0.266666666666666663,0.133333333333333331],"xyz":[0.321738622735262825,0.196245166394856702,0.0360723443018612297],"hpluv":[16.7333496749677373,316.337811591652041,51.4099976690743148],"hsluv":[16.7333496749677373,90.8878404873512551,51.4099976690743148]},"#dd4433":{"lch":[51.551120550377874,124.432504768689228,14.8985084842763058],"luv":[51.551120550377874,120.249428964759446,31.9925472049216744],"rgb":[0.866666666666666696,0.266666666666666663,0.2],"xyz":[0.324826373467720531,0.197480266687839801,0.0523344981594723729],"hpluv":[14.8985084842763058,306.291581325991444,51.551120550377874],"hsluv":[14.8985084842763058,81.5276169642245634,51.551120550377874]},"#dd4444":{"lch":[51.7538349343952575,119.518854000271219,12.1770506300618191],"luv":[51.7538349343952575,116.829734805674121,25.2105042943215345],"rgb":[0.866666666666666696,0.266666666666666663,0.266666666666666663],"xyz":[0.329284368711939446,0.199263464785527394,0.0758132731123590115],"hpluv":[12.1770506300618191,293.044254198223086,51.7538349343952575],"hsluv":[12.1770506300618191,68.6693518559736,51.7538349343952575]},"#dd4455":{"lch":[52.0230766847265045,113.767549619287195,8.41751308754220773],"luv":[52.0230766847265045,112.542004033713866,16.6539086839248256],"rgb":[0.866666666666666696,0.266666666666666663,0.333333333333333315],"xyz":[0.335246782751301431,0.201648430401272227,0.107215320386332927],"hpluv":[8.41751308754220773,277.499175779034886,52.0230766847265045],"hsluv":[8.41751308754220773,69.8262296658756867,52.0230766847265045]},"#dd4466":{"lch":[52.3625377834239316,107.708396397149357,3.47572472865958737],"luv":[52.3625377834239316,107.51027478189765,6.52989056311981209],"rgb":[0.866666666666666696,0.266666666666666663,0.4],"xyz":[0.342831778524809616,0.204682428710675518,0.147162964793476875],"hpluv":[3.47572472865958737,261.016642983210886,52.3625377834239316],"hsluv":[3.47572472865958737,71.1800009153795088,52.3625377834239316]},"#dd4477":{"lch":[52.7748219535637304,102.013560717275851,357.256373562230806],"luv":[52.7748219535637304,101.896624345108023,-4.88308481282748108],"rgb":[0.866666666666666696,0.266666666666666663,0.466666666666666674],"xyz":[0.352145791545011522,0.208408033918756341,0.196216766699874784],"hpluv":[357.256373562230806,245.284698321799027,52.7748219535637304],"hsluv":[357.256373562230806,72.6848757644217898,52.7748219535637304]},"#dd4488":{"lch":[53.2615487789460502,97.4233940898595137,349.787328406912707],"luv":[53.2615487789460502,95.8798587184095368,-17.273401753155067],"rgb":[0.866666666666666696,0.266666666666666663,0.533333333333333326],"xyz":[0.363286208646955322,0.212864200759533939,0.254889630103446951],"hpluv":[349.787328406912707,232.107295472344475,53.2615487789460502],"hsluv":[349.787328406912707,74.290572198007979,53.2615487789460502]},"#dd4499":{"lch":[53.8234397136373133,94.6288173232078123,341.30539151945959],"luv":[53.8234397136373133,89.63624285692255,-30.330793502376995],"rgb":[0.866666666666666696,0.266666666666666663,0.6],"xyz":[0.376343172756028,0.218086986403163097,0.323656307744564886],"hpluv":[341.30539151945959,223.095746339835301,53.8234397136373133],"hsluv":[341.30539151945959,75.9477058190526577,53.8234397136373133]},"#dd44aa":{"lch":[54.4604007326765327,94.1226543521493539,332.285935566136516],"luv":[54.4604007326765327,83.3248558176969425,-43.7726223255380802],"rgb":[0.866666666666666696,0.266666666666666663,0.66666666666666663],"xyz":[0.391400865721280578,0.224110063589264191,0.402960157361563487],"hpluv":[332.285935566136516,219.307083848265933,54.4604007326765327],"hsluv":[332.285935566136516,77.6118806813578175,54.4604007326765327]},"#dd44bb":{"lch":[55.1716077278512387,96.0796222427451596,323.344264550451],"luv":[55.1716077278512387,77.0786382371216,-57.3600674495728526],"rgb":[0.866666666666666696,0.266666666666666663,0.733333333333333282],"xyz":[0.408538457828617252,0.23096510043219895,0.493218142460205233],"hpluv":[323.344264550451,220.981019921853772,55.1716077278512387],"hsluv":[323.344264550451,79.2461809113807334,55.1716077278512387]},"#dd44cc":{"lch":[55.9555962107488511,100.342448880687911,315.038748994660807],"luv":[55.9555962107488511,71.0007950362134,-70.9048246002984],"rgb":[0.866666666666666696,0.266666666666666663,0.8],"xyz":[0.427830833272338951,0.238682050609687751,0.594824653130475389],"hpluv":[315.038748994660807,227.551915064947707,55.9555962107488511],"hsluv":[315.038748994660807,80.8221578956601547,55.9555962107488511]},"#dd44dd":{"lch":[56.8103543983327484,106.525561993860563,307.715012949243828],"luv":[56.8103543983327484,65.1653443433699664,-84.2684594300729515],"rgb":[0.866666666666666696,0.266666666666666663,0.866666666666666696],"xyz":[0.44934915882297255,0.247289380829941285,0.708154501030481387],"hpluv":[307.715012949243828,237.939016458104504,56.8103543983327484],"hsluv":[307.715012949243828,82.3196529548951474,56.8103543983327484]},"#dd44ee":{"lch":[57.7334174818232384,114.162073161526394,301.482814132357476],"luv":[57.7334174818232384,59.6203198077272134,-97.3570563162323452],"rgb":[0.866666666666666696,0.266666666666666663,0.933333333333333348],"xyz":[0.473161339089147259,0.256814252936411302,0.83356531709900461],"hpluv":[301.482814132357476,250.91920763959763,57.7334174818232384],"hsluv":[301.482814132357476,85.8927976857303577,57.7334174818232384]},"#dd44ff":{"lch":[58.721960397178492,122.814959128704743,296.287773174859751],"luv":[58.721960397178492,54.3922733794591196,-110.113554035820684],"rgb":[0.866666666666666696,0.266666666666666663,1],"xyz":[0.49933238749897868,0.267282672300344,0.971399505390786455],"hpluv":[296.287773174859751,265.393357493052918,58.721960397178492],"hsluv":[296.287773174859751,99.9999999999987779,58.721960397178492]},"#dd5500":{"lch":[53.8905970004369834,121.845910621274882,22.2085433527856502],"luv":[53.8905970004369834,112.806678507237621,46.055175814369008],"rgb":[0.866666666666666696,0.333333333333333315,0],"xyz":[0.330664855811494629,0.218716870368303284,0.0248051053792416147],"hpluv":[22.2085433527856502,286.904453583707834,53.8905970004369834],"hsluv":[22.2085433527856502,100.000000000002217,53.8905970004369834]},"#dd5511":{"lch":[53.9336739056601573,120.58904296901602,21.6306448037720749],"luv":[53.9336739056601573,112.097097503939963,44.4517492948856656],"rgb":[0.866666666666666696,0.333333333333333315,0.0666666666666666657],"xyz":[0.331676521311131733,0.219121536568158137,0.0301332103439972479],"hpluv":[21.6306448037720749,283.71818310283129,53.9336739056601573],"hsluv":[21.6306448037720749,97.0955711707227493,53.9336739056601573]},"#dd5522":{"lch":[54.0133869328819856,118.329807147086328,20.5443811064534074],"luv":[54.0133869328819856,110.804107011743554,41.5258128011568957],"rgb":[0.866666666666666696,0.333333333333333315,0.133333333333333331],"xyz":[0.33355187944960879,0.219871679823548966,0.0400100965399764405],"hpluv":[20.5443811064534074,277.99185559962018,54.0133869328819856],"hsluv":[20.5443811064534074,91.805999212684128,54.0133869328819856]},"#dd5533":{"lch":[54.1442392255445526,114.805940194650788,18.7140712474621722],"luv":[54.1442392255445526,108.736323489647134,36.8349814433582736],"rgb":[0.866666666666666696,0.333333333333333315,0.2],"xyz":[0.336639630182066496,0.221106780116532065,0.0562722503975875837],"hpluv":[18.7140712474621722,269.061420184977408,54.1442392255445526],"hsluv":[18.7140712474621722,83.3546452149230674,54.1442392255445526]},"#dd5544":{"lch":[54.3323026853354207,110.135081135525823,15.9827981501284579],"luv":[54.3323026853354207,105.877744255237971,30.3255563535325479],"rgb":[0.866666666666666696,0.333333333333333315,0.266666666666666663],"xyz":[0.341097625426285411,0.222889978214219658,0.0797510253504742223],"hpluv":[15.9827981501284579,257.221277658214035,54.3323026853354207],"hsluv":[15.9827981501284579,71.6878656400709104,54.3323026853354207]},"#dd5555":{"lch":[54.5822696158357132,104.625049281135261,12.1770506300618937],"luv":[54.5822696158357132,102.271033836367579,22.0689051636128752],"rgb":[0.866666666666666696,0.333333333333333315,0.333333333333333315],"xyz":[0.347060039465647396,0.225274943829964491,0.111153072624448138],"hpluv":[12.1770506300618937,243.233512665758,54.5822696158357132],"hsluv":[12.1770506300618937,61.8784513389384,54.5822696158357132]},"#dd5566":{"lch":[54.8977244977922254,98.7674373059184205,7.11744080010036573],"luv":[54.8977244977922254,98.0063618739055897,12.2376347477602359],"rgb":[0.866666666666666696,0.333333333333333315,0.4],"xyz":[0.354645035239155582,0.228308942139367782,0.151100717031592086],"hpluv":[7.11744080010036573,228.296245111676484,54.8977244977922254],"hsluv":[7.11744080010036573,62.7979151590930655,54.8977244977922254]},"#dd5577":{"lch":[55.2812881935381597,93.2135187108595886,0.661514811515945267],"luv":[55.2812881935381597,93.2073060454778783,1.07618316489082022],"rgb":[0.866666666666666696,0.333333333333333315,0.466666666666666674],"xyz":[0.363959048259357487,0.232034547347448605,0.20015451893799],"hpluv":[0.661514811515945267,213.963687644495565,55.2812881935381597],"hsluv":[0.661514811515945267,63.8225359413096456,55.2812881935381597]},"#dd5588":{"lch":[55.7347110848163538,88.7163187329837,352.791835078768599],"luv":[55.7347110848163538,88.0151786426913532,-11.1316457915027787],"rgb":[0.866666666666666696,0.333333333333333315,0.533333333333333326],"xyz":[0.375099465361301287,0.236490714188226203,0.258827382341562162],"hpluv":[352.791835078768599,201.984054112510194,55.7347110848163538],"hsluv":[352.791835078768599,64.9173177009572,55.7347110848163538]},"#dd5599":{"lch":[56.2589463845586408,86.0173277442407169,343.733753082454825],"luv":[56.2589463845586408,82.5740942724548717,-24.0935598727929836],"rgb":[0.866666666666666696,0.333333333333333315,0.6],"xyz":[0.388156429470374,0.241713499831855361,0.327594059982680097],"hpluv":[343.733753082454825,194.014271994181229,56.2589463845586408],"hsluv":[343.733753082454825,66.0466553819121,56.2589463845586408]},"#dd55aa":{"lch":[56.8542178605490278,85.677853149792881,334.018383993549605],"luv":[56.8542178605490278,77.0187914763158545,-37.5339883290498477],"rgb":[0.866666666666666696,0.333333333333333315,0.66666666666666663],"xyz":[0.403214122435626543,0.247736577017956455,0.406897909599678698],"hpluv":[334.018383993549605,191.225239227061849,56.8542178605490278],"hsluv":[334.018383993549605,67.3075554564469485,56.8542178605490278]},"#dd55bb":{"lch":[57.5200884026389332,87.9206422548043633,324.375348896731964],"luv":[57.5200884026389332,71.4663144117056817,-51.2113780219251638],"rgb":[0.866666666666666696,0.333333333333333315,0.733333333333333282],"xyz":[0.420351714542963217,0.254591613860891242,0.497155894698320444],"hpluv":[324.375348896731964,193.959311397505388,57.5200884026389332],"hsluv":[324.375348896731964,69.5366313504716,57.5200884026389332]},"#dd55cc":{"lch":[58.2555317670128829,92.5910381182408315,315.474469199465034],"luv":[58.2555317670128829,66.0116746837007895,-64.9273374262858596],"rgb":[0.866666666666666696,0.333333333333333315,0.8],"xyz":[0.439644089986684916,0.262308564038380043,0.5987624053685906],"hpluv":[315.474469199465034,201.683843426221756,58.2555317670128829],"hsluv":[315.474469199465034,71.7082017587958802,58.2555317670128829]},"#dd55dd":{"lch":[59.0590075291469532,99.2700295618383848,307.715012949244056],"luv":[59.0590075291469532,60.7268860008133231,-78.5288742174016363],"rgb":[0.866666666666666696,0.333333333333333315,0.866666666666666696],"xyz":[0.461162415537318515,0.270915894258633549,0.712092253268596598],"hpluv":[307.715012949244056,213.290412049590259,59.0590075291469532],"hsluv":[307.715012949244056,73.7919865345850923,59.0590075291469532]},"#dd55ee":{"lch":[59.9285380001613674,107.447476486145689,301.201070052482692],"luv":[59.9285380001613674,55.6624113436061592,-91.905691698915],"rgb":[0.866666666666666696,0.333333333333333315,0.933333333333333348],"xyz":[0.484974595803493225,0.280440766365103566,0.837503069337119821],"hpluv":[301.201070052482692,227.510719406260364,59.9285380001613674],"hsluv":[301.201070052482692,84.9240358585231405,59.9285380001613674]},"#dd55ff":{"lch":[60.8617852443614,116.651127585902827,295.843561463814751],"luv":[60.8617852443614,50.8500320114402413,-104.984569397117028],"rgb":[0.866666666666666696,0.333333333333333315,1],"xyz":[0.511145644213324646,0.29090918572903629,0.975337257628901666],"hpluv":[295.843561463814751,243.211205533984923,60.8617852443614],"hsluv":[295.843561463814751,99.9999999999987,60.8617852443614]},"#dd6600":{"lch":[56.9556719941368783,111.624872970007345,27.247071009398578],"luv":[56.9556719941368783,99.2390381331236568,51.1050445257873349],"rgb":[0.866666666666666696,0.4,0],"xyz":[0.345692913517341105,0.248772985779996625,0.0298144579478569621],"hpluv":[27.247071009398578,248.69286407076,56.9556719941368783],"hsluv":[27.247071009398578,100.000000000002402,56.9556719941368783]},"#dd6611":{"lch":[56.9952083090352204,110.431802069127656,26.6846840374429064],"luv":[56.9952083090352204,98.6698726856829325,49.5927326573774181],"rgb":[0.866666666666666696,0.4,0.0666666666666666657],"xyz":[0.346704579016978209,0.249177651979851478,0.0351425629126125919],"hpluv":[26.6846840374429064,245.864111809588593,56.9952083090352204],"hsluv":[26.6846840374429064,97.4289366186781,56.9952083090352204]},"#dd6622":{"lch":[57.0683850250612181,108.280332786330632,25.6245441521289443],"luv":[57.0683850250612181,97.630674939023308,46.8282156319165637],"rgb":[0.866666666666666696,0.4,0.133333333333333331],"xyz":[0.348579937155455266,0.249927795235242306,0.0450194491085917914],"hpluv":[25.6245441521289443,240.764984433182946,57.0683850250612181],"hsluv":[25.6245441521289443,92.7369917538900239,57.0683850250612181]},"#dd6633":{"lch":[57.1885511035567617,104.905985735707603,23.8291565941278485],"luv":[57.1885511035567617,95.9631904105633566,42.3831561992078036],"rgb":[0.866666666666666696,0.4,0.2],"xyz":[0.351667687887912972,0.251162895528225405,0.0612816029662029346],"hpluv":[23.8291565941278485,232.771873337598265,57.1885511035567617],"hsluv":[23.8291565941278485,85.2149281001260306,57.1885511035567617]},"#dd6644":{"lch":[57.3613500282636153,100.395707721520722,21.1283100845564071],"luv":[57.3613500282636153,93.6466609873464222,36.1884099516133162],"rgb":[0.866666666666666696,0.4,0.266666666666666663],"xyz":[0.356125683132131887,0.252946093625912971,0.0847603779190895801],"hpluv":[21.1283100845564071,222.093121414046323,57.3613500282636153],"hsluv":[21.1283100845564071,74.7790089775498785,57.3613500282636153]},"#dd6655":{"lch":[57.5911977652478555,95.0134939889914136,17.3206113628181804],"luv":[57.5911977652478555,90.7049894048208927,28.2872575034667619],"rgb":[0.866666666666666696,0.4,0.333333333333333315],"xyz":[0.362088097171493872,0.255331059241657832,0.116162425193063482],"hpluv":[17.3206113628181804,209.347849744778358,57.5911977652478555],"hsluv":[17.3206113628181804,61.5516693045169205,57.5911977652478555]},"#dd6666":{"lch":[57.8815358558834703,89.2064417623026742,12.1770506300619559],"luv":[57.8815358558834703,87.1993378887650579,18.8166076552624659],"rgb":[0.866666666666666696,0.4,0.4],"xyz":[0.369673092945002058,0.25836505755106115,0.156110069600207457],"hpluv":[12.1770506300619559,195.566965385494854,57.8815358558834703],"hsluv":[12.1770506300619559,60.6635523422702,57.8815358558834703]},"#dd6677":{"lch":[58.2349645673757834,83.6008411979688901,5.48003957367995387],"luv":[58.2349645673757834,83.2187459143753188,7.98379467713524704],"rgb":[0.866666666666666696,0.4,0.466666666666666674],"xyz":[0.378987105965203963,0.262090662759141946,0.205163871506605366],"hpluv":[5.48003957367995387,182.165511808695555,58.2349645673757834],"hsluv":[5.48003957367995387,61.6238417996400329,58.2349645673757834]},"#dd6688":{"lch":[58.6533262634944208,78.9686504698842,357.125632416080862],"luv":[58.6533262634944208,78.8692993006444,-3.95997283577995],"rgb":[0.866666666666666696,0.4,0.533333333333333326],"xyz":[0.390127523067147763,0.266546829599919544,0.263836734910177506],"hpluv":[357.125632416080862,170.8446551494321,58.6533262634944208],"hsluv":[357.125632416080862,62.6596910240402778,58.6533262634944208]},"#dd6699":{"lch":[59.1377678367746853,76.1279623836736192,347.292482429378936],"luv":[59.1377678367746853,74.2632604984211184,-16.746187531306056],"rgb":[0.866666666666666696,0.4,0.6],"xyz":[0.403184487176220463,0.271769615243548701,0.332603412551295441],"hpluv":[347.292482429378936,163.349798950832565,59.1377678367746853],"hsluv":[347.292482429378936,63.7390009960191435,59.1377678367746853]},"#dd66aa":{"lch":[59.6887956605557406,75.751758533498986,336.577260120739709],"luv":[59.6887956605557406,69.5095811529117,-30.1122408476074845],"rgb":[0.866666666666666696,0.4,0.66666666666666663],"xyz":[0.418242180141473,0.277792692429649823,0.411907262168294042],"hpluv":[336.577260120739709,161.042027442088397,59.6887956605557406],"hsluv":[336.577260120739709,64.8305690383666473,59.6887956605557406]},"#dd66bb":{"lch":[60.3063295400458372,78.1477005551706,325.894443158435308],"luv":[60.3063295400458372,64.706761589723726,-43.8189240697585518],"rgb":[0.866666666666666696,0.4,0.733333333333333282],"xyz":[0.435379772248809693,0.284647729272584582,0.502165247266935788],"hpluv":[325.894443158435308,164.434383230317081,60.3063295400458372],"hsluv":[325.894443158435308,65.9059953936301213,60.3063295400458372]},"#dd66cc":{"lch":[60.9897585015337427,83.1712006992562891,316.109248272524042],"luv":[60.9897585015337427,59.9384091909213694,-57.6613885491638314],"rgb":[0.866666666666666696,0.4,0.8],"xyz":[0.454672147692531392,0.292364679450073384,0.603771757937205944],"hpluv":[316.109248272524042,173.043537218511,60.9897585015337427],"hsluv":[316.109248272524042,66.9408479310096709,60.9897585015337427]},"#dd66dd":{"lch":[61.7379991889007158,90.3518241723814555,307.715012949244283],"luv":[61.7379991889007158,55.2713135142553753,-71.4740094977595675],"rgb":[0.866666666666666696,0.4,0.866666666666666696],"xyz":[0.476190473243165,0.30097200967032689,0.717101605837211942],"hpluv":[307.715012949244283,185.705044478150711,61.7379991889007158],"hsluv":[307.715012949244283,67.9151328937623759,61.7379991889007158]},"#dd66ee":{"lch":[62.5495564285741779,99.1126076890086125,300.803780654240427],"luv":[62.5495564285741779,50.7555210146825431,-85.1304063742412183],"rgb":[0.866666666666666696,0.4,0.933333333333333348],"xyz":[0.500002653509339701,0.310496881776796907,0.842512421905735165],"hpluv":[300.803780654240427,201.068480083703747,62.5495564285741779],"hsluv":[300.803780654240427,83.670703518064812,62.5495564285741779]},"#dd66ff":{"lch":[63.4225848554444696,108.928953372808309,295.226788235463459],"luv":[63.4225848554444696,46.4257694276883512,-98.5401685402585628],"rgb":[0.866666666666666696,0.4,1],"xyz":[0.526173701919171122,0.320965301140729631,0.980346610197517],"hpluv":[295.226788235463459,217.940889521273107,63.4225848554444696],"hsluv":[295.226788235463459,99.9999999999986073,63.4225848554444696]},"#dd7700":{"lch":[60.3985006876916088,102.209421710697811,33.6568691403047779],"luv":[60.3985006876916088,85.0762157619203,56.6463008330327753],"rgb":[0.866666666666666696,0.466666666666666674,0],"xyz":[0.364146651570758706,0.285680461886832382,0.0359657039656626626],"hpluv":[33.6568691403047779,214.735624532269611,60.3985006876916088],"hsluv":[33.6568691403047779,100.000000000002245,60.3985006876916088]},"#dd7711":{"lch":[60.4345564785723894,101.058408313912437,33.1281817520222],"luv":[60.4345564785723894,84.6313647704988,55.2298287886556736],"rgb":[0.866666666666666696,0.466666666666666674,0.0666666666666666657],"xyz":[0.36515831707039581,0.286085128086687235,0.0412938089304182923],"hpluv":[33.1281817520222,212.190746676882327,60.4345564785723894],"hsluv":[33.1281817520222,97.7465438968969238,60.4345564785723894]},"#dd7722":{"lch":[60.5013044729937803,98.9745052833742136,32.1281810047412648],"luv":[60.5013044729937803,83.8175940663154364,52.6361436754539582],"rgb":[0.866666666666666696,0.466666666666666674,0.133333333333333331],"xyz":[0.367033675208872867,0.286835271342078035,0.0511706951263974918],"hpluv":[32.1281810047412648,207.585936448863947,60.5013044729937803],"hsluv":[32.1281810047412648,93.6262478826975126,60.5013044729937803]},"#dd7733":{"lch":[60.6109510167574115,95.6833141687104813,30.4242910043150516],"luv":[60.6109510167574115,82.5076313520097813,48.4539717565960331],"rgb":[0.866666666666666696,0.466666666666666674,0.2],"xyz":[0.370121425941330573,0.288070371635061162,0.067432848984008642],"hpluv":[30.4242910043150516,200.320058173129354,60.6109510167574115],"hsluv":[30.4242910043150516,86.9991150080846722,60.6109510167574115]},"#dd7744":{"lch":[60.7687036553482756,91.2360291121886888,27.8356422373186483],"luv":[60.7687036553482756,80.6791699404734857,42.6014617809804932],"rgb":[0.866666666666666696,0.466666666666666674,0.266666666666666663],"xyz":[0.374579421185549488,0.289853569732748728,0.0909116239368952805],"hpluv":[27.8356422373186483,190.513488615549676,60.7687036553482756],"hsluv":[27.8356422373186483,77.760618312285672,60.7687036553482756]},"#dd7755":{"lch":[60.9786842032445122,85.8448802225428125,24.131655223886618],"luv":[60.9786842032445122,78.3427622472179479,35.096368243717265],"rgb":[0.866666666666666696,0.466666666666666674,0.333333333333333315],"xyz":[0.380541835224911473,0.292238535348493589,0.122313671210869182],"hpluv":[24.131655223886618,178.63875223296418,60.9786842032445122],"hsluv":[24.131655223886618,65.9765814384596894,60.9786842032445122]},"#dd7766":{"lch":[61.2441632046235895,79.8999585154359693,19.0216316495787474],"luv":[61.2441632046235895,75.5370685872685073,26.0414024201977448],"rgb":[0.866666666666666696,0.466666666666666674,0.4],"xyz":[0.388126830998419659,0.295272533657896907,0.162261315618013158],"hpluv":[19.0216316495787474,165.546946717194828,61.2441632046235895],"hsluv":[19.0216316495787474,57.9572057581871576,61.2441632046235895]},"#dd7777":{"lch":[61.5676827516498122,73.9875996712566,12.1770506300619097],"luv":[61.5676827516498122,72.3229127387857318,15.6064473244910626],"rgb":[0.866666666666666696,0.466666666666666674,0.466666666666666674],"xyz":[0.397440844018621564,0.298998138865977703,0.211315117524411067],"hpluv":[12.1770506300619097,152.491436777287873,61.5676827516498122],"hsluv":[12.1770506300619097,58.8480912007490744,61.5676827516498122]},"#dd7788":{"lch":[61.9511315612573,68.8928540500868252,3.33484257213660307],"luv":[61.9511315612573,68.7761927043778769,4.00757485979294081],"rgb":[0.866666666666666696,0.466666666666666674,0.533333333333333326],"xyz":[0.408581261120565364,0.303454305706755301,0.269987980927983207],"hpluv":[3.33484257213660307,141.112101622994089,61.9511315612573],"hsluv":[3.33484257213660307,59.8177792812577849,61.9511315612573]},"#dd7799":{"lch":[62.395798681375723,65.5359342889949659,352.534540584191575],"luv":[62.395798681375723,64.9804103256140309,-8.5149842657693231],"rgb":[0.866666666666666696,0.466666666666666674,0.6],"xyz":[0.421638225229638119,0.308677091350384458,0.338754658569101141],"hpluv":[352.534540584191575,133.27953643418,62.395798681375723],"hsluv":[352.534540584191575,60.8378233331756135,62.395798681375723]},"#dd77aa":{"lch":[62.9024183325334576,64.7691926058513587,340.409048511657261],"luv":[62.9024183325334576,61.0197310981447743,-21.7172909803219412],"rgb":[0.866666666666666696,0.466666666666666674,0.66666666666666663],"xyz":[0.43669591819489062,0.314700168536485581,0.418058508186099742],"hpluv":[340.409048511657261,130.659342151792146,62.9024183325334576],"hsluv":[340.409048511657261,61.8795186032410598,62.9024183325334576]},"#dd77bb":{"lch":[63.4712121738611472,67.0588140204747,328.168414880738283],"luv":[63.4712121738611472,56.973307333119962,-35.3684434115847779],"rgb":[0.866666666666666696,0.466666666666666674,0.733333333333333282],"xyz":[0.453833510302227294,0.321555205379420339,0.508316493284741489],"hpluv":[328.168414880738283,134.065922948238125,63.4712121738611472],"hsluv":[328.168414880738283,62.9156692244191049,63.4712121738611472]},"#dd77cc":{"lch":[64.1019320742502856,72.2937871392105649,317.045265551381931],"luv":[64.1019320742502856,52.9112642996390861,-49.2624580095555586],"rgb":[0.866666666666666696,0.466666666666666674,0.8],"xyz":[0.473125885745949049,0.329272155556909141,0.609923003955011644],"hpluv":[317.045265551381931,143.109736775843601,64.1019320742502856],"hsluv":[317.045265551381931,63.9218174738772262,64.1019320742502856]},"#dd77dd":{"lch":[64.7939046430230547,79.9242419089019904,307.715012949244624],"luv":[64.7939046430230547,48.8924033620837761,-63.225132172198613],"rgb":[0.866666666666666696,0.466666666666666674,0.866666666666666696],"xyz":[0.494644211296582537,0.337879485777162647,0.723252851855017642],"hpluv":[307.715012949244624,156.524995415635317,64.7939046430230547],"hsluv":[307.715012949244624,64.8769154463944,64.7939046430230547]},"#dd77ee":{"lch":[65.5460776792256,89.2673698488479772,300.244676230176196],"luv":[65.5460776792256,44.9634126652007424,-77.116501743983946],"rgb":[0.866666666666666696,0.466666666666666674,0.933333333333333348],"xyz":[0.518456391562757357,0.347404357883632664,0.848663667923540865],"hpluv":[300.244676230176196,172.816560464305326,65.5460776792256],"hsluv":[300.244676230176196,82.07388698168063,65.5460776792256]},"#dd77ff":{"lch":[66.3570680439545,99.7204006423648366,294.377473048092611],"luv":[66.3570680439545,41.1592308753033436,-90.8299290874281837],"rgb":[0.866666666666666696,0.466666666666666674,1],"xyz":[0.544627439972588667,0.357872777247565388,0.98649785621532271],"hpluv":[294.377473048092611,190.693615319177383,66.3570680439545],"hsluv":[294.377473048092611,99.9999999999983373,66.3570680439545]},"#dd8800":{"lch":[64.1467534130096766,94.4821411478558701,41.4445641191571781],"luv":[64.1467534130096766,70.8234804869986192,62.5372657508392],"rgb":[0.866666666666666696,0.533333333333333326,0],"xyz":[0.386219021295729159,0.329825201336773954,0.0433231605406526124],"hpluv":[41.4445641191571781,186.902182331454583,64.1467534130096766],"hsluv":[41.4445641191571781,100.000000000002416,64.1467534130096766]},"#dd8811":{"lch":[64.1795176641247593,93.3565504581455,40.9755438084832377],"luv":[64.1795176641247593,70.4832194968749235,61.2173282886440333],"rgb":[0.866666666666666696,0.533333333333333326,0.0666666666666666657],"xyz":[0.387230686795366263,0.330229867536628807,0.0486512655054082421],"hpluv":[40.9755438084832377,184.581288668542754,64.1795176641247593],"hsluv":[40.9755438084832377,98.0366401848460072,64.1795176641247593]},"#dd8822":{"lch":[64.2401831232140665,91.3094921720035444,40.0852847486271529],"luv":[64.2401831232140665,69.8596876954725303,58.7966614341343359],"rgb":[0.866666666666666696,0.533333333333333326,0.133333333333333331],"xyz":[0.38910604493384332,0.330980010792019608,0.0585281517013874417],"hpluv":[40.0852847486271529,180.363429125237786,64.2401831232140665],"hsluv":[40.0852847486271529,94.440421143342,64.2401831232140665]},"#dd8833":{"lch":[64.3398685532121704,88.0506151089842319,38.5586382769189342],"luv":[64.3398685532121704,68.8529964065635,54.8832916916272],"rgb":[0.866666666666666696,0.533333333333333326,0.2],"xyz":[0.392193795666301,0.332215111085002734,0.0747903055589985849],"hpluv":[38.5586382769189342,173.656703033806934,64.3398685532121704],"hsluv":[38.5586382769189342,88.6389494712849171,64.3398685532121704]},"#dd8844":{"lch":[64.4833562447751376,83.590391105324656,36.2144134416389392],"luv":[64.4833562447751376,67.4417066096926305,49.3859260793323571],"rgb":[0.866666666666666696,0.533333333333333326,0.266666666666666663],"xyz":[0.396651790910519941,0.333998309182690301,0.0982690805118852234],"hpluv":[36.2144134416389392,164.493238171948974,64.4833562447751376],"hsluv":[36.2144134416389392,80.515719620269337,64.4833562447751376]},"#dd8855":{"lch":[64.6744699451661234,78.0792033713498768,32.8038905377638059],"luv":[64.6744699451661234,65.6278986079903746,42.3006019272060527],"rgb":[0.866666666666666696,0.533333333333333326,0.333333333333333315],"xyz":[0.402614204949881926,0.336383274798435161,0.129671127785859125],"hpluv":[32.8038905377638059,153.194023310958244,64.6744699451661234],"hsluv":[32.8038905377638059,70.0933757373770874,64.6744699451661234]},"#dd8866":{"lch":[64.9162913059566762,71.8298791231791114,27.9793586637294176],"luv":[64.9162913059566762,63.4341634455056251,33.69923504798588],"rgb":[0.866666666666666696,0.533333333333333326,0.4],"xyz":[0.410199200723390112,0.33941727310783848,0.169618772193003087],"hpluv":[27.9793586637294176,140.40764710249897,64.9162913059566762],"hsluv":[27.9793586637294176,57.516131894534638,64.9162913059566762]},"#dd8877":{"lch":[65.211273186305,65.3549274640793243,21.2774014292581],"luv":[65.211273186305,60.8999714810578325,23.7162395299384023],"rgb":[0.866666666666666696,0.533333333333333326,0.466666666666666674],"xyz":[0.419513213743592,0.343142878315919275,0.218672574099401],"hpluv":[21.2774014292581,127.173019810527066,65.211273186305],"hsluv":[21.2774014292581,55.3192807564291797,65.211273186305]},"#dd8888":{"lch":[65.5613077882642585,59.4140252364257222,12.17705063006205],"luv":[65.5613077882642585,58.0772370198051675,12.5323954190731097],"rgb":[0.866666666666666696,0.533333333333333326,0.533333333333333326],"xyz":[0.430653630845535818,0.347599045156696873,0.277345437502973191],"hpluv":[12.17705063006205,114.995459986814794,65.5613077882642585],"hsluv":[12.17705063006205,56.217054427929,65.5613077882642585]},"#dd8899":{"lch":[65.9677735951440809,55.0265961591163304,0.371909902430330563],"luv":[65.9677735951440809,55.0254369244830599,0.357178006339119947],"rgb":[0.866666666666666696,0.533333333333333326,0.6],"xyz":[0.443710594954608517,0.352821830800326031,0.34611211514409107],"hpluv":[0.371909902430330563,105.847388780281833,65.9677735951440809],"hsluv":[0.371909902430330563,57.1692646853200088,65.9677735951440809]},"#dd88aa":{"lch":[66.4315725960282,53.3143351650078756,346.342357286170909],"luv":[66.4315725960282,51.8068159744011751,-12.5885723051236678],"rgb":[0.866666666666666696,0.533333333333333326,0.66666666666666663],"xyz":[0.458768287919861073,0.358844907986427153,0.425415964761089671],"hpluv":[346.342357286170909,101.837748961685463,66.4315725960282],"hsluv":[346.342357286170909,58.1497775423036174,66.4315725960282]},"#dd88bb":{"lch":[66.9531637379342754,55.0554122119122695,331.715662007953938],"luv":[66.9531637379342754,48.482176665295448,-26.0878699709014299],"rgb":[0.866666666666666696,0.533333333333333326,0.733333333333333282],"xyz":[0.475905880027197747,0.365699944829361911,0.515673949859731473],"hpluv":[331.715662007953938,104.344182679937973,66.9531637379342754],"hsluv":[331.715662007953938,59.1328526037280824,66.9531637379342754]},"#dd88cc":{"lch":[67.5325957217288391,60.2482932018326949,318.477460357427788],"luv":[67.5325957217288391,45.1075955230381,-39.9394749572899741],"rgb":[0.866666666666666696,0.533333333333333326,0.8],"xyz":[0.495198255470919446,0.373416895006850713,0.617280460530001629],"hpluv":[318.477460357427788,113.206309259525241,67.5325957217288391],"hsluv":[318.477460357427788,60.0943355072680134,67.5325957217288391]},"#dd88dd":{"lch":[68.1695406599531566,68.219499196860184,307.715012949245079],"luv":[68.1695406599531566,41.7322103060295,-53.965940125636024],"rgb":[0.866666666666666696,0.533333333333333326,0.866666666666666696],"xyz":[0.516716581021553,0.382024225227104219,0.730610308430007627],"hpluv":[307.715012949245079,126.986480244117786,68.1695406599531566],"hsluv":[307.715012949245079,61.0124281772922785,68.1695406599531566]},"#dd88ee":{"lch":[68.8633291469121,78.1074456653267504,299.445313850889818],"luv":[68.8633291469121,38.3970440138518896,-68.0179393936650456],"rgb":[0.866666666666666696,0.533333333333333326,0.933333333333333348],"xyz":[0.540528761287727755,0.391549097333574236,0.85602112449853085],"hpluv":[299.445313850889818,143.92748858218269,68.8633291469121],"hsluv":[299.445313850889818,80.0342386911036385,68.8633291469121]},"#dd88ff":{"lch":[69.6129866887261244,89.1875622693819281,293.199992160066699],"luv":[69.6129866887261244,35.1347073752451706,-81.975445111391565],"rgb":[0.866666666666666696,0.533333333333333326,1],"xyz":[0.566699809697559176,0.40201751669750696,0.993855312790312695],"hpluv":[293.199992160066699,162.574846632166981,69.6129866887261244],"hsluv":[293.199992160066699,99.9999999999981242,69.6129866887261244]},"#dd9900":{"lch":[68.1357569139589287,89.1370219700488775,50.3810095729648921],"luv":[68.1357569139589287,56.8408371488252229,68.6624199829113735],"rgb":[0.866666666666666696,0.6,0],"xyz":[0.41208862174819666,0.381564402241709621,0.0519463606914748674],"hpluv":[50.3810095729648921,166.005456049637957,68.1357569139589287],"hsluv":[50.3810095729648921,100.000000000002245,68.1357569139589287]},"#dd9911":{"lch":[68.1654896561650077,88.0318570495471278,50.0002977758109424],"luv":[68.1654896561650077,56.5854364905009248,67.4366089951992507],"rgb":[0.866666666666666696,0.6,0.0666666666666666657],"xyz":[0.413100287247833764,0.381969068441564474,0.0572744656562305],"hpluv":[50.0002977758109424,163.875726960716179,68.1654896561650077],"hsluv":[50.0002977758109424,98.2940371374324826,68.1654896561650077]},"#dd9922":{"lch":[68.2205507365204,86.012937831153792,49.27558445879027],"luv":[68.2205507365204,56.1166821435168472,65.1854543556261774],"rgb":[0.866666666666666696,0.6,0.133333333333333331],"xyz":[0.414975645386310821,0.382719211696955275,0.0671513518522096897],"hpluv":[49.27558445879027,159.988175949224541,68.2205507365204],"hsluv":[49.27558445879027,95.1643810214000325,68.2205507365204]},"#dd9933":{"lch":[68.3110514885433133,82.7730333151944677,48.0261582829398179],"luv":[68.3110514885433133,55.3578808500206918,61.5376313485756867],"rgb":[0.866666666666666696,0.6,0.2],"xyz":[0.418063396118768527,0.383954311989938402,0.0834135057098208399],"hpluv":[48.0261582829398179,153.757824966526499,68.3110514885433133],"hsluv":[48.0261582829398179,90.1021642959546512,68.3110514885433133]},"#dd9944":{"lch":[68.4413718194248,78.2806718730308688,46.0898611008159875],"luv":[68.4413718194248,54.2899414547091936,56.3956190296495805],"rgb":[0.866666666666666696,0.6,0.266666666666666663],"xyz":[0.422521391362987442,0.385737510087625968,0.106892280662707478],"hpluv":[46.0898611008159875,145.136005207448051,68.4413718194248],"hsluv":[46.0898611008159875,82.9860784920926449,68.4413718194248]},"#dd9955":{"lch":[68.615044439797245,72.617894762441864,43.2298844404699452],"luv":[68.615044439797245,52.9102318436571935,49.7379734808277689],"rgb":[0.866666666666666696,0.6,0.333333333333333315],"xyz":[0.428483805402349427,0.388122475703370828,0.138294327936681394],"hpluv":[43.2298844404699452,134.296171447129637,68.615044439797245],"hsluv":[43.2298844404699452,73.8078183466747362,68.615044439797245]},"#dd9966":{"lch":[68.8349542760461333,65.9999398631214262,39.0839575312566296],"luv":[68.8349542760461333,51.2306688139135815,41.6102227200810404],"rgb":[0.866666666666666696,0.6,0.4],"xyz":[0.436068801175857612,0.391156474012774147,0.178241972343825356],"hpluv":[39.0839575312566296,121.667290932950721,68.8349542760461333],"hsluv":[39.0839575312566296,62.6592399312796076,68.8349542760461333]},"#dd9977":{"lch":[69.1034430542988929,58.8170492635600723,33.0939178586399834],"luv":[69.1034430542988929,49.2755524050587468,32.1148753578207291],"rgb":[0.866666666666666696,0.6,0.466666666666666674],"xyz":[0.445382814196059518,0.394882079220854942,0.227295774250223265],"hpluv":[33.0939178586399834,108.004754244465147,69.1034430542988929],"hsluv":[33.0939178586399834,50.7393036295826789,69.1034430542988929]},"#dd9988":{"lch":[69.4223715869125328,51.7141196395305656,24.4437159362198635],"luv":[69.4223715869125328,47.0788901370553745,21.3992587150758773],"rgb":[0.866666666666666696,0.6,0.533333333333333326],"xyz":[0.456523231298003318,0.39933824606163254,0.285968637653795432],"hpluv":[24.4437159362198635,94.5255072345235305,69.4223715869125328],"hsluv":[24.4437159362198635,51.5589665528693786,69.4223715869125328]},"#dd9999":{"lch":[69.7931614924381591,45.7097919546320597,12.1770506300622632],"luv":[69.7931614924381591,44.6813426781189875,9.64171649740066705],"rgb":[0.866666666666666696,0.6,0.6],"xyz":[0.469580195407076073,0.404561031705261698,0.354735315294913311],"hpluv":[12.1770506300622632,83.1066353202273689,69.7931614924381591],"hsluv":[12.1770506300622632,52.4335711570844438,69.7931614924381591]},"#dd99aa":{"lch":[70.2168268189972196,42.2311183685245624,355.977290330288042],"luv":[70.2168268189972196,42.1270745474506256,-2.96259155636920823],"rgb":[0.866666666666666696,0.6,0.66666666666666663],"xyz":[0.484637888372328574,0.41058410889136282,0.434039164911911912],"hpluv":[355.977290330288042,76.3186553239153369,70.2168268189972196],"hsluv":[355.977290330288042,53.3392978779897788,70.2168268189972196]},"#dd99bb":{"lch":[70.694001085559151,42.6623948649138427,337.661645838825223],"luv":[70.694001085559151,39.4608168046039651,-16.2149274658665163],"rgb":[0.866666666666666696,0.6,0.733333333333333282],"xyz":[0.501775480479665248,0.417439145734297579,0.524297150010553659],"hpluv":[337.661645838825223,76.5776430619999502,70.694001085559151],"hsluv":[337.661645838825223,54.2517942883204398,70.694001085559151]},"#dd99cc":{"lch":[71.2249627580945912,47.3730793907595,320.82657583403028],"luv":[71.2249627580945912,36.7253906259007294,-29.9241430008982121],"rgb":[0.866666666666666696,0.6,0.8],"xyz":[0.521067855923387,0.42515609591178638,0.625903660680823815],"hpluv":[320.82657583403028,84.3992741769230719,71.2249627580945912],"hsluv":[320.82657583403028,55.1472527266246075,71.2249627580945912]},"#dd99dd":{"lch":[71.8096607795551876,55.5140341348433424,307.715012949246],"luv":[71.8096607795551876,33.9598410238411077,-43.9151133843462844],"rgb":[0.866666666666666696,0.6,0.866666666666666696],"xyz":[0.54258618147402049,0.433763426132039887,0.739233508580829812],"hpluv":[307.715012949246,98.0977936102115677,71.8096607795551876],"hsluv":[307.715012949246,56.0031828352742878,71.8096607795551876]},"#dd99ee":{"lch":[72.447740927007942,65.8885644567307907,298.26171852853804],"luv":[72.447740927007942,31.1982236173053273,-58.0342465212858656],"rgb":[0.866666666666666696,0.6,0.933333333333333348],"xyz":[0.566398361740195311,0.443288298238509904,0.864644324649353],"hpluv":[298.26171852853804,115.404973126410823,72.447740927007942],"hsluv":[298.26171852853804,77.3800261839098908,72.447740927007942]},"#dd99ff":{"lch":[73.1385732331520302,77.5656763031263,291.532620718417377],"luv":[73.1385732331520302,28.4689992262389602,-72.1522710898123592],"rgb":[0.866666666666666696,0.6,1],"xyz":[0.592569410150026621,0.453756717602442627,1.00247851294113488],"hpluv":[291.532620718417377,134.574391894016571,73.1385732331520302],"hsluv":[291.532620718417377,99.9999999999977689,73.1385732331520302]},"#cc0000":{"lch":[42.5207510295766156,142.998625281495549,12.1770506300617818],"luv":[42.5207510295766156,139.781222041964895,30.163169542547891],"rgb":[0.8,0,0],"xyz":[0.249012838889184379,0.128397245052238429,0.0116724768229302719],"hpluv":[12.1770506300617818,426.746789183124861,42.5207510295766156],"hsluv":[12.1770506300617818,100.000000000002174,42.5207510295766156]},"#cc0011":{"lch":[42.5821659889152784,141.236718626044905,11.4841194603559],"luv":[42.5821659889152784,138.409148973409117,28.119711390930437],"rgb":[0.8,0,0.0666666666666666657],"xyz":[0.250024504388821511,0.128801911252093282,0.0170005817876859033],"hpluv":[11.4841194603559,420.880880123779207,42.5821659889152784],"hsluv":[11.4841194603559,99.9999999999964331,42.5821659889152784]},"#cc0022":{"lch":[42.6956735686566518,138.114600243667155,10.1872609469282853],"luv":[42.6956735686566518,135.937217546775798,24.4277646564013864],"rgb":[0.8,0,0.133333333333333331],"xyz":[0.251899862527298513,0.12955205450748411,0.0268774679836651],"hpluv":[10.1872609469282853,410.482879191578036,42.6956735686566518],"hsluv":[10.1872609469282853,99.9999999999964615,42.6956735686566518]},"#cc0033":{"lch":[42.881611378965772,133.362165770655935,8.01952044887972626],"luv":[42.881611378965772,132.057963211529,18.6054188736068511],"rgb":[0.8,0,0.2],"xyz":[0.254987613259756274,0.130787154800467209,0.0431396218412762461],"hpluv":[8.01952044887972626,394.639788400466045,42.881611378965772],"hsluv":[8.01952044887972626,99.9999999999966604,42.881611378965772]},"#cc0044":{"lch":[43.1480085091585153,127.29097956278504,4.82801781999359658],"luv":[43.1480085091585153,126.839328429887985,10.7134607624411853],"rgb":[0.8,0,0.266666666666666663],"xyz":[0.259445608503975134,0.132570352898154803,0.0666183967941628846],"hpluv":[4.82801781999359658,374.34858804079829,43.1480085091585153],"hsluv":[4.82801781999359658,99.9999999999967741,43.1480085091585153]},"#cc0055":{"lch":[43.5005971125795,120.485699890795146,0.473888563816867114],"luv":[43.5005971125795,120.481578818580687,0.996515708296922487],"rgb":[0.8,0,0.333333333333333315],"xyz":[0.265408022543337119,0.134955318513899636,0.0980204440681367861],"hpluv":[0.473888563816867114,351.463000970195878,43.5005971125795],"hsluv":[0.473888563816867114,99.999999999997,43.5005971125795]},"#cc0066":{"lch":[43.9431844272177372,113.726547538665841,354.863826263116096],"luv":[43.9431844272177372,113.269906269789104,-10.1811565500985228],"rgb":[0.8,0,0.4],"xyz":[0.272993018316845304,0.137989316823302927,0.137968088475280748],"hpluv":[354.863826263116096,328.404920869645196,43.9431844272177372],"hsluv":[354.863826263116096,99.9999999999972857,43.9431844272177372]},"#cc0077":{"lch":[44.4778741065655,107.874648109024193,348.012259047653401],"luv":[44.4778741065655,105.522124609829902,-22.4058234053856609],"rgb":[0.8,0,0.466666666666666674],"xyz":[0.28230703133704721,0.14171492203138375,0.187021890381678657],"hpluv":[348.012259047653401,307.761788629886667,44.4778741065655],"hsluv":[348.012259047653401,99.9999999999975273,44.4778741065655]},"#cc0088":{"lch":[45.1052440924579,103.725434836726933,340.1176986346278],"luv":[45.1052440924579,97.5426962017022703,-35.2758876538989838],"rgb":[0.8,0,0.533333333333333326],"xyz":[0.293447448438991065,0.146171088872161348,0.245694753785250825],"hpluv":[340.1176986346278,291.808241377507443,45.1052440924579],"hsluv":[340.1176986346278,99.9999999999978,45.1052440924579]},"#cc0099":{"lch":[45.8245205562958589,101.850048541314862,331.598662995615],"luv":[45.8245205562958589,89.5911194129305102,-48.4444394147173441],"rgb":[0.8,0,0.6],"xyz":[0.306504412548063765,0.151393874515790505,0.314461431426368732],"hpluv":[331.598662995615,282.034759885138044,45.8245205562958589],"hsluv":[331.598662995615,99.9999999999981,45.8245205562958589]},"#cc00aa":{"lch":[46.633760692471931,102.477609530343315,323.022725489580409],"luv":[46.633760692471931,81.8667129915779,-61.640098629123905],"rgb":[0.8,0,0.66666666666666663],"xyz":[0.321562105513316321,0.1574169517018916,0.393765281043367332],"hpluv":[323.022725489580409,278.848217687739293,46.633760692471931],"hsluv":[323.022725489580409,99.9999999999983658,46.633760692471931]},"#cc00bb":{"lch":[47.5300446684938933,105.484027274260768,314.937463984289479],"luv":[47.5300446684938933,74.5070162947061903,-74.6698368342758414],"rgb":[0.8,0,0.733333333333333282],"xyz":[0.33869969762065294,0.164271988544826358,0.484023266142009079],"hpluv":[314.937463984289479,281.616311803476265,47.5300446684938933],"hsluv":[314.937463984289479,99.9999999999986,47.5300446684938933]},"#cc00cc":{"lch":[48.5096711653281147,110.497164945278598,307.715012949243601],"luv":[48.5096711653281147,67.5949102529980621,-87.4102486487325],"rgb":[0.8,0,0.8],"xyz":[0.357992073064374694,0.17198893872231516,0.585629776812279235],"hpluv":[307.715012949243601,289.042783730483393,48.5096711653281147],"hsluv":[307.715012949243601,99.9999999999988,48.5096711653281147]},"#cc00dd":{"lch":[49.5683488162236614,117.049051317219835,301.506761454082039],"luv":[49.5683488162236614,61.1697383356450075,-99.7935044289451],"rgb":[0.8,0,0.866666666666666696],"xyz":[0.379510398615008238,0.180596268942568694,0.698959624712285232],"hpluv":[301.506761454082039,299.64205877637869,49.5683488162236614],"hsluv":[301.506761454082039,99.9999999999990337,49.5683488162236614]},"#cc00ee":{"lch":[50.7013760136427862,124.695255359169607,296.294949026353493],"luv":[50.7013760136427862,55.2390203059142522,-111.792474454818787],"rgb":[0.8,0,0.933333333333333348],"xyz":[0.403322578881182947,0.190121141049038739,0.824370440780808456],"hpluv":[296.294949026353493,312.082566880879938,50.7013760136427862],"hsluv":[296.294949026353493,99.99999999999919,50.7013760136427862]},"#cc00ff":{"lch":[51.9038030272213,133.072735088441448,291.971633700566258],"luv":[51.9038030272213,49.7888328026579075,-123.407556300526],"rgb":[0.8,0,1],"xyz":[0.429493627291014368,0.200589560412971435,0.962204629072590301],"hpluv":[291.971633700566258,325.333832743425603,51.9038030272213],"hsluv":[291.971633700566258,99.9999999999993321,51.9038030272213]},"#cc1100":{"lch":[43.1235624482234172,140.134259476931788,12.8715382160273855],"luv":[43.1235624482234172,136.61296213687416,31.2171307992428524],"rgb":[0.8,0.0666666666666666657,0],"xyz":[0.251017239150112814,0.132406045574095299,0.0123406102432397219],"hpluv":[12.8715382160273855,412.352867097941,43.1235624482234172],"hsluv":[12.8715382160273855,100.000000000002245,43.1235624482234172]},"#cc1111":{"lch":[43.1837333530957892,138.41807101963343,12.1770506300617676],"luv":[43.1837333530957892,135.303728142340162,29.196978192614182],"rgb":[0.8,0.0666666666666666657,0.0666666666666666657],"xyz":[0.252028904649749919,0.132810711773950152,0.0176687152079953516],"hpluv":[12.1770506300617676,406.735363437937394,43.1837333530957892],"hsluv":[12.1770506300617676,95.3107026807431197,43.1837333530957892]},"#cc1122":{"lch":[43.294951674171287,135.375047793376126,10.8766574447476163],"luv":[43.294951674171287,132.943125696930394,25.5446451333550044],"rgb":[0.8,0.0666666666666666657,0.133333333333333331],"xyz":[0.253904262788227,0.13356085502934098,0.0275456014039745511],"hpluv":[10.8766574447476163,396.771701832449367,43.294951674171287],"hsluv":[10.8766574447476163,95.396390587568618,43.294951674171287]},"#cc1133":{"lch":[43.4771672841157724,130.73841758888139,8.7012157385065958],"luv":[43.4771672841157724,129.233706917218683,19.7783424502448213],"rgb":[0.8,0.0666666666666666657,0.2],"xyz":[0.256992013520684681,0.134795955322324079,0.0438077552615856944],"hpluv":[8.7012157385065958,381.576227833431062,43.4771672841157724],"hsluv":[8.7012157385065958,95.5308510527687389,43.4771672841157724]},"#cc1144":{"lch":[43.7382910834512586,124.807582872189826,5.49437317543092796],"luv":[43.7382910834512586,124.234167693991893,11.9500761411646046],"rgb":[0.8,0.0666666666666666657,0.266666666666666663],"xyz":[0.261450008764903596,0.136579153420011673,0.0672865302144723398],"hpluv":[5.49437317543092796,362.091632024479338,43.7382910834512586],"hsluv":[5.49437317543092796,95.7116850897169229,43.7382910834512586]},"#cc1155":{"lch":[44.0840061747103107,118.151091154502552,1.11194247693657511],"luv":[44.0840061747103107,118.128842001262925,2.29282106589917234],"rgb":[0.8,0.0666666666666666657,0.333333333333333315],"xyz":[0.267412422804265582,0.138964119035756506,0.0986885774884462413],"hpluv":[1.11194247693657511,340.091681007194666,44.0840061747103107],"hsluv":[1.11194247693657511,95.9318436200579754,44.0840061747103107]},"#cc1166":{"lch":[44.5181325219627837,111.53522478210337,355.453854482233226],"luv":[44.5181325219627837,111.184314904818763,-8.84050260677650712],"rgb":[0.8,0.0666666666666666657,0.4],"xyz":[0.274997418577773767,0.141998117345159797,0.138636221895590217],"hpluv":[355.453854482233226,317.917500588946211,44.5181325219627837],"hsluv":[355.453854482233226,96.1812476973727115,44.5181325219627837]},"#cc1177":{"lch":[45.0428415016287857,105.814757555455103,348.528515458334311],"luv":[45.0428415016287857,103.700981473984271,-21.0444614531261323],"rgb":[0.8,0.0666666666666666657,0.466666666666666674],"xyz":[0.284311431597975672,0.14572372255324062,0.187690023801988126],"hpluv":[348.528515458334311,298.098498005115459,45.0428415016287857],"hsluv":[348.528515458334311,96.4486017572014589,45.0428415016287857]},"#cc1188":{"lch":[45.6588256994622341,101.788242110562607,340.533613155211185],"luv":[45.6588256994622341,95.9697371205835594,-33.9213176183443323],"rgb":[0.8,0.0666666666666666657,0.533333333333333326],"xyz":[0.295451848699919473,0.150179889394018218,0.246362887205560266],"hpluv":[340.533613155211185,282.886487347344485,45.6588256994622341],"hsluv":[340.533613155211185,96.7230145871901215,45.6588256994622341]},"#cc1199":{"lch":[46.3654632546324876,100.035938879036408,331.896400713626349],"luv":[46.3654632546324876,88.2414291467186,-47.1236591273953138],"rgb":[0.8,0.0666666666666666657,0.6],"xyz":[0.308508812808992228,0.155402675037647375,0.315129564846678201],"hpluv":[331.896400713626349,273.779405248492822,46.3654632546324876],"hsluv":[331.896400713626349,96.9951405388504355,46.3654632546324876]},"#cc11aa":{"lch":[47.1609900317596882,100.794975336059878,323.201580807901109],"luv":[47.1609900317596882,80.7113646178594735,-60.3763420100941488],"rgb":[0.8,0.0666666666666666657,0.66666666666666663],"xyz":[0.323566505774244728,0.16142575222374847,0.394433414463676801],"hpluv":[323.201580807901109,271.203503720358924,47.1609900317596882],"hsluv":[323.201580807901109,97.2577546113476075,47.1609900317596882]},"#cc11bb":{"lch":[48.0426807208370548,103.942897448445919,315.013990059648165],"luv":[48.0426807208370548,73.5166718264647727,-73.4807790754699681],"rgb":[0.8,0.0666666666666666657,0.733333333333333282],"xyz":[0.340704097881581403,0.168280789066683228,0.484691399562318548],"hpluv":[315.013990059648165,274.540811344802705,48.0426807208370548],"hsluv":[315.013990059648165,97.5058443216483,48.0426807208370548]},"#cc11cc":{"lch":[49.0070341259591515,109.103198367120783,307.715012949243601],"luv":[49.0070341259591515,66.7421730285370387,-86.3075328888743769],"rgb":[0.8,0.0666666666666666657,0.8],"xyz":[0.359996473325303157,0.17599773924417203,0.586297910232588704],"hpluv":[307.715012949243601,282.499958642668389,49.0070341259591515],"hsluv":[307.715012949243601,97.7363817897909541,49.0070341259591515]},"#cc11dd":{"lch":[50.0499556366759037,115.801352096543823,301.456118533327128],"luv":[50.0499556366759037,60.4304023076134555,-98.7831950502093292],"rgb":[0.8,0.0666666666666666657,0.866666666666666696],"xyz":[0.381514798875936645,0.184605069464425564,0.699627758132594701],"hpluv":[301.456118533327128,293.595408819402792,50.0499556366759037],"hsluv":[301.456118533327128,97.9479403979501342,50.0499556366759037]},"#cc11ee":{"lch":[51.1669298024285837,123.587345912593733,296.214453457233276],"luv":[51.1669298024285837,54.5925079172689109,-110.876012505059137],"rgb":[0.8,0.0666666666666666657,0.933333333333333348],"xyz":[0.40532697914211141,0.194129941570895609,0.825038574201117925],"hpluv":[296.214453457233276,306.495409047480564,51.1669298024285837],"hsluv":[296.214453457233276,98.1402788193950215,51.1669298024285837]},"#cc11ff":{"lch":[52.3531771468210678,132.094610043027387,291.87590029388349],"luv":[52.3531771468210678,49.2181193296501576,-122.582881072651375],"rgb":[0.8,0.0666666666666666657,1],"xyz":[0.431498027551942775,0.204598360934828305,0.96287276249289977],"hpluv":[291.87590029388349,320.170549145207644,52.3531771468210678],"hsluv":[291.87590029388349,99.9999999999991189,52.3531771468210678]},"#cc2200":{"lch":[44.2095884480383674,135.132222138307952,14.1797238149512133],"luv":[44.2095884480383674,131.015027118873576,33.102569825888537],"rgb":[0.8,0.133333333333333331,0],"xyz":[0.254732862884880729,0.139837293043631267,0.0135791514881623328],"hpluv":[14.1797238149512133,387.866054960954045,44.2095884480383674],"hsluv":[14.1797238149512133,100.00000000000226,44.2095884480383674]},"#cc2211":{"lch":[44.2676114068871129,133.490625771231663,13.482935392010976],"luv":[44.2676114068871129,129.81154471696064,31.1241068464871375],"rgb":[0.8,0.133333333333333331,0.0666666666666666657],"xyz":[0.255744528384517833,0.14024195924348612,0.0189072564529179643],"hpluv":[13.482935392010976,382.652016671578622,44.2676114068871129],"hsluv":[13.482935392010976,95.5414705532830197,44.2676114068871129]},"#cc2222":{"lch":[44.3748759613401162,130.576558981694717,12.1770506300617747],"luv":[44.3748759613401162,127.638646515421286,27.5429423121666019],"rgb":[0.8,0.133333333333333331,0.133333333333333331],"xyz":[0.25761988652299489,0.140992102498876948,0.0287841426488971604],"hpluv":[12.1770506300617747,373.394050741154899,44.3748759613401162],"hsluv":[12.1770506300617747,87.4977996802062847,44.3748759613401162]},"#cc2233":{"lch":[44.5506596541482907,126.128431434884163,9.98899557195718657],"luv":[44.5506596541482907,124.216461430809,21.8781152257824267],"rgb":[0.8,0.133333333333333331,0.2],"xyz":[0.260707637255452596,0.142227202791860047,0.0450462965065083071],"hpluv":[9.98899557195718657,359.251162664680805,44.5506596541482907],"hsluv":[9.98899557195718657,87.8457930667704829,44.5506596541482907]},"#cc2244":{"lch":[44.8026641682027602,120.425301369152351,6.75586226508684629],"luv":[44.8026641682027602,119.589119356054482,14.1667124448306829],"rgb":[0.8,0.133333333333333331,0.266666666666666663],"xyz":[0.265165632499671511,0.144010400889547641,0.0685250714593949456],"hpluv":[6.75586226508684629,341.077623618219945,44.8026641682027602],"hsluv":[6.75586226508684629,88.3153597242729,44.8026641682027602]},"#cc2255":{"lch":[45.136480402373536,114.008772215671115,2.323188749975583],"luv":[45.136480402373536,113.915065115628011,4.62148047999889577],"rgb":[0.8,0.133333333333333331,0.333333333333333315],"xyz":[0.271128046539033496,0.146395366505292474,0.0999271187333688471],"hpluv":[2.323188749975583,320.51614012782295,45.136480402373536],"hsluv":[2.323188749975583,88.8894607126765663,45.136480402373536]},"#cc2266":{"lch":[45.5559407124691731,107.622008592458101,356.577515499379103],"luv":[45.5559407124691731,107.430062323442542,-6.42483016556681452],"rgb":[0.8,0.133333333333333331,0.4],"xyz":[0.278713042312541681,0.149429364814695764,0.139874763140512809],"hpluv":[356.577515499379103,299.774992396016216,45.5559407124691731],"hsluv":[356.577515499379103,89.543058875786258,45.5559407124691731]},"#cc2277":{"lch":[46.0633224094211542,102.110102175352239,349.514816334356908],"luv":[46.0633224094211542,100.405067655344695,-18.5821246198201955],"rgb":[0.8,0.133333333333333331,0.466666666666666674],"xyz":[0.288027055332743587,0.153154970022776588,0.188928565046910718],"hpluv":[349.514816334356908,281.289018816444,46.0633224094211542],"hsluv":[349.514816334356908,90.2475430222303174,46.0633224094211542]},"#cc2288":{"lch":[46.6595045299101443,98.2790088680822294,341.330158110485115],"luv":[46.6595045299101443,93.107459692013677,-31.4605234189234864],"rgb":[0.8,0.133333333333333331,0.533333333333333326],"xyz":[0.299167472434687387,0.157611136863554185,0.247601428450482886],"hpluv":[341.330158110485115,267.276005324070297,46.6595045299101443],"hsluv":[341.330158110485115,90.9748001704168,46.6595045299101443]},"#cc2299":{"lch":[47.3441166442187154,96.727251962869147,332.467163788405],"luv":[47.3441166442187154,85.772509513995189,-44.7128380217581167],"rgb":[0.8,0.133333333333333331,0.6],"xyz":[0.312224436543760087,0.162833922507183343,0.31636810609160082],"hpluv":[332.467163788405,259.252025571181889,47.3441166442187154],"hsluv":[332.467163788405,91.7002075152857259,47.3441166442187154]},"#cc22aa":{"lch":[48.1156936783416285,97.7076198445846131,323.544141865814368],"luv":[48.1156936783416285,78.5876931080813534,-58.0581903579838254],"rgb":[0.8,0.133333333333333331,0.66666666666666663],"xyz":[0.327282129509012643,0.168856999693284437,0.395671955708599421],"hpluv":[323.544141865814368,257.680176436907345,48.1156936783416285],"hsluv":[323.544141865814368,92.4042695013683328,48.1156936783416285]},"#cc22bb":{"lch":[48.9718390817589295,101.100583268181566,315.160199675634601],"luv":[48.9718390817589295,71.6885121422158846,-71.2887450022924867],"rgb":[0.8,0.133333333333333331,0.733333333333333282],"xyz":[0.344419721616349317,0.175712036536219196,0.485929940807241167],"hpluv":[315.160199675634601,261.96699229126267,48.9718390817589295],"hsluv":[315.160199675634601,93.0730408422972602,48.9718390817589295]},"#cc22cc":{"lch":[49.9093929354593513,106.520702596514482,307.715012949243658],"luv":[49.9093929354593513,65.1623716831421405,-84.2646153393173876],"rgb":[0.8,0.133333333333333331,0.8],"xyz":[0.363712097060071,0.183428986713708,0.587536451477511323],"hpluv":[307.715012949243658,270.826440261226253,49.9093929354593513],"hsluv":[307.715012949243658,93.6976999618693327,49.9093929354593513]},"#cc22dd":{"lch":[50.9245991417877377,113.480326695625976,301.360030221234524],"luv":[50.9245991417877377,59.0567580516805819,-96.9024451465042347],"rgb":[0.8,0.133333333333333331,0.866666666666666696],"xyz":[0.385230422610704615,0.192036316933961532,0.700866299377517321],"hpluv":[301.360030221234524,282.769318292038,50.9245991417877377],"hsluv":[301.360030221234524,94.2736696463096848,50.9245991417877377]},"#cc22ee":{"lch":[52.0132654143591964,121.518329969744158,296.062236941936249],"luv":[52.0132654143591964,53.3887372455597244,-109.162022947361166],"rgb":[0.8,0.133333333333333331,0.933333333333333348],"xyz":[0.409042602876879324,0.201561189040431576,0.826277115446040544],"hpluv":[296.062236941936249,296.460610812118318,52.0132654143591964],"hsluv":[296.062236941936249,94.7995997265514,52.0132654143591964]},"#cc22ff":{"lch":[53.170910599170611,130.261070707018604,291.695402941657903],"luv":[53.170910599170611,48.1538976563848422,-121.033667556747687],"rgb":[0.8,0.133333333333333331,1],"xyz":[0.435213651286710745,0.212029608404364273,0.964111303737822389],"hpluv":[291.695402941657903,310.870757963074425,53.170910599170611],"hsluv":[291.695402941657903,99.9999999999990621,53.170910599170611]},"#cc3300":{"lch":[45.9167915379707807,127.686226573765651,16.3911473443809399],"luv":[45.9167915379707807,122.496750231663356,36.0321889333482446],"rgb":[0.8,0.2,0],"xyz":[0.260850584973891519,0.15207273722165307,0.0156183921844992128],"hpluv":[16.3911473443809399,352.867650162608584,45.9167915379707807],"hsluv":[16.3911473443809399,100.000000000002288,45.9167915379707807]},"#cc3311":{"lch":[45.9716631772740811,126.14350976506573,15.6923563051461095],"luv":[45.9716631772740811,121.44186843726601,34.118289029712578],"rgb":[0.8,0.2,0.0666666666666666657],"xyz":[0.261862250473528624,0.152477403421507923,0.020946497149254846],"hpluv":[15.6923563051461095,348.188177538365835,45.9716631772740811],"hsluv":[15.6923563051461095,95.8756509753329595,45.9716631772740811]},"#cc3322":{"lch":[46.0731243265426613,123.399991281457972,14.3806932854006604],"luv":[46.0731243265426613,119.533487768482047,30.6480529588105668],"rgb":[0.8,0.2,0.133333333333333331],"xyz":[0.263737608612005681,0.153227546676898752,0.0308233833452340386],"hpluv":[14.3806932854006604,339.865273437066321,46.0731243265426613],"hsluv":[14.3806932854006604,88.4197842587317524,46.0731243265426613]},"#cc3333":{"lch":[46.2394596481243951,119.199958247304309,12.1770506300617924],"luv":[46.2394596481243951,116.518014060345578,25.1432385661076303],"rgb":[0.8,0.2,0.2],"xyz":[0.266825359344463386,0.154462646969881851,0.0470855372028451818],"hpluv":[12.1770506300617924,327.11667224844831,46.2394596481243951],"hsluv":[12.1770506300617924,76.6535755019082,46.2394596481243951]},"#cc3344":{"lch":[46.4780522046582405,113.793717346871745,8.90746564227168669],"luv":[46.4780522046582405,112.421330819758609,17.6197186224449389],"rgb":[0.8,0.2,0.266666666666666663],"xyz":[0.271283354588682302,0.156245845067569444,0.0705643121557318204],"hpluv":[8.90746564227168669,310.677421508065,46.4780522046582405],"hsluv":[8.90746564227168669,77.4930753906613887,46.4780522046582405]},"#cc3355":{"lch":[46.7943405275181661,107.68493286266704,4.39945159143432907],"luv":[46.7943405275181661,107.367637754253522,8.26045572038872855],"rgb":[0.8,0.2,0.333333333333333315],"xyz":[0.277245768628044287,0.158630810683314277,0.101966359429705736],"hpluv":[4.39945159143432907,292.012160158640199,46.7943405275181661],"hsluv":[4.39945159143432907,78.5258346284665265,46.7943405275181661]},"#cc3366":{"lch":[47.192153202602185,101.584765682520938,358.514989280316684],"luv":[47.192153202602185,101.55064731932022,-2.63261235272558647],"rgb":[0.8,0.2,0.4],"xyz":[0.284830764401552472,0.161664808992717568,0.141914003836849684],"hpluv":[358.514989280316684,273.148057687163259,47.192153202602185],"hsluv":[358.514989280316684,79.7102211537212781,47.192153202602185]},"#cc3377":{"lch":[47.6738975277608859,96.3272258277819589,351.225603296168742],"luv":[47.6738975277608859,95.1998742335289876,-14.6941614798792699],"rgb":[0.8,0.2,0.466666666666666674],"xyz":[0.294144777421754378,0.165390414200798391,0.190967805743247593],"hpluv":[351.225603296168742,256.39391915093114,47.6738975277608859],"hsluv":[351.225603296168742,80.9972134637005894,47.6738975277608859]},"#cc3388":{"lch":[48.2406991607903279,92.7347249941698095,342.718318936463845],"luv":[48.2406991607903279,88.5482927213948301,-27.5486674064369161],"rgb":[0.8,0.2,0.533333333333333326],"xyz":[0.305285194523698178,0.169846581041576,0.24964066914681976],"hpluv":[342.718318936463845,243.93163202064531,48.2406991607903279],"hsluv":[342.718318936463845,82.3372641433758758,48.2406991607903279]},"#cc3399":{"lch":[48.8925304323200436,91.4400639314067405,333.463846826874658],"luv":[48.8925304323200436,81.8070942553503926,-40.8519843003490877],"rgb":[0.8,0.2,0.6],"xyz":[0.318342158632770933,0.175069366685205147,0.318407346787937695],"hpluv":[333.463846826874658,237.319449797121564,48.8925304323200436],"hsluv":[333.463846826874658,83.6856508008112,48.8925304323200436]},"#cc33aa":{"lch":[49.6283419748853873,92.7248127600779242,324.141487451800515],"luv":[49.6283419748853873,75.1503095778714254,-54.3168654447363792],"rgb":[0.8,0.2,0.66666666666666663],"xyz":[0.333399851598023433,0.181092443871306241,0.397711196404936296],"hpluv":[324.141487451800515,237.085790295602294,49.6283419748853873],"hsluv":[324.141487451800515,85.0057245198840263,49.6283419748853873]},"#cc33bb":{"lch":[50.4462014889725054,96.4744776262418355,315.414049480091705],"luv":[50.4462014889725054,68.7089492450233905,-67.7230029377097],"rgb":[0.8,0.2,0.733333333333333282],"xyz":[0.350537443705360108,0.187947480714241,0.487969181503578042],"hpluv":[315.414049480091705,242.674024226837219,50.4462014889725054],"hsluv":[315.414049480091705,86.2701296035756258,50.4462014889725054]},"#cc33cc":{"lch":[51.3434379695087273,102.286811532428814,307.715012949243771],"luv":[51.3434379695087273,62.5723551280607779,-80.915339628518268],"rgb":[0.8,0.2,0.8],"xyz":[0.369829819149081862,0.195664430891729801,0.589575692173848198],"hpluv":[307.715012949243771,252.798225898109365,51.3434379695087273],"hsluv":[307.715012949243771,87.4604868647498,51.3434379695087273]},"#cc33dd":{"lch":[52.3167871114961827,109.649949983538605,301.195256028086874],"luv":[52.3167871114961827,56.7938698017029751,-93.7953510806358],"rgb":[0.8,0.2,0.866666666666666696],"xyz":[0.39134814469971535,0.204271761111983335,0.702905540073854196],"hpluv":[301.195256028086874,265.954105752122757,52.3167871114961827],"hsluv":[301.195256028086874,88.5661577004671,52.3167871114961827]},"#cc33ee":{"lch":[53.3625327970638494,118.082474280319559,295.802769884900215],"luv":[53.3625327970638494,51.3983045372134626,-106.309383512755787],"rgb":[0.8,0.2,0.933333333333333348],"xyz":[0.415160324965890115,0.21379663321845338,0.828316356142377419],"hpluv":[295.802769884900215,280.794331636146467,53.3625327970638494],"hsluv":[295.802769884900215,89.5826266077864375,53.3625327970638494]},"#cc33ff":{"lch":[54.4766398815527566,127.197777570935344,291.389330811727291],"luv":[54.4766398815527566,46.3894624378335,-118.436870921660102],"rgb":[0.8,0.2,1],"xyz":[0.441331373375721481,0.224265052582386076,0.966150544434159264],"hpluv":[291.389330811727291,296.284230666095709,54.4766398815527566],"hsluv":[291.389330811727291,99.9999999999990195,54.4766398815527566]},"#cc4400":{"lch":[48.2269914221542848,118.435883841274119,19.7039935064818295],"luv":[48.2269914221542848,111.501113106022,39.9319465764175447],"rgb":[0.8,0.266666666666666663,0],"xyz":[0.26968315545685756,0.1697378781875854,0.0185625823454878096],"hpluv":[19.7039935064818295,311.625122342549162,48.2269914221542848],"hsluv":[19.7039935064818295,100.000000000002174,48.2269914221542848]},"#cc4411":{"lch":[48.2779913635395,116.996103035931512,19.0066631306561966],"luv":[48.2779913635395,110.617558299276112,38.1030697123021],"rgb":[0.8,0.266666666666666663,0.0666666666666666657],"xyz":[0.270694820956494664,0.170142544387440253,0.0238906873102434428],"hpluv":[19.0066631306561966,307.511619232155283,48.2779913635395],"hsluv":[19.0066631306561966,96.278384876640132,48.2779913635395]},"#cc4422":{"lch":[48.3723181772035389,114.428966114904512,17.6946931608209894],"luv":[48.3723181772035389,109.015290220227484,34.7800917814421453],"rgb":[0.8,0.266666666666666663,0.133333333333333331],"xyz":[0.272570179094971721,0.170892687642831081,0.0337675735062226354],"hpluv":[17.6946931608209894,300.177682052924467,48.3723181772035389],"hsluv":[17.6946931608209894,89.5341066932624869,48.3723181772035389]},"#cc4433":{"lch":[48.5270263662828114,110.48209503335984,15.4815426750504042],"luv":[48.5270263662828114,106.473417017787412,29.4907577304601034],"rgb":[0.8,0.266666666666666663,0.2],"xyz":[0.275657929827429427,0.17212778793581418,0.0500297273638337786],"hpluv":[15.4815426750504042,288.900004133964501,48.5270263662828114],"hsluv":[15.4815426750504042,78.8475327486048,48.5270263662828114]},"#cc4444":{"lch":[48.7490888960709725,105.371058014361893,12.1770506300618457],"luv":[48.7490888960709725,103.000257716521162,22.2262632351064191],"rgb":[0.8,0.266666666666666663,0.266666666666666663],"xyz":[0.280115925071648342,0.173910986033501774,0.0735085023167204171],"hpluv":[12.1770506300618457,274.28001464324592,48.7490888960709725],"hsluv":[12.1770506300618457,64.2723089184284788,48.7490888960709725]},"#cc4455":{"lch":[49.0437296069087,99.5540950311582691,7.58056168126664254],"luv":[49.0437296069087,98.6840273694228074,13.1331861946711772],"rgb":[0.8,0.266666666666666663,0.333333333333333315],"xyz":[0.286078339111010327,0.176295951649246607,0.104910549590694333],"hpluv":[7.58056168126664254,257.581676799067395,49.0437296069087],"hsluv":[7.58056168126664254,65.7689369270132858,49.0437296069087]},"#cc4466":{"lch":[49.4147368002801244,93.7049448509207679,1.51289058041819868],"luv":[49.4147368002801244,93.6722802728102835,2.47398423725391092],"rgb":[0.8,0.266666666666666663,0.4],"xyz":[0.293663334884518512,0.179329949958649898,0.14485819399783828],"hpluv":[1.51289058041819868,240.627550105868352,49.4147368002801244],"hsluv":[1.51289058041819868,67.500804726855,49.4147368002801244]},"#cc4477":{"lch":[49.8646356184384132,88.6490107187132566,353.900159994018],"luv":[49.8646356184384132,88.1471013723349586,-9.41995865499641383],"rgb":[0.8,0.266666666666666663,0.466666666666666674],"xyz":[0.302977347904720418,0.183055555166730721,0.19391199590423619],"hpluv":[353.900159994018,225.590377060975072,49.8646356184384132],"hsluv":[353.900159994018,69.4017616341687784,49.8646356184384132]},"#cc4488":{"lch":[50.3948096201307436,85.2405150759366279,344.907000147604322],"luv":[50.3948096201307436,82.3000967091543743,-22.1954835963269055],"rgb":[0.8,0.266666666666666663,0.533333333333333326],"xyz":[0.314117765006664218,0.187511722007508319,0.252584859307808385],"hpluv":[344.907000147604322,214.634525667930632,50.3948096201307436],"hsluv":[344.907000147604322,71.4025087995354824,50.3948096201307436]},"#cc4499":{"lch":[51.0056074652318046,84.1718897613591679,335.041688295241613],"luv":[51.0056074652318046,76.3115014820887581,-35.5170630478867793],"rgb":[0.8,0.266666666666666663,0.6],"xyz":[0.327174729115737,0.192734507651137477,0.321351536948926264],"hpluv":[335.041688295241613,209.40569084337892,51.0056074652318046],"hsluv":[335.041688295241613,73.4381222823911344,51.0056074652318046]},"#cc44aa":{"lch":[51.6964496814969152,85.7749410926589348,325.085448007895536],"luv":[51.6964496814969152,70.3360122964612913,-49.093644127128691],"rgb":[0.8,0.266666666666666663,0.66666666666666663],"xyz":[0.342232422080989473,0.198757584837238571,0.400655386565924865],"hpluv":[325.085448007895536,210.542141790665795,51.6964496814969152],"hsluv":[325.085448007895536,75.4531429469973602,51.6964496814969152]},"#cc44bb":{"lch":[52.465940673938249,89.9444778306290829,315.812454406659811],"luv":[52.465940673938249,64.4957791941851326,-62.692133145710109],"rgb":[0.8,0.266666666666666663,0.733333333333333282],"xyz":[0.359370014188326148,0.20561262168017333,0.490913371664566611],"hpluv":[315.812454406659811,217.538619181736436,52.465940673938249],"hsluv":[315.812454406659811,77.4040753157756143,52.465940673938249]},"#cc44cc":{"lch":[53.3119860408958175,96.2498903650287758,307.715012949243885],"luv":[53.3119860408958175,58.8793631430003828,-76.1397530279337502],"rgb":[0.8,0.266666666666666663,0.8],"xyz":[0.378662389632047902,0.213329571857662131,0.592519882334836767],"hpluv":[307.715012949243885,229.094523932317799,53.3119860408958175],"hsluv":[307.715012949243885,79.2597279113993,53.3119860408958175]},"#cc44dd":{"lch":[54.2319126329379486,104.138844540210442,300.941773361922515],"luv":[54.2319126329379486,53.5447276840333259,-89.31887303035586],"rgb":[0.8,0.266666666666666663,0.866666666666666696],"xyz":[0.40018071518268139,0.221936902077915665,0.705849730234842765],"hpluv":[300.941773361922515,243.66724889744043,54.2319126329379486],"hsluv":[300.941773361922515,81.0000946003390538,54.2319126329379486]},"#cc44ee":{"lch":[55.2225876682288401,113.096616320403683,295.407423092027],"luv":[55.2225876682288401,48.5243479249087528,-102.157879194837463],"rgb":[0.8,0.266666666666666663,0.933333333333333348],"xyz":[0.423992895448856155,0.23146177418438571,0.831260546303366],"hpluv":[295.407423092027,259.879597148300718,55.2225876682288401],"hsluv":[295.407423092027,86.8652077390175634,55.2225876682288401]},"#cc44ff":{"lch":[56.2805330741479537,122.715491745326418,290.92682559337851],"luv":[56.2805330741479537,43.8309487146615382,-114.62085259266739],"rgb":[0.8,0.266666666666666663,1],"xyz":[0.450163943858687521,0.241930193548318406,0.969094734595147833],"hpluv":[290.92682559337851,276.681751484143376,56.2805330741479537],"hsluv":[290.92682559337851,99.9999999999989768,56.2805330741479537]},"#cc5500":{"lch":[51.07852272981998,108.355754132896138,24.3337665629108457],"luv":[51.07852272981998,98.7294936728878838,44.6481414260866],"rgb":[0.8,0.333333333333333315,0],"xyz":[0.281496412171203525,0.193364391616277664,0.0225003345836030169],"hpluv":[24.3337665629108457,269.186315008697875,51.07852272981998],"hsluv":[24.3337665629108457,100.000000000002217,51.07852272981998]},"#cc5511":{"lch":[51.1252833166066,107.003417336388864,23.6474066829241423],"luv":[51.1252833166066,98.0184651549503201,42.91983003616388],"rgb":[0.8,0.333333333333333315,0.0666666666666666657],"xyz":[0.282508077670840629,0.193769057816132517,0.0278284395483586466],"hpluv":[23.6474066829241423,265.583595811902,51.1252833166066],"hsluv":[23.6474066829241423,96.7082849697218307,51.1252833166066]},"#cc5522":{"lch":[51.2117930688627467,104.583581473170284,22.351909846807331],"luv":[51.2117930688627467,96.7257518395109486,39.7725337995530808],"rgb":[0.8,0.333333333333333315,0.133333333333333331],"xyz":[0.284383435809317686,0.194519201071523345,0.0377053257443378462],"hpluv":[22.351909846807331,259.139045481141636,51.2117930688627467],"hsluv":[22.351909846807331,90.7274756498525079,51.2117930688627467]},"#cc5533":{"lch":[51.3537468781662625,100.840694749975015,20.1540565840537802],"luv":[51.3537468781662625,94.6661789932146718,34.7442120716858369],"rgb":[0.8,0.333333333333333315,0.2],"xyz":[0.287471186541775392,0.195754301364506444,0.0539674796019489894],"hpluv":[20.1540565840537802,249.174169543579183,51.3537468781662625],"hsluv":[20.1540565840537802,81.2092815218714321,51.3537468781662625]},"#cc5544":{"lch":[51.5576456995760424,95.9504499860225764,16.842752904303623],"luv":[51.5576456995760424,91.8345174188591074,27.8012636936791502],"rgb":[0.8,0.333333333333333315,0.266666666666666663],"xyz":[0.291929181785994307,0.197537499462194038,0.0774462545548356279],"hpluv":[16.842752904303623,236.152889903020736,51.5576456995760424],"hsluv":[16.842752904303623,68.1451659970290109,51.5576456995760424]},"#cc5555":{"lch":[51.8284441386287114,90.3192908744292851,12.1770506300618919],"luv":[51.8284441386287114,88.2871484081680364,19.0513445723360242],"rgb":[0.8,0.333333333333333315,0.333333333333333315],"xyz":[0.297891595825356292,0.199922465077938871,0.108848301828809529],"hpluv":[12.1770506300618919,221.132040760117775,51.8284441386287114],"hsluv":[12.1770506300618919,51.8180912815801,51.8284441386287114]},"#cc5566":{"lch":[52.1698415772242612,84.57836719340618,5.91246023067467696],"luv":[52.1698415772242612,84.1284474176031836,8.71232071300305577],"rgb":[0.8,0.333333333333333315,0.4],"xyz":[0.305476591598864478,0.202956463387342162,0.148795946235953491],"hpluv":[5.91246023067467696,205.721226704565879,52.1698415772242612],"hsluv":[5.91246023067467696,54.0130370973951415,52.1698415772242612]},"#cc5577":{"lch":[52.5844387621358607,79.5477054283049654,357.892334615122479],"luv":[52.5844387621358607,79.493890006545314,-2.92555815796844554],"rgb":[0.8,0.333333333333333315,0.466666666666666674],"xyz":[0.314790604619066383,0.206682068595422985,0.1978497481423514],"hpluv":[357.892334615122479,191.959557587962337,52.5844387621358607],"hsluv":[357.892334615122479,56.4492590331968884,52.5844387621358607]},"#cc5588":{"lch":[53.0738428910491962,76.1348505840982,348.222799824086337],"luv":[53.0738428910491962,74.5321119975331072,-15.5396188708133902],"rgb":[0.8,0.333333333333333315,0.533333333333333326],"xyz":[0.325931021721010183,0.211138235436200583,0.256522611545923596],"hpluv":[348.222799824086337,182.029716109510787,53.0738428910491962],"hsluv":[348.222799824086337,59.0443947768825339,53.0738428910491962]},"#cc5599":{"lch":[53.6387547547300443,75.1322702050955655,337.451566852479516],"luv":[53.6387547547300443,69.3888374020903314,-28.8105409556599774],"rgb":[0.8,0.333333333333333315,0.6],"xyz":[0.338987985830082938,0.216361021079829741,0.325289289187041475],"hpluv":[337.451566852479516,177.740808472615271,53.6387547547300443],"hsluv":[337.451566852479516,61.7180151219793274,53.6387547547300443]},"#cc55aa":{"lch":[54.2790527162633651,76.9604755372169507,326.525055670409472],"luv":[54.2790527162633651,64.1948187783047359,-42.449264268479169],"rgb":[0.8,0.333333333333333315,0.66666666666666663],"xyz":[0.354045678795335439,0.222384098265930835,0.404593138804040076],"hpluv":[326.525055670409472,179.918080614224607,54.2790527162633651],"hsluv":[326.525055670409472,64.3982563598392517,54.2790527162633651]},"#cc55bb":{"lch":[54.9938795911038767,81.534325182187132,316.414019967357433],"luv":[54.9938795911038767,59.0586208757266817,-56.2132144888709888],"rgb":[0.8,0.333333333333333315,0.733333333333333282],"xyz":[0.371183270902672113,0.229239135108865594,0.494851123902681822],"hpluv":[316.414019967357433,188.133202867989326,54.9938795911038767],"hsluv":[316.414019967357433,67.0257727218245378,54.9938795911038767]},"#cc55cc":{"lch":[55.7817339145568667,88.3780574248019,307.715012949244169],"luv":[55.7817339145568667,54.0638926159085145,-69.9126351198200382],"rgb":[0.8,0.333333333333333315,0.8],"xyz":[0.390475646346393868,0.236956085286354395,0.596457634572952],"hpluv":[307.715012949244169,201.044301715196383,55.7817339145568667],"hsluv":[307.715012949244169,69.5552053299685156,55.7817339145568667]},"#cc55dd":{"lch":[56.6405645837994882,96.8744721490496232,300.570417552325068],"luv":[56.6405645837994882,49.2700598324241312,-83.4093793183137],"rgb":[0.8,0.333333333333333315,0.866666666666666696],"xyz":[0.411993971897027356,0.245563415506607929,0.709787482472958],"hpluv":[300.570417552325068,217.030665421015726,56.6405645837994882],"hsluv":[300.570417552325068,72.1703256475756234,56.6405645837994882]},"#cc55ee":{"lch":[57.5678665910353118,106.457154357221242,294.836459829444038],"luv":[57.5678665910353118,44.7151619549172707,-96.6109724885468],"rgb":[0.8,0.333333333333333315,0.933333333333333348],"xyz":[0.435806152163202121,0.255088287613077946,0.835198298541481199],"hpluv":[294.836459829444038,234.657286550118499,57.5678665910353118],"hsluv":[294.836459829444038,85.8995510844284809,57.5678665910353118]},"#cc55ff":{"lch":[58.560775097021633,116.686665261471418,290.266986003053091],"luv":[58.560775097021633,40.4196983751927874,-109.462440284789551],"rgb":[0.8,0.333333333333333315,1],"xyz":[0.461977200573033486,0.26555670697701067,0.973032486833263],"hpluv":[290.266986003053091,252.844632524376181,58.560775097021633],"hsluv":[290.266986003053091,99.9999999999988,58.560775097021633]},"#cc6600":{"lch":[54.388060759003551,98.5584029412379579,30.482787603130209],"luv":[54.388060759003551,84.9358174587045482,49.9966569177284157],"rgb":[0.8,0.4,0],"xyz":[0.29652446987705,0.223420507027971,0.0275096871522183678],"hpluv":[30.482787603130209,229.947880001204965,54.388060759003551],"hsluv":[30.482787603130209,100.000000000002359,54.388060759003551]},"#cc6611":{"lch":[54.430531479182676,97.2669366851907711,29.8266301777559697],"luv":[54.430531479182676,84.3824110244092367,48.3783596438383583],"rgb":[0.8,0.4,0.0666666666666666657],"xyz":[0.297536135376687105,0.223825173227825858,0.032837792116974],"hpluv":[29.8266301777559697,226.757672191171366,54.430531479182676],"hsluv":[29.8266301777559697,97.1300271864182463,54.430531479182676]},"#cc6622":{"lch":[54.5091256699603548,94.945229062596681,28.5830621108902889],"luv":[54.5091256699603548,83.3737269438019695,45.4248629854764],"rgb":[0.8,0.4,0.133333333333333331],"xyz":[0.299411493515164162,0.224575316483216686,0.0427146783129532],"hpluv":[28.5830621108902889,221.025945543219876,54.5091256699603548],"hsluv":[28.5830621108902889,91.902111940908739,54.5091256699603548]},"#cc6633":{"lch":[54.6381494647888388,91.324965774397,26.4577509745500876],"luv":[54.6381494647888388,81.7598754062496624,40.688722605278663],"rgb":[0.8,0.4,0.2],"xyz":[0.302499244247621868,0.225810416776199785,0.0589768321705643403],"hpluv":[26.4577509745500876,212.096187894217309,54.6381494647888388],"hsluv":[26.4577509745500876,83.5463344335908289,54.6381494647888388]},"#cc6644":{"lch":[54.8236025158742137,86.5353782352002,23.2174871910251],"luv":[54.8236025158742137,79.5273159773273903,34.1141861950638798],"rgb":[0.8,0.4,0.266666666666666663],"xyz":[0.306957239491840783,0.227593614873887379,0.0824556071234509858],"hpluv":[23.2174871910251,200.292852977212362,54.8236025158742137],"hsluv":[23.2174871910251,72.0055590941951635,54.8236025158742137]},"#cc6655":{"lch":[55.0701314820163077,80.921365039871,18.5706632184066578],"luv":[55.0701314820163077,76.7079190692017505,25.7713498286149552],"rgb":[0.8,0.4,0.333333333333333315],"xyz":[0.312919653531202768,0.229978580489632212,0.113857654397424887],"hpluv":[18.5706632184066578,186.460314881725708,55.0701314820163077],"hsluv":[18.5706632184066578,57.463707489477386,55.0701314820163077]},"#cc6666":{"lch":[55.3812986167643686,75.0592421503045841,12.1770506300619576],"luv":[55.3812986167643686,73.3704437553848834,15.8324923911544637],"rgb":[0.8,0.4,0.4],"xyz":[0.320504649304710953,0.233012578799035502,0.153805298804568835],"hpluv":[12.1770506300619576,171.980959079196282,55.3812986167643686],"hsluv":[12.1770506300619576,45.9214429163451925,55.3812986167643686]},"#cc6677":{"lch":[55.7597240294908403,69.7578535305897702,3.7339069954147126],"luv":[55.7597240294908403,69.6097753289024,4.54283037928401079],"rgb":[0.8,0.4,0.466666666666666674],"xyz":[0.329818662324912859,0.236738184007116326,0.202859100710966744],"hpluv":[3.7339069954147126,158.749300244695775,55.7597240294908403],"hsluv":[3.7339069954147126,47.4001946683844935,55.7597240294908403]},"#cc6688":{"lch":[56.2071770412836855,65.9988703650454198,353.20230012342131],"luv":[56.2071770412836855,65.534915505775615,-7.81189727997758432],"rgb":[0.8,0.4,0.533333333333333326],"xyz":[0.340959079426856659,0.241194350847893924,0.26153196411453894],"hpluv":[353.20230012342131,148.999240608904586,56.2071770412836855],"hsluv":[353.20230012342131,48.9818497710332537,56.2071770412836855]},"#cc6699":{"lch":[56.7246474757154573,64.7364860461136544,341.13073016495332],"luv":[56.7246474757154573,61.2574795353059756,-20.9364234428957907],"rgb":[0.8,0.4,0.6],"xyz":[0.354016043535929414,0.246417136491523081,0.330298641755656819],"hpluv":[341.13073016495332,144.81603174775961,56.7246474757154573],"hsluv":[341.13073016495332,50.615240188358726,56.7246474757154573]},"#cc66aa":{"lch":[57.3124110050500661,66.5536753014576874,328.724652687595039],"luv":[57.3124110050500661,56.882247269492467,-34.5514347271451925],"rgb":[0.8,0.4,0.66666666666666663],"xyz":[0.369073736501181915,0.252440213677624203,0.40960249137265542],"hpluv":[328.724652687595039,147.354258527000582,57.3124110050500661],"hsluv":[328.724652687595039,52.5782983823555057,57.3124110050500661]},"#cc66bb":{"lch":[57.9700950113726634,71.4140361316817831,317.320615294889421],"luv":[57.9700950113726634,52.5006394421278628,-48.4112323204526405],"rgb":[0.8,0.4,0.733333333333333282],"xyz":[0.386211328608518589,0.259295250520558962,0.499860476471297166],"hpluv":[317.320615294889421,156.321564636453559,57.9700950113726634],"hsluv":[317.320615294889421,55.7867325729046044,57.9700950113726634]},"#cc66cc":{"lch":[58.6967474031167882,78.7715159072838844,307.71501294924451],"luv":[58.6967474031167882,48.1872412824568599,-62.3132529717215391],"rgb":[0.8,0.4,0.8],"xyz":[0.405503704052240344,0.267012200698047764,0.601466987141567322],"hpluv":[307.71501294924451,170.292097080892688,58.6967474031167882],"hsluv":[307.71501294924451,58.9158791245518429,58.6967474031167882]},"#cc66dd":{"lch":[59.4909085631812928,87.9045601549668589,300.035118747227784],"luv":[59.4909085631812928,43.9989332886277964,-76.1006278916348151],"rgb":[0.8,0.4,0.866666666666666696],"xyz":[0.427022029602873832,0.27561953091830127,0.71479683504157332],"hpluv":[300.035118747227784,187.499506963343748,59.4909085631812928],"hsluv":[300.035118747227784,69.8010448945604907,59.4909085631812928]},"#cc66ee":{"lch":[60.3506853352839272,98.1678970647401314,294.030303780460372],"luv":[60.3506853352839272,39.9759075841908498,-89.6597057040320919],"rgb":[0.8,0.4,0.933333333333333348],"xyz":[0.450834209869048597,0.285144403024771287,0.840207651110096543],"hpluv":[294.030303780460372,206.408039079415715,60.3506853352839272],"hsluv":[294.030303780460372,84.6650997716967169,60.3506853352839272]},"#cc66ff":{"lch":[61.2738253236974799,109.076950193692937,289.351384827957531],"luv":[61.2738253236974799,36.143813792667018,-102.914555763887847],"rgb":[0.8,0.4,1],"xyz":[0.477005258278879962,0.295612822388704,0.978041839401878388],"hpluv":[289.351384827957531,225.890163025573315,61.2738253236974799],"hsluv":[289.351384827957531,99.9999999999987,61.2738253236974799]},"#cc7700":{"lch":[58.0681687130694684,90.1274111260576,38.2527636780657616],"luv":[58.0681687130694684,70.775890411238,55.8007488550273862],"rgb":[0.8,0.466666666666666674,0],"xyz":[0.314978207930467602,0.260327983134806762,0.0336609331700240683],"hpluv":[38.2527636780657616,196.95095583694345,58.0681687130694684],"hsluv":[38.2527636780657616,100.00000000000226,58.0681687130694684]},"#cc7711":{"lch":[58.1065272060428,88.8714225311590837,37.658223554494576],"luv":[58.1065272060428,70.356768805075,54.2959927252558288],"rgb":[0.8,0.466666666666666674,0.0666666666666666657],"xyz":[0.315989873430104706,0.260732649334661615,0.0389890381347797],"hpluv":[37.658223554494576,194.078102813960953,58.1065272060428],"hsluv":[37.658223554494576,97.5201736027742925,58.1065272060428]},"#cc7722":{"lch":[58.1775287784180364,86.6008188207648573,36.5262538454337786],"luv":[58.1775287784180364,69.5910513475594286,51.5440335321973748],"rgb":[0.8,0.466666666666666674,0.133333333333333331],"xyz":[0.317865231568581763,0.261482792590052415,0.0488659243307589],"hpluv":[36.5262538454337786,188.888733728089306,58.1775287784180364],"hsluv":[36.5262538454337786,92.9922153048462832,58.1775287784180364]},"#cc7733":{"lch":[58.2941365993826111,83.0249283524691606,34.5753600294232513],"luv":[58.2941365993826111,68.3611064237300781,47.1157920070976459],"rgb":[0.8,0.466666666666666674,0.2],"xyz":[0.320952982301039469,0.262717892883035542,0.0651280781883700477],"hpluv":[34.5753600294232513,180.726967614303447,58.2941365993826111],"hsluv":[34.5753600294232513,85.7262720770138458,58.2941365993826111]},"#cc7744":{"lch":[58.4618482438389577,78.2181767747613321,31.5590767862408974],"luv":[58.4618482438389577,66.6497843857434447,40.9376284034837923],"rgb":[0.8,0.466666666666666674,0.266666666666666663],"xyz":[0.325410977545258384,0.264501090980723108,0.0886068531412566862],"hpluv":[31.5590767862408974,169.775287201810244,58.4618482438389577],"hsluv":[31.5590767862408974,75.6318325574838,58.4618482438389577]},"#cc7755":{"lch":[58.6849825995062133,72.4480337937475,27.1381330463907204],"luv":[58.6849825995062133,64.4721877935720187,33.0462494345479811],"rgb":[0.8,0.466666666666666674,0.333333333333333315],"xyz":[0.331373391584620369,0.266886056596467969,0.120008900415230588],"hpluv":[27.1381330463907204,156.653084219512607,58.6849825995062133],"hsluv":[27.1381330463907204,62.8141161752895059,58.6849825995062133]},"#cc7766":{"lch":[58.9669266929607829,66.2083874258113667,20.8554290651987451],"luv":[58.9669266929607829,61.8705265372573407,23.5709251309504673],"rgb":[0.8,0.466666666666666674,0.4],"xyz":[0.338958387358128554,0.269920054905871287,0.159956544822374536],"hpluv":[20.8554290651987451,142.476698671576116,58.9669266929607829],"hsluv":[20.8554290651987451,47.542957476979069,58.9669266929607829]},"#cc7777":{"lch":[59.3102652975897229,60.2635194006596251,12.177050630062082],"luv":[59.3102652975897229,58.907617956407762,12.7115820123061383],"rgb":[0.8,0.466666666666666674,0.466666666666666674],"xyz":[0.34827240037833046,0.273645660113952083,0.209010346728772445],"hpluv":[12.177050630062082,128.932959302114057,59.3102652975897229],"hsluv":[12.177050630062082,43.5373021749198443,59.3102652975897229]},"#cc7788":{"lch":[59.7168613687891963,55.6638868177661834,0.734433949810619269],"luv":[59.7168613687891963,55.6593138534775917,0.713496335773026069],"rgb":[0.8,0.466666666666666674,0.533333333333333326],"xyz":[0.35941281748027426,0.278101826954729681,0.26768321013234464],"hpluv":[0.734433949810619269,118.281243349182901,59.7168613687891963],"hsluv":[0.734433949810619269,45.0130000154657779,59.7168613687891963]},"#cc7799":{"lch":[60.187915321807921,53.6038783156568073,346.890122071781263],"luv":[60.187915321807921,52.2067938730354371,-12.1583898596044406],"rgb":[0.8,0.466666666666666674,0.6],"xyz":[0.37246978158934696,0.283324612598358838,0.336449887773462519],"hpluv":[346.890122071781263,113.012436406344946,60.187915321807921],"hsluv":[346.890122071781263,46.5549497102544,60.187915321807921]},"#cc77aa":{"lch":[60.7240163061688349,54.9761438743297148,332.197464335395125],"luv":[60.7240163061688349,48.6297161920954863,-25.6422912074417866],"rgb":[0.8,0.466666666666666674,0.66666666666666663],"xyz":[0.387527474554599516,0.28934768978445996,0.41575373739046112],"hpluv":[332.197464335395125,114.882297594683308,60.7240163061688349],"hsluv":[332.197464335395125,48.1189262345266471,60.7240163061688349]},"#cc77bb":{"lch":[61.3251919150652043,59.875823087291181,318.726648244723037],"luv":[61.3251919150652043,45.0009333565193046,-39.4972174643062743],"rgb":[0.8,0.466666666666666674,0.733333333333333282],"xyz":[0.40466506666193619,0.296202726627394719,0.506011722489102866],"hpluv":[318.726648244723037,123.894465684476771,61.3251919150652043],"hsluv":[318.726648244723037,49.6642191709372156,61.3251919150652043]},"#cc77cc":{"lch":[61.9909592768387228,67.6487625915650881,307.715012949244965],"luv":[61.9909592768387228,41.3830711255614219,-53.514451360232222],"rgb":[0.8,0.466666666666666674,0.8],"xyz":[0.423957442105657889,0.303919676804883521,0.607618233159373],"hpluv":[307.715012949244965,138.474825543749517,61.9909592768387228],"hsluv":[307.715012949244965,51.1553628289834066,61.9909592768387228]},"#cc77dd":{"lch":[62.7203784873954362,77.3966796673740305,299.257833182927357],"luv":[62.7203784873954362,37.8268934727942252,-67.5231231041040161],"rgb":[0.8,0.466666666666666674,0.866666666666666696],"xyz":[0.445475767656291488,0.312527007025137,0.720948081059379],"hpluv":[299.257833182927357,156.586020071329443,62.7203784873954362],"hsluv":[299.257833182927357,66.8390608629672158,62.7203784873954362]},"#cc77ee":{"lch":[63.5121081687847351,88.3507940057556453,292.894169444170245],"luv":[63.5121081687847351,34.371127600373157,-81.3909601179783],"rgb":[0.8,0.466666666666666674,0.933333333333333348],"xyz":[0.469287947922466198,0.322051879131607044,0.846358897127902243],"hpluv":[292.894169444170245,176.519730115921618,63.5121081687847351],"hsluv":[292.894169444170245,83.1130682001540322,63.5121081687847351]},"#cc77ff":{"lch":[64.3644622692190467,99.9639900757921112,288.092077643344339],"luv":[64.3644622692190467,31.0433170684360782,-95.0216384686225553],"rgb":[0.8,0.466666666666666674,1],"xyz":[0.495458996332297619,0.332520298495539768,0.984193085419684088],"hpluv":[288.092077643344339,197.077372703744913,64.3644622692190467],"hsluv":[288.092077643344339,99.9999999999984794,64.3644622692190467]},"#cc8800":{"lch":[62.03823759594124,83.9779445354575813,47.4964941193052752],"luv":[62.03823759594124,56.738465406715342,61.9115636346826221],"rgb":[0.8,0.533333333333333326,0],"xyz":[0.337050577655438111,0.304472722584748334,0.0410183897450140181],"hpluv":[47.4964941193052752,171.769129739761638,62.03823759594124],"hsluv":[47.4964941193052752,100.000000000002245,62.03823759594124]},"#cc8811":{"lch":[62.0727951053461879,82.7448035916202542,47.0033697453910904],"luv":[62.0727951053461879,56.4282611354359744,60.519037225048919],"rgb":[0.8,0.533333333333333326,0.0666666666666666657],"xyz":[0.338062243155075215,0.304877388784603187,0.0463464947097696478],"hpluv":[47.0033697453910904,169.152629782786704,62.0727951053461879],"hsluv":[47.0033697453910904,97.8669953021426,62.0727951053461879]},"#cc8822":{"lch":[62.1367747194074127,80.5023095814055836,46.0605806208152728],"luv":[62.1367747194074127,55.8603434591127268,57.9676105818622389],"rgb":[0.8,0.533333333333333326,0.133333333333333331],"xyz":[0.339937601293552272,0.305627532039994,0.0562233809057488473],"hpluv":[46.0605806208152728,164.398919884807611,62.1367747194074127],"hsluv":[46.0605806208152728,93.9640765124603,62.1367747194074127]},"#cc8833":{"lch":[62.2418885518498541,76.9329948636363241,44.4230175211057343],"luv":[62.2418885518498541,54.9448944756850963,53.8492736231801246],"rgb":[0.8,0.533333333333333326,0.2],"xyz":[0.34302535202601,0.306862632332977114,0.0724855347633599906],"hpluv":[44.4230175211057343,156.844467463147254,62.2418885518498541],"hsluv":[44.4230175211057343,87.678806867525978,62.2418885518498541]},"#cc8844":{"lch":[62.3931521103864668,72.0506908450526424,41.8566920827827929],"luv":[62.3931521103864668,53.6645163812677168,48.0772475586321661],"rgb":[0.8,0.533333333333333326,0.266666666666666663],"xyz":[0.347483347270228893,0.30864583043066468,0.0959643097162466291],"hpluv":[41.8566920827827929,146.534723453778,62.3931521103864668],"hsluv":[41.8566920827827929,78.900857077449,62.3931521103864668]},"#cc8855":{"lch":[62.5945538889838673,66.028576146577123,38.0101307109045408],"luv":[62.5945538889838673,52.0240395147187513,40.6604498316892062],"rgb":[0.8,0.533333333333333326,0.333333333333333315],"xyz":[0.353445761309590878,0.311030796046409541,0.127366356990220531],"hpluv":[38.0101307109045408,133.855034432196135,62.5945538889838673],"hsluv":[38.0101307109045408,67.6770944211119314,62.5945538889838673]},"#cc8866":{"lch":[62.8492816845599265,59.2369010326618337,32.3420191431213624],"luv":[62.8492816845599265,50.047464385327217,31.6900891849924626],"rgb":[0.8,0.533333333333333326,0.4],"xyz":[0.361030757083099063,0.31406479435581286,0.167314001397364492],"hpluv":[32.3420191431213624,119.60004374597824,62.8492816845599265],"hsluv":[32.3420191431213624,54.1901780257147436,62.8492816845599265]},"#cc8877":{"lch":[63.1598410661450771,52.3169991415742,24.053169540805424],"luv":[63.1598410661450771,47.7741895619322392,21.3235834436907119],"rgb":[0.8,0.533333333333333326,0.466666666666666674],"xyz":[0.370344770103300969,0.317790399563893655,0.216367803303762402],"hpluv":[24.053169540805424,105.109295035123296,63.1598410661450771],"hsluv":[24.053169540805424,38.7316682482548558,63.1598410661450771]},"#cc8888":{"lch":[63.5281271999152182,46.2961098245983322,12.1770506300622312],"luv":[63.5281271999152182,45.2544686659219906,9.76539045078869528],"rgb":[0.8,0.533333333333333326,0.533333333333333326],"xyz":[0.381485187205244769,0.322246566404671253,0.275040666707334569],"hpluv":[12.1770506300622312,92.4736018048895403,63.5281271999152182],"hsluv":[12.1770506300622312,40.0703189706204199,63.5281271999152182]},"#cc8899":{"lch":[63.9554753143552119,42.6335463086933615,356.296984030050055],"luv":[63.9554753143552119,42.5445368433351,-2.7534806412255004],"rgb":[0.8,0.533333333333333326,0.6],"xyz":[0.394542151314317469,0.327469352048300411,0.343807344348452504],"hpluv":[356.296984030050055,84.588837176407921,63.9554753143552119],"hsluv":[356.296984030050055,41.5088242950414781,63.9554753143552119]},"#cc88aa":{"lch":[64.442701858069384,42.8028595258545153,338.056731442080661],"luv":[64.442701858069384,39.701977128446444,-15.9949303118941444],"rgb":[0.8,0.533333333333333326,0.66666666666666663],"xyz":[0.40959984427957,0.333492429234401533,0.423111193965451104],"hpluv":[338.056731442080661,84.28268641071584,64.442701858069384],"hsluv":[338.056731442080661,42.9831867606486924,64.442701858069384]},"#cc88bb":{"lch":[64.9901424985427099,47.2946673003310707,321.051918945199532],"luv":[64.9901424985427099,36.7818149859187784,-29.7301806484697622],"rgb":[0.8,0.533333333333333326,0.733333333333333282],"xyz":[0.426737436386906699,0.340347466077336291,0.513369179064092851],"hpluv":[321.051918945199532,92.3430068912496296,64.9901424985427099],"hsluv":[321.051918945199532,44.4548878388224864,64.9901424985427099]},"#cc88cc":{"lch":[65.5976900795525637,55.3077284551996158,307.715012949245761],"luv":[65.5976900795525637,33.8336367550969399,-43.751912538747959],"rgb":[0.8,0.533333333333333326,0.8],"xyz":[0.446029811830628398,0.348064416254825093,0.614975689734363],"hpluv":[307.715012949245761,106.988377595373095,65.5976900795525637],"hsluv":[307.715012949245761,45.8886814173124122,65.5976900795525637]},"#cc88dd":{"lch":[66.2648339334855905,65.6132669537387727,298.095232643272539],"luv":[66.2648339334855905,30.8998122908772608,-57.8817967994354774],"rgb":[0.8,0.533333333333333326,0.866666666666666696],"xyz":[0.467548137381262,0.356671746475078599,0.728305537634369],"hpluv":[298.095232643272539,125.645770778198369,66.2648339334855905],"hsluv":[298.095232643272539,63.1276078601331037,66.2648339334855905]},"#cc88ee":{"lch":[66.9907009061042,77.2337728548956193,291.267726386147558],"luv":[66.9907009061042,28.0147259973813227,-71.9738202174461463],"rgb":[0.8,0.533333333333333326,0.933333333333333348],"xyz":[0.491360317647436706,0.366196618581548616,0.853716353702892228],"hpluv":[291.267726386147558,146.295866424915545,66.9907009061042],"hsluv":[291.267726386147558,81.1585487563552874,66.9907009061042]},"#cc88ff":{"lch":[67.7740978167257,89.535143384050329,286.350196506734335],"luv":[67.7740978167257,25.2048126805589376,-85.914255618845857],"rgb":[0.8,0.533333333333333326,1],"xyz":[0.517531366057268127,0.37666503794548134,0.991550541994674073],"hpluv":[286.350196506734335,167.63670457649863,67.7740978167257],"hsluv":[286.350196506734335,99.9999999999982379,67.7740978167257]},"#cc9900":{"lch":[66.2294666531998217,80.7116888085701163,57.6888018595631422],"luv":[66.2294666531998217,43.1418134232290527,68.2140795209226383],"rgb":[0.8,0.6,0],"xyz":[0.362920178107905556,0.356211923489684,0.0496415898958362731],"hpluv":[57.6888018595631422,154.64094800189136,66.2294666531998217],"hsluv":[57.6888018595631422,100.000000000002331,66.2294666531998217]},"#cc9911":{"lch":[66.2605931548954459,79.5070460268624,57.3307205104302042],"luv":[66.2605931548954459,42.9170325725223805,66.9290570909725915],"rgb":[0.8,0.6,0.0666666666666666657],"xyz":[0.36393184360754266,0.356616589689538854,0.0549696948605919],"hpluv":[57.3307205104302042,152.261332222626407,66.2605931548954459],"hsluv":[57.3307205104302042,98.1673920986410877,66.2605931548954459]},"#cc9922":{"lch":[66.318231165714252,77.3048675578901339,56.6444543825244],"luv":[66.318231165714252,42.5047546114663533,64.5708013235236535],"rgb":[0.8,0.6,0.133333333333333331],"xyz":[0.365807201746019717,0.357366732944929655,0.0648465810565711],"hpluv":[56.6444543825244,147.915345655385721,66.318231165714252],"hsluv":[56.6444543825244,94.8079930897652901,66.318231165714252]},"#cc9933":{"lch":[66.4129558628457772,73.7662990604099207,55.446788144651876],"luv":[66.4129558628457772,41.8381333944198062,60.7539091017242114],"rgb":[0.8,0.6,0.2],"xyz":[0.368894952478477423,0.358601833237912782,0.0811087349141822456],"hpluv":[55.446788144651876,140.943324602767206,66.4129558628457772],"hsluv":[55.446788144651876,89.3812598244831804,66.4129558628457772]},"#cc9944":{"lch":[66.5493334014023361,68.8491039809152596,53.5533094328142383],"luv":[66.5493334014023361,40.9015039610359423,55.3829043360877122],"rgb":[0.8,0.6,0.266666666666666663],"xyz":[0.373352947722696338,0.360385031335600348,0.104587509867068884],"hpluv":[53.5533094328142383,131.278591794008349,66.5493334014023361],"hsluv":[53.5533094328142383,81.7675495661837459,66.5493334014023361]},"#cc9955":{"lch":[66.7310322275847341,62.6300376921671571,50.6698876242401539],"luv":[66.7310322275847341,39.6941340540006422,48.4447865412296466],"rgb":[0.8,0.6,0.333333333333333315],"xyz":[0.379315361762058323,0.362769996951345208,0.135989557141042799],"hpluv":[50.6698876242401539,119.095172229338388,66.7310322275847341],"hsluv":[50.6698876242401539,71.9728873324543912,66.7310322275847341]},"#cc9966":{"lch":[66.9610303820851,55.3290996264574488,46.2964172073191236],"luv":[66.9610303820851,38.2284030091626121,39.9987308404091877],"rgb":[0.8,0.6,0.4],"xyz":[0.386900357535566508,0.365803995260748527,0.175937201548186761],"hpluv":[46.2964172073191236,104.850571413887963,66.9610303820851],"hsluv":[46.2964172073191236,60.1139469393688586,66.9610303820851]},"#cc9977":{"lch":[67.2417240975963608,47.3725698769106316,39.5497292985384448],"luv":[67.2417240975963608,36.5276723895038842,30.1643751227811094],"rgb":[0.8,0.6,0.466666666666666674],"xyz":[0.396214370555768414,0.369529600468829322,0.22499100345458467],"hpluv":[39.5497292985384448,89.3979234879296598,67.2417240975963608],"hsluv":[39.5497292985384448,46.4000360859745484,67.2417240975963608]},"#cc9988":{"lch":[67.5749927230407508,39.5461637624335367,28.8927829606528306],"luv":[67.5749927230407508,34.6236706423047593,19.1076031876950658],"rgb":[0.8,0.6,0.533333333333333326],"xyz":[0.407354787657712214,0.37398576730960692,0.28366386685815681],"hpluv":[28.8927829606528306,74.2604675709266076,67.5749927230407508],"hsluv":[28.8927829606528306,33.7758353105824227,67.5749927230407508]},"#cc9999":{"lch":[67.962242737641,33.3028609095241,12.177050630062606],"luv":[67.962242737641,32.5535618700051401,7.02468179598591647],"rgb":[0.8,0.6,0.6],"xyz":[0.420411751766784914,0.379208552953236078,0.352430544499274745],"hpluv":[12.177050630062606,62.1803508213615217,67.962242737641],"hsluv":[12.177050630062606,35.0991912912463349,67.962242737641]},"#cc99aa":{"lch":[68.4044417972397838,30.9200145018949506,349.049331623372325],"luv":[68.4044417972397838,30.3569952347367966,-5.87368173427548168],"rgb":[0.8,0.6,0.66666666666666663],"xyz":[0.43546944473203747,0.3852316301393372,0.431734394116273346],"hpluv":[349.049331623372325,57.3580941092039609,68.4044417972397838],"hsluv":[349.049331623372325,36.4663034143199312,68.4044417972397838]},"#cc99bb":{"lch":[68.9021485343020856,34.1112448474386483,325.385883063702067],"luv":[68.9021485343020856,28.0734328763681233,-19.3767745401024669],"rgb":[0.8,0.6,0.733333333333333282],"xyz":[0.452607036839374144,0.392086666982271959,0.521992379214915],"hpluv":[325.385883063702067,62.8208966420876678,68.9021485343020856],"hsluv":[325.385883063702067,37.8410036888738404,68.9021485343020856]},"#cc99cc":{"lch":[69.4555411877739601,42.0770553751994854,307.715012949247],"luv":[69.4555411877739601,25.7399796927440505,-33.285613025220492],"rgb":[0.8,0.6,0.8],"xyz":[0.471899412283095843,0.39980361715976076,0.623598889885185192],"hpluv":[307.715012949247,76.8736967911951581,69.4555411877739601],"hsluv":[307.715012949247,39.1886552488513473,69.4555411877739601]},"#cc99dd":{"lch":[70.0644466506374215,52.8759829560521695,296.254085335195782],"luv":[70.0644466506374215,23.3898305690433475,-47.4213601610093534],"rgb":[0.8,0.6,0.866666666666666696],"xyz":[0.493417737833729442,0.408410947380014266,0.73692873778519119],"hpluv":[296.254085335195782,95.7635162234915498,70.0644466506374215],"hsluv":[296.254085335195782,58.3905887561973813,70.0644466506374215]},"#cc99ee":{"lch":[70.7283706212672,65.1265075826905218,288.858843135035954],"luv":[70.7283706212672,21.0513451251656711,-61.6303728557552191],"rgb":[0.8,0.6,0.933333333333333348],"xyz":[0.517229918099904151,0.417935819486484283,0.862339553853714413],"hpluv":[288.858843135035954,116.843205481858362,70.7283706212672],"hsluv":[288.858843135035954,78.6530020758075494,70.7283706212672]},"#cc99ff":{"lch":[71.4465289765693115,78.0706881495843561,283.894640570210413],"luv":[71.4465289765693115,18.7476796475605703,-75.7862576987549517],"rgb":[0.8,0.6,1],"xyz":[0.543400966509735572,0.428404238850417,1.00017374214549637],"hpluv":[283.894640570210413,138.658404713871533,71.4465289765693115],"hsluv":[283.894640570210413,99.9999999999978,71.4465289765693115]},"#990000":{"lch":[31.2857235930303546,105.214874065330946,12.1770506300617765],"luv":[31.2857235930303546,102.847587834444283,22.1933188419334826],"rgb":[0.6,0,0],"xyz":[0.131365760434599882,0.067735470224092,0.00615777002037173893],"hpluv":[12.1770506300617765,426.746789183125316,31.2857235930303546],"hsluv":[12.1770506300617765,100.000000000002217,31.2857235930303546]},"#990011":{"lch":[31.379701704172021,102.819321078199806,10.8595456684147944],"luv":[31.379701704172021,100.978030711674904,19.3713732237542438],"rgb":[0.6,0,0.0666666666666666657],"xyz":[0.132377425934237014,0.0681401364239468538,0.0114858749851273704],"hpluv":[10.8595456684147944,415.781582167217948,31.379701704172021],"hsluv":[10.8595456684147944,99.9999999999964473,31.379701704172021]},"#990022":{"lch":[31.5529326060038784,98.7447775317108807,8.37468971343924729],"luv":[31.5529326060038784,97.6918390895904309,14.3817824027706251],"rgb":[0.6,0,0.133333333333333331],"xyz":[0.134252784072714015,0.0688902796793376682,0.0213627611811065682],"hpluv":[8.37468971343924729,397.112659756655944,31.5529326060038784],"hsluv":[8.37468971343924729,99.999999999996632,31.5529326060038784]},"#990033":{"lch":[31.8354354483696653,92.9837515463916162,4.18138532137367758],"luv":[31.8354354483696653,92.7362491408617586,6.7798338419980837],"rgb":[0.6,0,0.2],"xyz":[0.137340534805171777,0.070125379972320781,0.0376249150387177114],"hpluv":[4.18138532137367758,370.62575576901952,31.8354354483696653],"hsluv":[4.18138532137367758,99.9999999999969,31.8354354483696653]},"#990044":{"lch":[32.2375108843075537,86.4821897260425771,357.977822115898675],"luv":[32.2375108843075537,86.4283323676992552,-3.05163955108307716],"rgb":[0.6,0,0.266666666666666663],"xyz":[0.141798530049390636,0.071908578070008361,0.0611036899916043499],"hpluv":[357.977822115898675,340.411718586576399,32.2375108843075537],"hsluv":[357.977822115898675,99.9999999999971294,32.2375108843075537]},"#990055":{"lch":[32.7650133258702,80.5606445545256804,349.629319937368109],"luv":[32.7650133258702,79.244583226626645,-14.502188809930411],"rgb":[0.6,0,0.333333333333333315],"xyz":[0.147760944088752622,0.0742935436857532,0.0925057372655782584],"hpluv":[349.629319937368109,311.998071704954214,32.7650133258702],"hsluv":[349.629319937368109,99.9999999999974847,32.7650133258702]},"#990066":{"lch":[33.4199981031921354,76.5714397631706589,339.419101050621862],"luv":[33.4199981031921354,71.6844038684648268,-26.9171252073414813],"rgb":[0.6,0,0.4],"xyz":[0.155345939862260807,0.0773275419951565124,0.13245338167272222],"hpluv":[339.419101050621862,290.7366076723265,33.4199981031921354],"hsluv":[339.419101050621862,99.9999999999978257,33.4199981031921354]},"#990077":{"lch":[34.2012599030024091,75.4745938555541187,328.234093427391315],"luv":[34.2012599030024091,64.1689603650959413,-39.7335984190155429],"rgb":[0.6,0,0.466666666666666674],"xyz":[0.164659952882462712,0.0810531472032373218,0.181507183579120129],"hpluv":[328.234093427391315,280.025774017920355,34.2012599030024091],"hsluv":[328.234093427391315,99.9999999999982094,34.2012599030024091]},"#990088":{"lch":[35.1048906557013396,77.5195253213057214,317.327493504651898],"luv":[35.1048906557013396,56.9954501323273419,-52.5432723595889613],"rgb":[0.6,0,0.533333333333333326],"xyz":[0.175800369984406568,0.0855093140440149196,0.240180046982692297],"hpluv":[317.327493504651898,280.209468657326,35.1048906557013396],"hsluv":[317.327493504651898,99.9999999999985505,35.1048906557013396]},"#990099":{"lch":[36.1248689761228263,82.286593786153162,307.715012949243601],"luv":[36.1248689761228263,50.3375351282041592,-65.0939019735657922],"rgb":[0.6,0,0.6],"xyz":[0.188857334093479268,0.0907320996876440772,0.308946724623810232],"hpluv":[307.715012949243601,289.042783730483336,36.1248689761228263],"hsluv":[307.715012949243601,99.9999999999988205,36.1248689761228263]},"#9900aa":{"lch":[37.2536516336468,89.0432435337247,299.813571633796073],"luv":[37.2536516336468,44.2704748017611038,-77.2581664281054685],"rgb":[0.6,0,0.66666666666666663],"xyz":[0.203915027058731824,0.0967551768737451856,0.388250574240808777],"hpluv":[299.813571633796073,303.299328566743952,37.2536516336468],"hsluv":[299.813571633796073,99.9999999999990905,37.2536516336468]},"#9900bb":{"lch":[38.4827280957899163,97.0854614833978786,293.557760104203282],"luv":[38.4827280957899163,38.802472411223853,-88.9941288300556579],"rgb":[0.6,0,0.733333333333333282],"xyz":[0.221052619166068443,0.103610213716679944,0.478508559339450579],"hpluv":[293.557760104203282,320.130957524774431,38.4827280957899163],"hsluv":[293.557760104203282,99.9999999999993179,38.4827280957899163]},"#9900cc":{"lch":[39.8031058181596933,105.884836559305498,288.673688741635],"luv":[39.8031058181596933,33.9019931565070394,-100.310784431221492],"rgb":[0.6,0,0.8],"xyz":[0.240344994609790197,0.111327163894168746,0.580115070009720735],"hpluv":[288.673688741635,337.564008898092311,39.8031058181596933],"hsluv":[288.673688741635,99.9999999999995879,39.8031058181596933]},"#9900dd":{"lch":[41.2057071388761145,115.092674624289529,284.860629917023232],"luv":[41.2057071388761145,29.5176685469448401,-111.243116621772529],"rgb":[0.6,0,0.866666666666666696],"xyz":[0.26186332016042374,0.11993449411442228,0.693444917909726732],"hpluv":[284.860629917023232,354.429316861661562,41.2057071388761145],"hsluv":[284.860629917023232,99.9999999999996732,41.2057071388761145]},"#9900ee":{"lch":[42.6816722484951754,124.494824438150232,281.862271937449748],"luv":[42.6816722484951754,25.5911328567321625,-121.836181945245357],"rgb":[0.6,0,0.933333333333333348],"xyz":[0.285675500426598505,0.129459366220892297,0.81885573397825],"hpluv":[281.862271937449748,370.125661914021862,42.6816722484951754],"hsluv":[281.862271937449748,99.9999999999998437,42.6816722484951754]},"#9900ff":{"lch":[44.2225734052255817,133.965544030308308,279.479958267333473],"luv":[44.2225734052255817,22.0644732467518,-132.136013288126151],"rgb":[0.6,0,1],"xyz":[0.311846548836429871,0.139927785584825,0.956689922270031801],"hpluv":[279.479958267333473,384.404468177447882,44.2225734052255817],"hsluv":[279.479958267333473,99.9999999999999574,44.2225734052255817]},"#bb0000":{"lch":[38.8409426943877918,130.623313921981463,12.1770506300617818],"luv":[38.8409426943877918,127.684349491075153,27.5528044852332741],"rgb":[0.733333333333333282,0,0],"xyz":[0.20493059501477473,0.105667338054495463,0.00960612164131736251],"hpluv":[12.1770506300617818,426.746789183125145,38.8409426943877918],"hsluv":[12.1770506300617818,100.000000000002217,38.8409426943877918]},"#bb0011":{"lch":[38.9108602521517142,128.680110500437479,11.3344428162225856],"luv":[38.9108602521517142,126.170422440132384,25.2902222149853806],"rgb":[0.733333333333333282,0,0.0666666666666666657],"xyz":[0.205942260514411862,0.106072004254350316,0.014934226606072994],"hpluv":[11.3344428162225856,419.642938315359174,38.9108602521517142],"hsluv":[11.3344428162225856,99.9999999999964189,38.9108602521517142]},"#bb0022":{"lch":[39.0399998564474373,125.270257566289573,9.75441483214293292],"luv":[39.0399998564474373,123.459226352671962,21.2239689767074431],"rgb":[0.733333333333333282,0,0.133333333333333331],"xyz":[0.207817618652888864,0.10682214750974113,0.0248111128020521918],"hpluv":[9.75441483214293292,407.171610230013243,39.0399998564474373],"hsluv":[9.75441483214293292,99.9999999999965326,39.0399998564474373]},"#bb0033":{"lch":[39.2513155564018916,120.169209623826248,7.10634666793171554],"luv":[39.2513155564018916,119.246098647877318,14.866300779810846],"rgb":[0.733333333333333282,0,0.2],"xyz":[0.210905369385346597,0.108057247802724243,0.041073266659663335],"hpluv":[7.10634666793171554,388.488631169232178,39.2513155564018916],"hsluv":[7.10634666793171554,99.9999999999967173,39.2513155564018916]},"#bb0044":{"lch":[39.5535843326651886,113.833969399977519,3.19865110237705785],"luv":[39.5535843326651886,113.656624965458903,6.3517077086437],"rgb":[0.733333333333333282,0,0.266666666666666663],"xyz":[0.215363364629565485,0.109840445900411823,0.0645520416125499735],"hpluv":[3.19865110237705785,365.195452768261646,39.5535843326651886],"hsluv":[3.19865110237705785,99.9999999999968878,39.5535843326651886]},"#bb0055":{"lch":[39.9527871554326666,107.03859947839959,357.869864695501747],"luv":[39.9527871554326666,106.964633924407806,-3.97855095665153691],"rgb":[0.733333333333333282,0,0.333333333333333315],"xyz":[0.221325778668927498,0.112225411516156656,0.095954088886523875],"hpluv":[357.869864695501747,339.963790558847222,39.9527871554326666],"hsluv":[357.869864695501747,99.9999999999971436,39.9527871554326666]},"#bb0066":{"lch":[40.452535568346093,100.749762000256624,351.053086521713055],"luv":[40.452535568346093,99.5239253968718884,-15.6685295004423661],"rgb":[0.733333333333333282,0,0.4],"xyz":[0.228910774442435655,0.115259409825559975,0.135901733293667837],"hpluv":[351.053086521713055,316.036764522848955,40.452535568346093],"hsluv":[351.053086521713055,99.999999999997442,40.452535568346093]},"#bb0077":{"lch":[41.0543478797665813,95.9494038996296581,342.883287985183927],"luv":[41.0543478797665813,91.699536963203,-28.2397420212797314],"rgb":[0.733333333333333282,0,0.466666666666666674],"xyz":[0.238224787462637588,0.118985015033640784,0.184955535200065746],"hpluv":[342.883287985183927,296.56674422547627,41.0543478797665813],"hsluv":[342.883287985183927,99.9999999999977,41.0543478797665813]},"#bb0088":{"lch":[41.7578935904565398,93.4210879643116243,333.788939203308246],"luv":[41.7578935904565398,83.8148890966975699,-41.2621381189091565],"rgb":[0.733333333333333282,0,0.533333333333333326],"xyz":[0.249365204564581389,0.123441181874418382,0.243628398603637913],"hpluv":[333.788939203308246,283.887103643995431,41.7578935904565398],"hsluv":[333.788939203308246,99.9999999999980531,41.7578935904565398]},"#bb0099":{"lch":[42.5612451572515,93.5592166386053918,324.452137443226093],"luv":[42.5612451572515,76.1225984195714318,-54.3937223205229472],"rgb":[0.733333333333333282,0,0.6],"xyz":[0.262422168673654088,0.12866396751804754,0.31239507624475582],"hpluv":[324.452137443226093,278.940502109978524,42.5612451572515],"hsluv":[324.452137443226093,99.9999999999983089,42.5612451572515]},"#bb00aa":{"lch":[43.461144448190268,96.3048592888224562,315.591494301740738],"luv":[43.461144448190268,68.7971872487792,-67.3911934105362747],"rgb":[0.733333333333333282,0,0.66666666666666663],"xyz":[0.277479861638906644,0.134687044704148634,0.391698925861754421],"hpluv":[315.591494301740738,281.181257774391042,43.461144448190268],"hsluv":[315.591494301740738,99.9999999999985647,43.461144448190268]},"#bb00bb":{"lch":[44.4532771259814652,101.257357078489918,307.715012949243601],"luv":[44.4532771259814652,61.9426024872754866,-80.100976021670192],"rgb":[0.733333333333333282,0,0.733333333333333282],"xyz":[0.294617453746243319,0.141542081547083393,0.481956910960396168],"hpluv":[307.715012949243601,289.042783730483507,44.4532771259814652],"hsluv":[307.715012949243601,99.9999999999988205,44.4532771259814652]},"#bb00cc":{"lch":[45.5325428123826796,107.876917991024385,301.028560594476971],"luv":[45.5325428123826796,55.6068066637028551,-92.44085940701639],"rgb":[0.733333333333333282,0,0.8],"xyz":[0.313909829189965,0.149259031724572194,0.583563421630666324],"hpluv":[301.028560594476971,300.639438898355309,45.5325428123826796],"hsluv":[301.028560594476971,99.999999999999,45.5325428123826796]},"#bb00dd":{"lch":[46.6933085129957348,115.650155059812704,295.504945579136574],"luv":[46.6933085129957348,49.7976850024997,-104.379830109799173],"rgb":[0.733333333333333282,0,0.866666666666666696],"xyz":[0.335428154740598616,0.157866361944825728,0.696893269530672321],"hpluv":[295.504945579136574,314.290242754568055,46.6933085129957348],"hsluv":[295.504945579136574,99.9999999999992468,46.6933085129957348]},"#bb00ee":{"lch":[47.929635203682146,124.167261181765113,290.999747870951808],"luv":[47.929635203682146,44.4970566855085821,-115.920320460682433],"rgb":[0.733333333333333282,0,0.933333333333333348],"xyz":[0.359240335006773326,0.167391234051295773,0.822304085599195544],"hpluv":[290.999747870951808,328.732244305823656,47.929635203682146],"hsluv":[290.999747870951808,99.9999999999993889,47.929635203682146]},"#bb00ff":{"lch":[49.2354711183318727,133.13261796854033,287.33664116340708],"luv":[49.2354711183318727,39.6715752597668896,-127.084460433075606],"rgb":[0.733333333333333282,0,1],"xyz":[0.385411383416604747,0.177859653415228469,0.96013827389097739],"hpluv":[287.33664116340708,343.119737385630629,49.2354711183318727],"hsluv":[287.33664116340708,99.9999999999995595,49.2354711183318727]},"#991100":{"lch":[32.2007428060931531,101.551746681272988,13.5001929330929755],"luv":[32.2007428060931531,98.7457840078795,23.707116962774041],"rgb":[0.6,0.0666666666666666657,0],"xyz":[0.133370160695528289,0.071744270745948871,0.00682590344068119],"hpluv":[13.5001929330929755,400.185025755779861,32.2007428060931531],"hsluv":[13.5001929330929755,100.000000000002359,32.2007428060931531]},"#991111":{"lch":[32.2911967351305,99.2607003603350506,12.1770506300617907],"luv":[32.2911967351305,97.0273802968116854,20.9373854328113431],"rgb":[0.6,0.0666666666666666657,0.0666666666666666657],"xyz":[0.134381826195165421,0.0721489369458037239,0.0121540084054368204],"hpluv":[12.1770506300617907,390.060992150638072,32.2911967351305],"hsluv":[12.1770506300617907,91.4033806551417,32.2911967351305]},"#991122":{"lch":[32.4579836187547883,95.3555453821432337,9.67722696349737355],"luv":[32.4579836187547883,93.9986702773161085,16.0290368151797],"rgb":[0.6,0.0666666666666666657,0.133333333333333331],"xyz":[0.136257184333642423,0.0728990802011945382,0.0220308946014160165],"hpluv":[9.67722696349737355,372.789562407290305,32.4579836187547883],"hsluv":[9.67722696349737355,91.6870397393079,32.4579836187547883]},"#991133":{"lch":[32.7301206059751877,89.8170234432985382,5.44607482402752385],"luv":[32.7301206059751877,89.4115862394302,8.52443231910342547],"rgb":[0.6,0.0666666666666666657,0.2],"xyz":[0.139344935066100184,0.0741341804941776511,0.0382930484590271597],"hpluv":[5.44607482402752385,348.217328437078379,32.7301206059751877],"hsluv":[5.44607482402752385,92.1153976677825312,32.7301206059751877]},"#991144":{"lch":[33.1177416447746893,83.547386161100178,359.159050762907725],"luv":[33.1177416447746893,83.5383872622118275,-1.22620878349376072],"rgb":[0.6,0.0666666666666666657,0.266666666666666663],"xyz":[0.143802930310319044,0.0759173785918652311,0.0617718234119138],"hpluv":[359.159050762907725,320.119020896680809,33.1177416447746893],"hsluv":[359.159050762907725,92.6613616101701609,33.1177416447746893]},"#991155":{"lch":[33.6267967661613341,77.8365467514172451,350.652860745276428],"luv":[33.6267967661613341,76.8030661853154,-12.6418762341523276],"rgb":[0.6,0.0666666666666666657,0.333333333333333315],"xyz":[0.149765344349681029,0.078302344207610064,0.0931738706858877136],"hpluv":[350.652860745276428,293.722615948770908,33.6267967661613341],"hsluv":[350.652860745276428,93.2833986807069664,33.6267967661613341]},"#991166":{"lch":[34.2596587707945375,74.039902428482776,340.197584074025258],"luv":[34.2596587707945375,69.661662743272629,-25.0830599301957804],"rgb":[0.6,0.0666666666666666657,0.4],"xyz":[0.157350340123189214,0.0813363425170133825,0.133121515093031662],"hpluv":[340.197584074025258,274.234525914752396,34.2596587707945375],"hsluv":[340.197584074025258,93.9371476037906774,34.2596587707945375]},"#991177":{"lch":[35.0156115165229096,73.1458980715855773,328.71391057162549],"luv":[35.0156115165229096,62.509382661628635,-37.9855167657472848],"rgb":[0.6,0.0666666666666666657,0.466666666666666674],"xyz":[0.16666435314339112,0.0850619477250941919,0.182175316999429571],"hpluv":[328.71391057162549,265.074278305330154,35.0156115165229096],"hsluv":[328.71391057162549,94.5844210689808165,35.0156115165229096]},"#991188":{"lch":[35.8913494409224185,75.4242755669397269,317.528981112118743],"luv":[35.8913494409224185,55.6343762077295239,-50.9277677576239398],"rgb":[0.6,0.0666666666666666657,0.533333333333333326],"xyz":[0.177804770245334975,0.0895181145658717897,0.240848180403001738],"hpluv":[317.528981112118743,266.661726649655066,35.8913494409224185],"hsluv":[317.528981112118743,95.1976582537924116,35.8913494409224185]},"#991199":{"lch":[36.8815072257793,80.448343562419069,307.715012949243601],"luv":[36.8815072257793,49.2130143411107568,-63.6397297401445599],"rgb":[0.6,0.0666666666666666657,0.6],"xyz":[0.190861734354407675,0.0947409002095009473,0.309614858044119645],"hpluv":[307.715012949243601,276.788327826692239,36.8815072257793],"hsluv":[307.715012949243601,95.7603314825458511,36.8815072257793]},"#9911aa":{"lch":[37.9791974354050694,87.4639739592788,299.695850237394552],"luv":[37.9791974354050694,43.3292813921454609,-75.9771025690614152],"rgb":[0.6,0.0666666666666666657,0.66666666666666663],"xyz":[0.205919427319660231,0.100763977395602056,0.388918707661118246],"hpluv":[299.695850237394552,292.228621346341356,37.9791974354050694],"hsluv":[299.695850237394552,96.26500390067784,37.9791974354050694]},"#9911bb":{"lch":[39.176522525078866,95.7489617369993624,293.383950362709356],"luv":[39.176522525078866,38.0018814997404846,-87.8847010360338459],"rgb":[0.6,0.0666666666666666657,0.733333333333333282],"xyz":[0.22305701942699685,0.107619014238536814,0.47917669275976],"hpluv":[293.383950362709356,310.132668732371314,39.176522525078866],"hsluv":[293.383950362709356,96.7106400677762537,39.176522525078866]},"#9911cc":{"lch":[40.465031277763515,104.765415075180798,288.480743990765689],"luv":[40.465031277763515,33.2091620218187842,-99.3626879350770622],"rgb":[0.6,0.0666666666666666657,0.8],"xyz":[0.242349394870718604,0.115335964416025616,0.580783203430030204],"hpluv":[288.480743990765689,328.531778006508034,40.465031277763515],"hsluv":[288.480743990765689,97.1001366995766,40.465031277763515]},"#9911dd":{"lch":[41.8361001822542917,114.161763941518927,284.668123617886636],"luv":[41.8361001822542917,28.9080153835727351,-110.441092863219225],"rgb":[0.6,0.0666666666666666657,0.866666666666666696],"xyz":[0.263867720421352148,0.12394329463627915,0.694113051330036201],"hpluv":[284.668123617886636,346.265164959266087,41.8361001822542917],"hsluv":[284.668123617886636,97.4384492036098,41.8361001822542917]},"#9911ee":{"lch":[43.2812320372341617,123.724619665436521,281.679545129349094],"luv":[43.2812320372341617,25.0465268392882301,-121.162919264293635],"rgb":[0.6,0.0666666666666666657,0.933333333333333348],"xyz":[0.287679900687526913,0.133468166742749167,0.819523867398559425],"hpluv":[281.679545129349094,362.740326129136179,43.2812320372341617],"hsluv":[281.679545129349094,97.7313369542794561,43.2812320372341617]},"#9911ff":{"lch":[44.7922739406791948,133.33068560825987,279.310828677429186],"luv":[44.7922739406791948,21.5716156333953251,-131.574074664174219],"rgb":[0.6,0.0666666666666666657,1],"xyz":[0.313850949097358278,0.143936586106681863,0.95735805569034127],"hpluv":[279.310828677429186,377.716823123197173,44.7922739406791948],"hsluv":[279.310828677429186,99.9999999999993179,44.7922739406791948]},"#bb1100":{"lch":[39.5258701457598747,127.514079962112703,13.0219609303782402],"luv":[39.5258701457598747,124.2348987579322,28.7320469022032583],"rgb":[0.733333333333333282,0.0666666666666666657,0],"xyz":[0.206934995275703137,0.109676138576352333,0.0102742550616268143],"hpluv":[13.0219609303782402,409.370014873310311,39.5258701457598747],"hsluv":[13.0219609303782402,100.000000000002203,39.5258701457598747]},"#bb1111":{"lch":[39.5940766091873897,125.63034182067031,12.177050630061796],"luv":[39.5940766091873897,122.803716963532779,26.4996204863200759],"rgb":[0.733333333333333282,0.0666666666666666657,0.0666666666666666657],"xyz":[0.20794666077534027,0.110080804776207186,0.0156023600263824457],"hpluv":[12.177050630061796,402.627698793753552,39.5940766091873897],"hsluv":[12.177050630061796,94.3481495348726753,39.5940766091873897]},"#bb1122":{"lch":[39.7200723855077413,122.321798686612851,10.5915831721034426],"luv":[39.7200723855077413,120.23772406897838,22.4835972353282152],"rgb":[0.733333333333333282,0.0666666666666666657,0.133333333333333331],"xyz":[0.209822018913817271,0.110830948031598,0.0254792462223616401],"hpluv":[10.5915831721034426,390.780742551338619,39.7200723855077413],"hsluv":[10.5915831721034426,94.4721603032542561,39.7200723855077413]},"#bb1133":{"lch":[39.9262897734852,117.365304386249704,7.93115519261489421],"luv":[39.9262897734852,116.242655940639409,16.194431559742192],"rgb":[0.733333333333333282,0.0666666666666666657,0.2],"xyz":[0.212909769646275,0.112066048324581113,0.0417414000799727902],"hpluv":[7.93115519261489421,373.009679290071517,39.9262897734852],"hsluv":[7.93115519261489421,94.6648992051481173,39.9262897734852]},"#bb1144":{"lch":[40.2213637516280755,111.198866264944101,3.99799547396429888],"luv":[40.2213637516280755,110.928262725239179,7.75295991020434627],"rgb":[0.733333333333333282,0.0666666666666666657,0.266666666666666663],"xyz":[0.217367764890493892,0.113849246422268693,0.0652201750328594287],"hpluv":[3.99799547396429888,350.818828640487084,40.2213637516280755],"hsluv":[3.99799547396429888,94.920595316052,40.2213637516280755]},"#bb1155":{"lch":[40.6112374139617245,104.574630781207446,358.621384873601698],"luv":[40.6112374139617245,104.544360517453882,-2.51596641918957786],"rgb":[0.733333333333333282,0.0666666666666666657,0.333333333333333315],"xyz":[0.223330178929855905,0.116234212038013526,0.0966222223068333302],"hpluv":[358.621384873601698,326.752894857139097,40.6112374139617245],"hsluv":[358.621384873601698,95.2265760165129791,40.6112374139617245]},"#bb1166":{"lch":[41.0995768863194755,98.4443929415329251,351.723860164231496],"luv":[41.0995768863194755,97.4191751888273672,-14.1704907168206535],"rgb":[0.733333333333333282,0.0666666666666666657,0.4],"xyz":[0.230915174703364062,0.119268210347416845,0.136569866713977306],"hpluv":[351.723860164231496,303.943570446579713,41.0995768863194755],"hsluv":[351.723860164231496,95.5663396203906643,41.0995768863194755]},"#bb1177":{"lch":[41.688035181331955,93.7889310063258,343.43446060875408],"luv":[41.688035181331955,89.8961490854954093,-26.7403432832812094],"rgb":[0.733333333333333282,0.0666666666666666657,0.466666666666666674],"xyz":[0.240229187723566,0.122993815555497654,0.185623668620375215],"hpluv":[343.43446060875408,285.48249634694713,41.688035181331955],"hsluv":[343.43446060875408,95.9227087501184883,41.688035181331955]},"#bb1188":{"lch":[42.3764815581906475,91.4027083669889606,334.189166164708297],"luv":[42.3764815581906475,82.2840505377722309,-39.7968607294366805],"rgb":[0.733333333333333282,0.0666666666666666657,0.533333333333333326],"xyz":[0.251369604825509796,0.127449982396275252,0.244296532023947383],"hpluv":[334.189166164708297,273.699179760613617,42.3764815581906475],"hsluv":[334.189166164708297,96.2803174994205,42.3764815581906475]},"#bb1199":{"lch":[43.1632358766101092,91.692942572352564,324.693570122963422],"luv":[43.1632358766101092,74.8281105443768269,-52.9938637007650755],"rgb":[0.733333333333333282,0.0666666666666666657,0.6],"xyz":[0.264426568934582495,0.13267276803990441,0.31306320966506529],"hpluv":[324.693570122963422,269.563595898888195,43.1632358766101092],"hsluv":[324.693570122963422,96.6270445785018239,43.1632358766101092]},"#bb11aa":{"lch":[44.0453166933651,94.6050581990027553,315.694091730478135],"luv":[44.0453166933651,67.7013389352867847,-66.0806003544619784],"rgb":[0.733333333333333282,0.0666666666666666657,0.66666666666666663],"xyz":[0.279484261899835051,0.138695845226005504,0.39236705928206389],"hpluv":[315.694091730478135,272.554870225691275,44.0453166933651],"hsluv":[315.694091730478135,96.9544350138240105,44.0453166933651]},"#bb11bb":{"lch":[45.0186979872658242,99.7328976909900717,307.715012949243601],"luv":[45.0186979872658242,61.0100383302365472,-78.8950321933172205],"rgb":[0.733333333333333282,0.0666666666666666657,0.733333333333333282],"xyz":[0.296621854007171726,0.145550882068940263,0.482625044380705637],"hpluv":[307.715012949243601,281.115526817766181,45.0186979872658242],"hsluv":[307.715012949243601,97.2574105430315115,45.0186979872658242]},"#bb11cc":{"lch":[46.0785638011469771,106.527215460047387,300.962972083371881],"luv":[46.0785638011469771,54.8065495444917161,-91.3470840295328372],"rgb":[0.733333333333333282,0.0666666666666666657,0.8],"xyz":[0.315914229450893425,0.153267832246429064,0.584231555050975793],"hpluv":[300.962972083371881,293.360047474541318,46.0785638011469771],"hsluv":[300.962972083371881,97.5336183018287528,46.0785638011469771]},"#bb11dd":{"lch":[47.2195492447565,114.4666153484132,295.402801066287566],"luv":[47.2195492447565,49.1038079522977853,-103.3993330438134],"rgb":[0.733333333333333282,0.0666666666666666657,0.866666666666666696],"xyz":[0.337432555001527,0.161875162466682598,0.69756140295098179],"hpluv":[295.402801066287566,307.607082675331128,47.2195492447565],"hsluv":[295.402801066287566,97.7826899351839813,47.2195492447565]},"#bb11ee":{"lch":[48.4359581768354701,123.136484869400022,290.880608651701721],"luv":[48.4359581768354701,43.8885280811888,-115.049515465553711],"rgb":[0.733333333333333282,0.0666666666666666657,0.933333333333333348],"xyz":[0.361244735267701733,0.171400034573152643,0.822972219019505],"hpluv":[290.880608651701721,322.595409245987128,48.4359581768354701],"hsluv":[290.880608651701721,98.0055710342431325,48.4359581768354701]},"#bb11ff":{"lch":[49.7219510368964,132.239138283310353,287.21247838519713],"luv":[49.7219510368964,39.1316890181496575,-126.316667975763593],"rgb":[0.733333333333333282,0.0666666666666666657,1],"xyz":[0.387415783677533154,0.181868453937085339,0.960806407311286859],"hpluv":[287.21247838519713,337.482436204013879,49.7219510368964],"hsluv":[287.21247838519713,99.9999999999991758,49.7219510368964]},"#992200":{"lch":[33.8105832897308716,95.4307991554818358,16.0266852535062476],"luv":[33.8105832897308716,91.7217107848809263,26.3470149760569932],"rgb":[0.6,0.133333333333333331,0],"xyz":[0.137085784430296231,0.0791755182154848525,0.0080644446856038],"hpluv":[16.0266852535062476,358.158468302090569,33.8105832897308716],"hsluv":[16.0266852535062476,100.000000000002331,33.8105832897308716]},"#992211":{"lch":[33.8952997814050718,93.2922690289088195,14.6972380002076104],"luv":[33.8952997814050718,90.239744522062125,23.669304365681274],"rgb":[0.6,0.133333333333333331,0.0666666666666666657],"xyz":[0.138097449929933364,0.0795801844153397,0.0133925496503594314],"hpluv":[14.6972380002076104,349.257308780581,33.8952997814050718],"hsluv":[14.6972380002076104,92.1483909924374274,33.8952997814050718]},"#992222":{"lch":[34.0515850466810335,89.6330213591727,12.1770506300618084],"luv":[34.0515850466810335,87.6163196410811338,18.9065874902323579],"rgb":[0.6,0.133333333333333331,0.133333333333333331],"xyz":[0.139972808068410365,0.0803303276707305197,0.0232694358463386292],"hpluv":[12.1770506300618084,334.018122077437397,34.0515850466810335],"hsluv":[12.1770506300618084,78.2707991117683,34.0515850466810335]},"#992233":{"lch":[34.3068003204445446,84.4135643942939282,7.88651435003668233],"luv":[34.3068003204445446,83.6151628365757773,11.58250394183076],"rgb":[0.6,0.133333333333333331,0.2],"xyz":[0.143060558800868098,0.0815654279637136326,0.0395315897039497724],"hpluv":[7.88651435003668233,312.227643050581207,34.3068003204445446],"hsluv":[7.88651435003668233,79.3008398259009226,34.3068003204445446]},"#992244":{"lch":[34.6707661525426,78.4682482149262199,1.45557545410962708],"luv":[34.6707661525426,78.4429281517087134,1.99323879782018309],"rgb":[0.6,0.133333333333333331,0.266666666666666663],"xyz":[0.147518554045086986,0.0833486260614012126,0.0630103646568364],"hpluv":[1.45557545410962708,287.190351340663,34.6707661525426],"hsluv":[1.45557545410962708,80.6267396657693212,34.6707661525426]},"#992255":{"lch":[35.149531709850983,73.0418005898087443,352.659616011821072],"luv":[35.149531709850983,72.4431965063170082,-9.33209051330535821],"rgb":[0.6,0.133333333333333331,0.333333333333333315],"xyz":[0.153480968084449,0.0857335916771460455,0.0944124119308103193],"hpluv":[352.659616011821072,263.688538908073838,35.149531709850983],"hsluv":[352.659616011821072,82.1555178352066804,35.149531709850983]},"#992266":{"lch":[35.7459223236079495,69.5043059181480203,341.734006615383123],"luv":[35.7459223236079495,66.0021002604389793,-21.7846574995905513],"rgb":[0.6,0.133333333333333331,0.4],"xyz":[0.161065963857957156,0.0887675899865493639,0.134360056337954281],"hpluv":[341.734006615383123,246.731460763727796,35.7459223236079495],"hsluv":[341.734006615383123,83.7834402291280753,35.7459223236079495]},"#992277":{"lch":[36.4599553630224946,68.9051746310403104,329.662355423262511],"luv":[36.4599553630224946,59.4695672743266783,-34.8036443370302],"rgb":[0.6,0.133333333333333331,0.466666666666666674],"xyz":[0.17037997687815909,0.0924931951946301734,0.18341385824435219],"hpluv":[329.662355423262511,239.814275331209444,36.4599553630224946],"hsluv":[329.662355423262511,85.4170781092293225,36.4599553630224946]},"#992288":{"lch":[37.2892540647929,71.5563678213307242,317.925484235555643],"luv":[37.2892540647929,53.1144286836587369,-47.9496740488411],"rgb":[0.6,0.133333333333333331,0.533333333333333326],"xyz":[0.18152039398010289,0.0969493620354077712,0.242086721647924358],"hpluv":[317.925484235555643,243.502777039008038,37.2892540647929],"hsluv":[317.925484235555643,86.9852623869732,37.2892540647929]},"#992299":{"lch":[38.2294870734457888,77.015786119064046,307.715012949243771],"luv":[38.2294870734457888,47.1132010795059841,-60.9243596238766827],"rgb":[0.6,0.133333333333333331,0.6],"xyz":[0.194577358089175617,0.102172147679036929,0.310853399289042265],"hpluv":[307.715012949243771,255.635172818446421,38.2294870734457888],"hsluv":[307.715012949243771,88.441984096309227,38.2294870734457888]},"#9922aa":{"lch":[39.2748221448681178,84.484081905089468,299.468150353755561],"luv":[39.2748221448681178,41.5610713460956234,-73.5543162833468],"rgb":[0.6,0.133333333333333331,0.66666666666666663],"xyz":[0.209635051054428145,0.108195224865138023,0.390157248906040865],"hpluv":[299.468150353755561,272.960615272696657,39.2748221448681178],"hsluv":[299.468150353755561,89.7633288768494708,39.2748221448681178]},"#9922bb":{"lch":[40.4183688993281436,93.2013493596814726,293.05045530637],"luv":[40.4183688993281436,36.4922039393154094,-85.7601922462677919],"rgb":[0.6,0.133333333333333331,0.733333333333333282],"xyz":[0.22677264316176482,0.115050261708072782,0.480415234004682612],"hpluv":[293.05045530637,292.605673863240838,40.4183688993281436],"hsluv":[293.05045530637,90.9419133161227222,40.4183688993281436]},"#9922cc":{"lch":[41.6525852773545182,102.609691310931794,288.11294916137831],"luv":[41.6525852773545182,31.900454524651952,-97.5249186210648702],"rgb":[0.6,0.133333333333333331,0.8],"xyz":[0.246065018605486546,0.122767211885561583,0.582021744674952712],"hpluv":[288.11294916137831,312.597676326075884,41.6525852773545182],"hsluv":[288.11294916137831,91.9812251551093851,41.6525852773545182]},"#9922dd":{"lch":[42.969628845807982,112.350489371469905,284.303043907998301],"luv":[42.969628845807982,27.7562437333976213,-108.867917201630149],"rgb":[0.6,0.133333333333333331,0.866666666666666696],"xyz":[0.267583344156120062,0.131374542105815117,0.69535159257495871],"hpluv":[284.303043907998301,331.781902020401162,42.969628845807982],"hsluv":[284.303043907998301,92.8910125551507235,42.969628845807982]},"#9922ee":{"lch":[44.361642902098545,122.210344632057584,281.334390799049743],"luv":[44.361642902098545,24.018574136526297,-119.826860225637532],"rgb":[0.6,0.133333333333333331,0.933333333333333348],"xyz":[0.291395524422294827,0.140899414212285162,0.820762408643481933],"hpluv":[281.334390799049743,349.574442537581717,44.361642902098545],"hsluv":[281.334390799049743,93.6839973987951566,44.361642902098545]},"#9922ff":{"lch":[45.8209755847726612,132.069283427413211,278.992348895848238],"luv":[45.8209755847726612,20.6427685166220094,-130.446049127597433],"rgb":[0.6,0.133333333333333331,1],"xyz":[0.317566572832126193,0.151367833576217858,0.958596596935263889],"hpluv":[278.992348895848238,365.74366826955071,45.8209755847726612],"hsluv":[278.992348895848238,99.9999999999993179,45.8209755847726612]},"#bb2200":{"lch":[40.7526421249889452,122.145166616692975,14.6188079362681389],"luv":[40.7526421249889452,118.190884669319914,30.8278528104570881],"rgb":[0.733333333333333282,0.133333333333333331,0],"xyz":[0.21065061901047108,0.117107386045888315,0.0115127963065494235],"hpluv":[14.6188079362681389,380.329350781024857,40.7526421249889452],"hsluv":[14.6188079362681389,100.000000000002217,40.7526421249889452]},"#bb2211":{"lch":[40.8179368215716849,120.355879944515436,13.7706881972771793],"luv":[40.8179368215716849,116.896392622501153,28.6491052053056343],"rgb":[0.733333333333333282,0.133333333333333331,0.0666666666666666657],"xyz":[0.211662284510108212,0.117512052245743168,0.0168409012713050532],"hpluv":[13.7706881972771793,374.158477594779924,40.8179368215716849],"hsluv":[13.7706881972771793,94.6800257514418,40.8179368215716849]},"#bb2222":{"lch":[40.9385803904414161,117.208042434762348,12.1770506300618102],"luv":[40.9385803904414161,114.570915436608942,24.7230772236478238],"rgb":[0.733333333333333282,0.133333333333333331,0.133333333333333331],"xyz":[0.213537642648585213,0.118262195501133982,0.0267177874672842527],"hpluv":[12.1770506300618102,363.298797482753,40.9385803904414161],"hsluv":[12.1770506300618102,85.1321689328196101,40.9385803904414161]},"#bb2233":{"lch":[41.136111673530813,112.480172956632245,9.49666640172232235],"luv":[41.136111673530813,110.938654987290519,18.5581286223806821],"rgb":[0.733333333333333282,0.133333333333333331,0.2],"xyz":[0.216625393381042974,0.119497295794117095,0.042979941324895396],"hpluv":[9.49666640172232235,346.970109935861444,41.136111673530813],"hsluv":[9.49666640172232235,85.6217357677037398,41.136111673530813]},"#bb2244":{"lch":[41.4189140922405201,106.57909239531196,5.51995404221549],"luv":[41.4189140922405201,106.084859394728952,10.2520994439692306],"rgb":[0.733333333333333282,0.133333333333333331,0.266666666666666663],"xyz":[0.221083388625261834,0.121280493891804675,0.0664587162777820345],"hpluv":[5.51995404221549,326.522141050690152,41.4189140922405201],"hsluv":[5.51995404221549,86.2742612371986297,41.4189140922405201]},"#bb2255":{"lch":[41.7928521194743823,100.22104851316422,0.0579838467833058424],"luv":[41.7928521194743823,100.220997191859041,0.101424589714973798],"rgb":[0.733333333333333282,0.133333333333333331,0.333333333333333315],"xyz":[0.227045802664623819,0.123665459507549508,0.097860763551755936],"hpluv":[0.0579838467833058424,304.296010337655673,41.7928521194743823],"hsluv":[0.0579838467833058424,87.0597094656736772,41.7928521194743823]},"#bb2266":{"lch":[42.2616671880265216,94.3342448936905,353.011685321171171],"luv":[42.2616671880265216,93.6334344607092106,-11.4773564358193614],"rgb":[0.733333333333333282,0.133333333333333331,0.4],"xyz":[0.234630798438132,0.126699457816952826,0.137808407958899898],"hpluv":[353.011685321171171,283.244886623536,42.2616671880265216],"hsluv":[353.011685321171171,87.937804292381287,42.2616671880265216]},"#bb2277":{"lch":[42.8272221099346666,89.9002723684957,344.496654306277264],"luv":[42.8272221099346666,86.6292371691086771,-24.0298614109202155],"rgb":[0.733333333333333282,0.133333333333333331,0.466666666666666674],"xyz":[0.24394481145833391,0.13042506302503365,0.186862209865297807],"hpluv":[344.496654306277264,266.367005402095344,42.8272221099346666],"hsluv":[344.496654306277264,88.8655868844719805,42.8272221099346666]},"#bb2288":{"lch":[43.4897067779173554,87.7363054907772693,334.961981200390596],"luv":[43.4897067779173554,79.4914755013727898,-37.1317199141871441],"rgb":[0.733333333333333282,0.133333333333333331,0.533333333333333326],"xyz":[0.255085228560277766,0.13488122986581122,0.245535073268869974],"hpluv":[334.961981200390596,255.995416581420926,43.4897067779173554],"hsluv":[334.961981200390596,89.8036443318747786,43.4897067779173554]},"#bb2299":{"lch":[44.2478449340908639,88.2751432264235092,325.159464012784042],"luv":[44.2478449340908639,72.4514028672968635,-50.4310929309115],"rgb":[0.733333333333333282,0.133333333333333331,0.6],"xyz":[0.268142192669350465,0.140104015509440405,0.314301750909987909],"hpluv":[325.159464012784042,253.154489640486645,44.2478449340908639],"hsluv":[325.159464012784042,90.7199745934293844,44.2478449340908639]},"#bb22aa":{"lch":[45.0991127685299062,91.4705260319517919,315.891475419905078],"luv":[45.0991127685299062,65.6779186933914758,-63.6652819727222195],"rgb":[0.733333333333333282,0.133333333333333331,0.66666666666666663],"xyz":[0.283199885634603,0.146127092695541499,0.39360560052698651],"hpluv":[315.891475419905078,257.366789521381691,45.0991127685299062],"hsluv":[315.891475419905078,91.5914304646717,45.0991127685299062]},"#bb22bb":{"lch":[46.0399667792549678,96.9048462314552,307.715012949243658],"luv":[46.0399667792549678,59.2800221375787615,-76.6578645574617497],"rgb":[0.733333333333333282,0.133333333333333331,0.733333333333333282],"xyz":[0.30033747774193964,0.152982129538476258,0.483863585625628256],"hpluv":[307.715012949243658,267.0851991180906,46.0399667792549678],"hsluv":[307.715012949243658,92.4033444706684,46.0399667792549678]},"#bb22cc":{"lch":[47.066072507765945,104.009692587178989,300.837938637053412],"luv":[47.066072507765945,53.3165662395356,-89.3048706202785496],"rgb":[0.733333333333333282,0.133333333333333331,0.8],"xyz":[0.319629853185661394,0.16069907971596506,0.585470096295898412],"hpluv":[300.837938637053412,280.417543020287,47.066072507765945],"hsluv":[300.837938637053412,93.1481326309998,47.066072507765945]},"#bb22dd":{"lch":[48.1725242595717589,112.247547842848149,295.20893392435471],"luv":[48.1725242595717589,47.808517424121824,-101.557164486017044],"rgb":[0.733333333333333282,0.133333333333333331,0.866666666666666696],"xyz":[0.341148178736294938,0.169306409936218594,0.69879994419590441],"hpluv":[295.20893392435471,295.676483579310798,48.1725242595717589],"hsluv":[295.20893392435471,93.8235497257627316,48.1725242595717589]},"#bb22ee":{"lch":[49.3540469689012724,121.194036197623419,290.655339197387],"luv":[49.3540469689012724,42.7506603945962169,-113.403595382583688],"rgb":[0.733333333333333282,0.133333333333333331,0.933333333333333348],"xyz":[0.364960359002469703,0.178831282042688611,0.824210760264427633],"hpluv":[290.655339197387,311.600255956968681,49.3540469689012724],"hsluv":[290.655339197387,94.4310255689598,49.3540469689012724]},"#bb22ff":{"lch":[50.6051737457033397,130.547024148317973,286.97844412333734],"luv":[50.6051737457033397,38.1212848334983647,-124.85709093449519],"rgb":[0.733333333333333282,0.133333333333333331,1],"xyz":[0.391131407412301069,0.189299701406621335,0.962044948556209478],"hpluv":[286.97844412333734,327.349274436557835,50.6051737457033397],"hsluv":[286.97844412333734,99.9999999999991616,50.6051737457033397]},"#993300":{"lch":[36.2545465004255476,86.9834057059747749,20.3835344027483316],"luv":[36.2545465004255476,81.5366895093473,30.2965531383769893],"rgb":[0.6,0.2,0],"xyz":[0.14320350651930705,0.0914109623935066423,0.0101036853819406816],"hpluv":[20.3835344027483316,304.448092478673459,36.2545465004255476],"hsluv":[20.3835344027483316,100.00000000000226,36.2545465004255476]},"#993311":{"lch":[36.3315413581227133,85.0112276295678839,19.0571063974297203],"luv":[36.3315413581227133,80.3520694714869279,27.7570487396543],"rgb":[0.6,0.2,0.0666666666666666657],"xyz":[0.144215172018944182,0.0918156285933615,0.0154317903466963131],"hpluv":[19.0571063974297203,296.914762557758195,36.3315413581227133],"hsluv":[19.0571063974297203,93.1288353931581,36.3315413581227133]},"#993322":{"lch":[36.4736730302835852,81.6150828115545863,16.5278497598068661],"luv":[36.4736730302835852,78.2428757472059573,23.217970134019108],"rgb":[0.6,0.2,0.133333333333333331],"xyz":[0.146090530157421183,0.0925657718487523096,0.0253086765426755109],"hpluv":[16.5278497598068661,283.942401799749632,36.4736730302835852],"hsluv":[16.5278497598068661,80.9121244795507124,36.4736730302835852]},"#993333":{"lch":[36.7060271438600836,76.7221326388105638,12.1770506300618369],"luv":[36.7060271438600836,74.9959199734098121,16.1832513417159589],"rgb":[0.6,0.2,0.2],"xyz":[0.149178280889878945,0.0938008721417354224,0.0415708304002866541],"hpluv":[12.1770506300618369,265.229979343802,36.7060271438600836],"hsluv":[12.1770506300618369,62.1516051360361459,36.7060271438600836]},"#993344":{"lch":[37.0379214664673668,71.077614272095758,5.55118145677439934],"luv":[37.0379214664673668,70.7442733159460744,6.87568495580995354],"rgb":[0.6,0.2,0.266666666666666663],"xyz":[0.153636276134097804,0.095584070239423,0.0650496053531732926],"hpluv":[5.55118145677439934,243.514912685509444,37.0379214664673668],"hsluv":[5.55118145677439934,64.3097526797848644,37.0379214664673668]},"#993355":{"lch":[37.4754277574064858,65.8722356173568073,356.298722520573506],"luv":[37.4754277574064858,65.7348379379961614,-4.25235305377523254],"rgb":[0.6,0.2,0.333333333333333315],"xyz":[0.15959869017345979,0.0979690358551678353,0.0964516526271472],"hpluv":[356.298722520573506,223.046355214908289,37.4754277574064858],"hsluv":[356.298722520573506,66.8387430740197885,37.4754277574064858]},"#993366":{"lch":[38.0218512407041942,62.5198646461221941,344.559385799457459],"luv":[38.0218512407041942,60.2633303059628602,-16.6452544529622166],"rgb":[0.6,0.2,0.4],"xyz":[0.167183685946967975,0.101003034164571154,0.136399297034291156],"hpluv":[344.559385799457459,208.652742449272864,38.0218512407041942],"hsluv":[344.559385799457459,69.5808124884664778,38.0218512407041942]},"#993377":{"lch":[38.6780657603296234,62.1964572713534949,331.414072321130675],"luv":[38.6780657603296234,54.6147414507713478,-29.7595247504508862],"rgb":[0.6,0.2,0.466666666666666674],"xyz":[0.17649769896716988,0.104728639372651963,0.185453098940689065],"hpluv":[331.414072321130675,204.051704505442274,38.6780657603296234],"hsluv":[331.414072321130675,72.3848063102254571,38.6780657603296234]},"#993388":{"lch":[39.4428302118465908,65.3028355433768155,318.6521895607018],"luv":[39.4428302118465908,49.0236963230770257,-43.1409031990296086],"rgb":[0.6,0.2,0.533333333333333326],"xyz":[0.187638116069113736,0.109184806213429561,0.244125962344261233],"hpluv":[318.6521895607018,210.08899125401652,39.4428302118465908],"hsluv":[318.6521895607018,75.1271370389489306,39.4428302118465908]},"#993399":{"lch":[40.3131218316236897,71.3679900272828149,307.715012949243942],"luv":[40.3131218316236897,43.6582502656979656,-56.4565955781255226],"rgb":[0.6,0.2,0.6],"xyz":[0.200695080178186436,0.114407591857058719,0.31289263998537914],"hpluv":[307.715012949243942,224.64479534599792,40.3131218316236897],"hsluv":[307.715012949243942,77.7202573427554313,40.3131218316236897]},"#9933aa":{"lch":[41.2844862133256925,79.5040030135899372,299.063916375798101],"luv":[41.2844862133256925,38.6218522191785354,-69.4927264276258825],"rgb":[0.6,0.2,0.66666666666666663],"xyz":[0.215752773143439,0.120430669043159827,0.39219648960237774],"hpluv":[299.063916375798101,244.366370382710016,41.2844862133256925],"hsluv":[299.063916375798101,80.1114582016200814,41.2844862133256925]},"#9933bb":{"lch":[42.3513893410192637,88.8787943355742,292.467029257400327],"luv":[42.3513893410192637,33.9651845170614,-82.1328577566084],"rgb":[0.6,0.2,0.733333333333333282],"xyz":[0.232890365250775611,0.127285705886094586,0.482454474701019487],"hpluv":[292.467029257400327,266.299173904300574,42.3513893410192637],"hsluv":[292.467029257400327,82.2764131802073848,42.3513893410192637]},"#9933cc":{"lch":[43.5075532005759911,98.8962106119506785,287.477062230467],"luv":[43.5075532005759911,29.700902070050418,-94.3308904316533],"rgb":[0.6,0.2,0.8],"xyz":[0.252182740694497365,0.135002656063583387,0.584060985371289698],"hpluv":[287.477062230467,288.439223502221068,43.5075532005759911],"hsluv":[287.477062230467,84.2111914011780129,43.5075532005759911]},"#9933dd":{"lch":[44.7462588110156716,109.182503226938962,283.677602435208257],"luv":[44.7462588110156716,25.8171133061496079,-106.086265234656878],"rgb":[0.6,0.2,0.866666666666666696],"xyz":[0.273701066245130908,0.143609986283836921,0.697390833271295696],"hpluv":[283.677602435208257,309.624731809924413,44.7462588110156716],"hsluv":[283.677602435208257,85.9249592908513478,44.7462588110156716]},"#9933ee":{"lch":[46.0606056636097208,119.52114969179982,280.747238708189116],"luv":[46.0606056636097208,22.2879081330132465,-117.42467532296601],"rgb":[0.6,0.2,0.933333333333333348],"xyz":[0.297513246511305618,0.153134858390306938,0.822801649339818919],"hpluv":[280.747238708189116,329.271729063034456,46.0606056636097208],"hsluv":[280.747238708189116,90.0471632149093324,46.0606056636097208]},"#9933ff":{"lch":[47.4437223771408512,129.794782591236896,278.453521985212944],"luv":[47.4437223771408512,19.0807517890999456,-128.38461940228359],"rgb":[0.6,0.2,1],"xyz":[0.323684294921137039,0.163603277754239662,0.960635837631600764],"hpluv":[278.453521985212944,347.150508646733101,47.4437223771408512],"hsluv":[278.453521985212944,99.999999999999261,47.4437223771408512]},"#bb3300":{"lch":[42.6640590509798585,114.303280915030754,17.3320761189885637],"luv":[42.6640590509798585,109.113245500432,34.0520143942012652],"rgb":[0.733333333333333282,0.2,0],"xyz":[0.216768341099481898,0.129342830223910105,0.0135520370028863052],"hpluv":[17.3320761189885637,339.966286272656077,42.6640590509798585],"hsluv":[17.3320761189885637,100.000000000002302,42.6640590509798585]},"#bb3311":{"lch":[42.7251747888925806,112.6335820513806,16.4819551739351198],"luv":[42.7251747888925806,108.005370801027979,31.9556518296457135],"rgb":[0.733333333333333282,0.2,0.0666666666666666657],"xyz":[0.21778000659911903,0.129747496423764958,0.0188801419676419349],"hpluv":[16.4819551739351198,334.52099084556113,42.7251747888925806],"hsluv":[16.4819551739351198,95.1490253673008368,42.7251747888925806]},"#bb3322":{"lch":[42.8381318005571785,109.688338781622747,14.8808580240480524],"luv":[42.8381318005571785,106.009603708482885,28.1690536980292627],"rgb":[0.733333333333333282,0.2,0.133333333333333331],"xyz":[0.219655364737596032,0.130497639679155786,0.0287570281636211345],"hpluv":[14.8808580240480524,324.914627119009424,42.8381318005571785],"hsluv":[14.8808580240480524,86.4181297836030211,42.8381318005571785]},"#bb3333":{"lch":[43.023174549414108,105.246046554892928,12.1770506300618351],"luv":[43.023174549414108,102.878058957341324,22.1998941575065203],"rgb":[0.733333333333333282,0.2,0.2],"xyz":[0.222743115470053765,0.131732739972138885,0.0450191820212322777],"hpluv":[12.1770506300618351,310.414975564112126,43.023174549414108],"hsluv":[12.1770506300618351,72.7398502888125762,43.023174549414108]},"#bb3344":{"lch":[43.2883038991094082,99.6704509181560496,8.14070356751482116],"luv":[43.2883038991094082,98.6661026897846085,14.1137863891102171],"rgb":[0.733333333333333282,0.2,0.266666666666666663],"xyz":[0.227201110714272653,0.133515938069826479,0.0684979569741189231],"hpluv":[8.14070356751482116,292.169703441320848,43.2883038991094082],"hsluv":[8.14070356751482116,73.8775464962187556,43.2883038991094082]},"#bb3355":{"lch":[43.6392404977582515,93.6285749325397632,2.54995992142812078],"luv":[43.6392404977582515,93.5358645919991289,4.16558266337591299],"rgb":[0.733333333333333282,0.2,0.333333333333333315],"xyz":[0.233163524753634666,0.135900903685571312,0.0999000042480928246],"hpluv":[2.54995992142812078,272.251672456619758,43.6392404977582515],"hsluv":[2.54995992142812078,75.2585830443305781,43.6392404977582515]},"#bb3366":{"lch":[44.0797950159491521,88.0182600678664784,355.263953050872033],"luv":[44.0797950159491521,87.7177339493983794,-7.26727295188107547],"rgb":[0.733333333333333282,0.2,0.4],"xyz":[0.240748520527142823,0.138934901994974602,0.1398476486552368],"hpluv":[355.263953050872033,253.380121177946961,44.0797950159491521],"hsluv":[355.263953050872033,76.8177075569623753,44.0797950159491521]},"#bb3377":{"lch":[44.6120878205181057,83.829516929164356,346.367941021132197],"luv":[44.6120878205181057,81.4679789337245239,-19.757437005625782],"rgb":[0.733333333333333282,0.2,0.466666666666666674],"xyz":[0.250062533547344756,0.142660507203055426,0.188901450561634709],"hpluv":[346.367941021132197,238.442541154787421,44.6120878205181057],"hsluv":[346.367941021132197,78.4827471040858597,44.6120878205181057]},"#bb3388":{"lch":[45.2367248685103078,81.924239827592,336.329010851829594],"luv":[45.2367248685103078,75.03162551729379,-32.8912791414593499],"rgb":[0.733333333333333282,0.2,0.533333333333333326],"xyz":[0.261202950649288557,0.147116674043833023,0.247574313965206849],"hpluv":[336.329010851829594,229.805591899252,45.2367248685103078],"hsluv":[336.329010851829594,80.18501002925629,45.2367248685103078]},"#bb3399":{"lch":[45.9529692994627226,82.7837935230449347,325.982908927834501],"luv":[45.9529692994627226,68.6170634488305495,-46.3125800806357404],"rgb":[0.733333333333333282,0.2,0.6],"xyz":[0.274259914758361312,0.152339459687462181,0.316340991606324784],"hpluv":[325.982908927834501,228.597286714525296,45.9529692994627226],"hsluv":[325.982908927834501,81.8663863744617402,45.9529692994627226]},"#bb33aa":{"lch":[46.7589216358443664,86.3774619636168524,316.238480868355282],"luv":[46.7589216358443664,62.3839556422166126,-59.7436859735489136],"rgb":[0.733333333333333282,0.2,0.66666666666666663],"xyz":[0.289317607723613812,0.158362536873563275,0.395644841223323385],"hpluv":[316.238480868355282,234.409537876970433,46.7589216358443664],"hsluv":[316.238480868355282,83.4827024616804181,46.7589216358443664]},"#bb33bb":{"lch":[47.6517090930198108,92.2657594707273461,307.715012949243828],"luv":[47.6517090930198108,56.4421334605023191,-72.9880534138084585],"rgb":[0.733333333333333282,0.2,0.733333333333333282],"xyz":[0.306455199830950487,0.165217573716498034,0.485902826321965131],"hpluv":[307.715012949243828,245.697877980233102,47.6517090930198108],"hsluv":[307.715012949243828,85.0039827354176,47.6517090930198108]},"#bb33cc":{"lch":[48.6276786348411179,99.8443429984049402,300.621719827817344],"luv":[48.6276786348411179,50.8574804969275078,-85.9209491700817551],"rgb":[0.733333333333333282,0.2,0.8],"xyz":[0.325747575274672241,0.172934523893986836,0.587509336992235287],"hpluv":[300.621719827817344,260.542905615006589,48.6276786348411179],"hsluv":[300.621719827817344,86.4127454729900535,48.6276786348411179]},"#bb33dd":{"lch":[49.6825862492002273,108.545865187730342,294.87630802524211],"luv":[49.6825862492002273,45.6609809337446322,-98.4747666639588459],"rgb":[0.733333333333333282,0.2,0.866666666666666696],"xyz":[0.347265900825305729,0.18154185411424037,0.700839184892241285],"hpluv":[294.87630802524211,277.235228758227834,49.6825862492002273],"hsluv":[294.87630802524211,87.70141038259,49.6825862492002273]},"#bb33ee":{"lch":[50.8117750205940695,117.927813495206621,290.271422146528892],"luv":[50.8117750205940695,40.8581913283156268,-110.623584271795281],"rgb":[0.733333333333333282,0.2,0.933333333333333348],"xyz":[0.371078081091480494,0.191066726220710414,0.826250000960764508],"hpluv":[290.271422146528892,294.504005794210514,50.8117750205940695],"hsluv":[290.271422146528892,88.8695912604113687,50.8117750205940695]},"#bb33ff":{"lch":[52.0103359867018611,127.679308171663493,286.581788346289272],"luv":[52.0103359867018611,36.4375993761859931,-122.36955130625914],"rgb":[0.733333333333333282,0.2,1],"xyz":[0.39724912950131186,0.201535145584643111,0.964084189252546353],"hpluv":[286.581788346289272,311.508705442628695,52.0103359867018611],"hsluv":[286.581788346289272,99.9999999999991616,52.0103359867018611]},"#994400":{"lch":[39.4244247356725168,77.6708634712958315,27.0445710144404678],"luv":[39.4244247356725168,69.1777945884316097,35.3156589667733627],"rgb":[0.6,0.266666666666666663,0],"xyz":[0.152036077002273062,0.109076103359438958,0.0130478755429292749],"hpluv":[27.0445710144404678,249.995444431237956,39.4244247356725168],"hsluv":[27.0445710144404678,100.000000000002302,39.4244247356725168]},"#994411":{"lch":[39.4928806474909351,75.8240556098730849,25.7566327743493559],"luv":[39.4928806474909351,68.2907795083206395,32.9493071744317447],"rgb":[0.6,0.266666666666666663,0.0666666666666666657],"xyz":[0.153047742501910194,0.109480769559293811,0.0183759805076849081],"hpluv":[25.7566327743493559,243.628181561178451,39.4928806474909351],"hsluv":[25.7566327743493559,94.1783894720599,39.4928806474909351]},"#994422":{"lch":[39.6193348047394807,72.6128884539244268,23.2788782073808527],"luv":[39.6193348047394807,66.7016282141236161,28.6971141964989123],"rgb":[0.6,0.266666666666666663,0.133333333333333331],"xyz":[0.154923100640387196,0.110230912814684626,0.0282528667036641],"hpluv":[23.2788782073808527,232.565805292122405,39.6193348047394807],"hsluv":[23.2788782073808527,83.7619004180350402,39.6193348047394807]},"#994433":{"lch":[39.8262957210095,67.9099451463512764,18.9473520481579776],"luv":[39.8262957210095,64.2304033034813671,22.0503047882012062],"rgb":[0.6,0.266666666666666663,0.2],"xyz":[0.158010851372844929,0.111466013107667739,0.0445150205612752509],"hpluv":[18.9473520481579776,216.372863201479333,39.8262957210095],"hsluv":[18.9473520481579776,67.5996848307310358,39.8262957210095]},"#994444":{"lch":[40.1224193460439267,62.3513134554678956,12.1770506300619097],"luv":[40.1224193460439267,60.9484376060972082,13.1519672672071142],"rgb":[0.6,0.266666666666666663,0.266666666666666663],"xyz":[0.162468846617063817,0.113249211205355318,0.0679937955141618894],"hpluv":[12.1770506300619097,197.195872414250289,40.1224193460439267],"hsluv":[12.1770506300619097,46.2091051210312429,40.1224193460439267]},"#994455":{"lch":[40.5136546800823041,57.0624194645929776,2.37288379618767387],"luv":[40.5136546800823041,57.0134905267935324,2.36254377830001205],"rgb":[0.6,0.266666666666666663,0.333333333333333315],"xyz":[0.16843126065642583,0.115634176821100151,0.0993958427881357909],"hpluv":[2.37288379618767387,178.726144329621945,40.5136546800823041],"hsluv":[2.37288379618767387,49.5312591923758063,40.5136546800823041]},"#994466":{"lch":[41.0036603670202382,53.5416261730848646,349.413399835018254],"luv":[41.0036603670202382,52.6302589877717111,-9.83674601372026558],"rgb":[0.6,0.266666666666666663,0.4],"xyz":[0.176016256429934,0.11866817513050347,0.139343487195279753],"hpluv":[349.413399835018254,165.694562401887765,41.0036603670202382],"hsluv":[349.413399835018254,53.2076295784804643,41.0036603670202382]},"#994477":{"lch":[41.594070304433572,53.2098960104776424,334.460192523955527],"luv":[41.594070304433572,48.0105420863306946,-22.9408125841809181],"rgb":[0.6,0.266666666666666663,0.466666666666666674],"xyz":[0.18533026945013592,0.122393780338584279,0.188397289101677662],"hpluv":[334.460192523955527,162.330570569563577,41.594070304433572],"hsluv":[334.460192523955527,57.0495308436177666,41.594070304433572]},"#994488":{"lch":[42.2847251453823887,56.6612659292255287,319.901700116735],"luv":[42.2847251453823887,43.3424978513170416,-36.4955742071691631],"rgb":[0.6,0.266666666666666663,0.533333333333333326],"xyz":[0.196470686552079721,0.126849947179361877,0.247070152505249829],"hpluv":[319.901700116735,170.036472949794188,42.2847251453823887],"hsluv":[319.901700116735,60.8903164523640683,42.2847251453823887]},"#994499":{"lch":[43.0739091348830314,63.3829857303906,307.715012949244226],"luv":[43.0739091348830314,38.7735489334465555,-50.1399519665159232],"rgb":[0.6,0.266666666666666663,0.6],"xyz":[0.209527650661152448,0.132072732822991035,0.315836830146367764],"hpluv":[307.715012949244226,186.722963823125951,43.0739091348830314],"hsluv":[307.715012949244226,64.600458594127474,43.0739091348830314]},"#9944aa":{"lch":[43.9586008361636686,72.3252063731545,298.405725418599673],"luv":[43.9586008361636686,34.4059763632637896,-63.6173267861038099],"rgb":[0.6,0.266666666666666663,0.66666666666666663],"xyz":[0.224585343626404976,0.138095810009092129,0.395140679763366365],"hpluv":[298.405725418599673,208.77819920337123,43.9586008361636686],"hsluv":[298.405725418599673,68.0913106207235,43.9586008361636686]},"#9944bb":{"lch":[44.9347323991438827,82.5300732915554676,291.540124858279853],"luv":[44.9347323991438827,30.3011407548278626,-76.7662286846607316],"rgb":[0.6,0.266666666666666663,0.733333333333333282],"xyz":[0.241722935733741651,0.144950846852026888,0.485398664862008111],"hpluv":[291.540124858279853,233.060888419388505,44.9347323991438827],"hsluv":[291.540124858279853,71.3111773355981882,44.9347323991438827]},"#9944cc":{"lch":[45.9974464532923903,93.3382836250318206,286.486143775676851],"luv":[45.9974464532923903,26.4878609436744341,-89.5009967134190561],"rgb":[0.6,0.266666666666666663,0.8],"xyz":[0.261015311177463349,0.152667797029515689,0.587005175532278267],"hpluv":[286.486143775676851,257.492992496327645,45.9974464532923903],"hsluv":[286.486143775676851,74.2376853125076792,45.9974464532923903]},"#9944dd":{"lch":[47.1413389271288139,104.350309752399141,282.717215233582351],"luv":[47.1413389271288139,22.9716047676972792,-101.790434323753402],"rgb":[0.6,0.266666666666666663,0.866666666666666696],"xyz":[0.282533636728096949,0.161275127249769223,0.700335023432284265],"hpluv":[282.717215233582351,280.886686990529654,47.1413389271288139],"hsluv":[282.717215233582351,78.691216526215527,47.1413389271288139]},"#9944ee":{"lch":[48.3606780479664593,115.341161543855208,279.855683836472622],"luv":[48.3606780479664593,19.7426125181249787,-113.638958096441911],"rgb":[0.6,0.266666666666666663,0.933333333333333348],"xyz":[0.306345816994271658,0.170799999356239268,0.825745839500807488],"hpluv":[279.855683836472622,302.643440789384783,48.3606780479664593],"hsluv":[279.855683836472622,89.2619995530309325,48.3606780479664593]},"#9944ff":{"lch":[49.6495929972458185,126.19285787586071,277.642335930208503],"luv":[49.6495929972458185,16.7822322716138856,-125.071955525044785],"rgb":[0.6,0.266666666666666663,1],"xyz":[0.332516865404103079,0.181268418720171964,0.963580027792589333],"hpluv":[277.642335930208503,322.521305960549284,49.6495929972458185],"hsluv":[277.642335930208503,99.9999999999991616,49.6495929972458185]},"#bb4400":{"lch":[45.2216387767487547,104.837609625168909,21.4216552556228201],"luv":[45.2216387767487547,97.5952013308911,38.2896992558330354],"rgb":[0.733333333333333282,0.266666666666666663,0],"xyz":[0.225600911582447911,0.147007971189842435,0.0164962271638749],"hpluv":[21.4216552556228201,294.177965476355098,45.2216387767487547],"hsluv":[21.4216552556228201,100.000000000002373,45.2216387767487547]},"#bb4411":{"lch":[45.2777618800582076,103.283777149094803,20.576768268141489],"luv":[45.2777618800582076,96.6944911384892123,36.3003306548646947],"rgb":[0.733333333333333282,0.266666666666666663,0.0666666666666666657],"xyz":[0.226612577082085043,0.147412637389697287,0.0218243321286305317],"hpluv":[20.576768268141489,289.458620037032802,45.2777618800582076],"hsluv":[20.576768268141489,95.6967439910137614,45.2777618800582076]},"#bb4422":{"lch":[45.3815280810129238,100.53232916519147,18.9799525675269258],"luv":[45.3815280810129238,95.0666309197234,32.6968636561903381],"rgb":[0.733333333333333282,0.266666666666666663,0.133333333333333331],"xyz":[0.228487935220562044,0.148162780645088116,0.0317012183246097243],"hpluv":[18.9799525675269258,281.103307599105051,45.3815280810129238],"hsluv":[18.9799525675269258,87.925891065222288,45.3815280810129238]},"#bb4433":{"lch":[45.5516172521931111,96.3559005693685862,16.2666991179303722],"luv":[45.5516172521931111,92.4986058403436147,26.9901369416087924],"rgb":[0.733333333333333282,0.266666666666666663,0.2],"xyz":[0.231575685953019805,0.149397880938071215,0.0479633721822208675],"hpluv":[16.2666991179303722,268.419362556396,45.5516172521931111],"hsluv":[16.2666991179303722,75.6846484949249572,45.5516172521931111]},"#bb4444":{"lch":[45.7955406359936816,91.066890863790789,12.177050630061844],"luv":[45.7955406359936816,89.0179277419259734,19.2090382927107299],"rgb":[0.733333333333333282,0.266666666666666663,0.266666666666666663],"xyz":[0.236033681197238665,0.151181079035758809,0.0714421471351075],"hpluv":[12.177050630061844,252.334507458167678,45.7955406359936816],"hsluv":[12.177050630061844,59.1297963696904461,45.7955406359936816]},"#bb4455":{"lch":[46.1187996938414813,85.2741675307746,6.43569277192082279],"luv":[46.1187996938414813,84.7367941199702273,9.55820957796975],"rgb":[0.733333333333333282,0.266666666666666663,0.333333333333333315],"xyz":[0.24199609523660065,0.153566044651503641,0.102844194409081421],"hpluv":[6.43569277192082279,234.627449284537505,46.1187996938414813],"hsluv":[6.43569277192082279,61.0765315010866274,46.1187996938414813]},"#bb4466":{"lch":[46.5252276318027427,79.8426568240615637,358.82639812637143],"luv":[46.5252276318027427,79.8259079304732779,-1.63532009113408461],"rgb":[0.733333333333333282,0.266666666666666663,0.4],"xyz":[0.249581091010108835,0.156600042960906932,0.142791838816225369],"hpluv":[358.82639812637143,217.763856882437722,46.5252276318027427],"hsluv":[358.82639812637143,63.3003300169989842,46.5252276318027427]},"#bb4477":{"lch":[47.0171837667790697,75.785442181693,349.367581794189107],"luv":[47.0171837667790697,74.484290362097866,-13.9829802234512588],"rgb":[0.733333333333333282,0.266666666666666663,0.466666666666666674],"xyz":[0.258895104030310741,0.160325648168987756,0.191845640722623278],"hpluv":[349.367581794189107,204.535408840651428,47.0171837667790697],"hsluv":[349.367581794189107,65.7062458495858266,47.0171837667790697]},"#bb4488":{"lch":[47.5956997014540235,74.0450948660102,338.538246495536782],"luv":[47.5956997014540235,68.9109568360576219,-27.0916241974425098],"rgb":[0.733333333333333282,0.266666666666666663,0.533333333333333326],"xyz":[0.270035521132254597,0.164781815009765353,0.250518504126195474],"hpluv":[338.538246495536782,197.409434601059019,47.5956997014540235],"hsluv":[338.538246495536782,68.1997676790361,47.5956997014540235]},"#bb4499":{"lch":[48.2606154557730633,75.1911240047971,327.313188255720945],"luv":[48.2606154557730633,63.2834900243205496,-40.6067115074158309],"rgb":[0.733333333333333282,0.266666666666666663,0.6],"xyz":[0.283092485241327296,0.170004600653394511,0.319285181767313353],"hpluv":[327.313188255720945,197.702903480158483,48.2606154557730633],"hsluv":[327.313188255720945,70.6969578310621074,48.2606154557730633]},"#bb44aa":{"lch":[49.0107199856960278,79.2228796099941093,316.794363507436401],"luv":[49.0107199856960278,57.7456584584256944,-54.2374739723603838],"rgb":[0.733333333333333282,0.266666666666666663,0.66666666666666663],"xyz":[0.298150178206579852,0.176027677839495605,0.398589031384311954],"hpluv":[316.794363507436401,205.115683333718124,49.0107199856960278],"hsluv":[316.794363507436401,73.1302855273877128,49.0107199856960278]},"#bb44bb":{"lch":[49.8438993628519427,85.6636869410227746,307.715012949243942],"luv":[49.8438993628519427,52.4034189799077268,-67.7653963284049752],"rgb":[0.733333333333333282,0.266666666666666663,0.733333333333333282],"xyz":[0.315287770313916471,0.182882714682430364,0.4888470164829537],"hpluv":[307.715012949243942,218.084137693810391,49.8438993628519427],"hsluv":[307.715012949243942,75.450469608388417,49.8438993628519427]},"#bb44cc":{"lch":[50.757290285110841,93.8478600934752905,300.284565440631638],"luv":[50.757290285110841,47.3270085455435918,-81.0405769121528152],"rgb":[0.733333333333333282,0.266666666666666663,0.8],"xyz":[0.334580145757638225,0.190599664859919166,0.590453527153223856],"hpluv":[300.284565440631638,234.620130462749955,50.757290285110841],"hsluv":[300.284565440631638,77.6254237907312898,50.757290285110841]},"#bb44dd":{"lch":[51.7474340276366291,103.158361374368454,294.364201848969515],"luv":[51.7474340276366291,42.5564715489483518,-93.971241615445],"rgb":[0.733333333333333282,0.266666666666666663,0.866666666666666696],"xyz":[0.356098471308271769,0.1992069950801727,0.703783375053229854],"hpluv":[294.364201848969515,252.961799427415912,51.7474340276366291],"hsluv":[294.364201848969515,79.6375689955678467,51.7474340276366291]},"#bb44ee":{"lch":[52.8104252671910217,113.122924260907325,289.686672533024307],"luv":[52.8104252671910217,38.1084271425454304,-106.510768347901248],"rgb":[0.733333333333333282,0.266666666666666663,0.933333333333333348],"xyz":[0.379910651574446478,0.208731867186642744,0.829194191121753077],"hpluv":[289.686672533024307,271.813038246621943,52.8104252671910217],"hsluv":[289.686672533024307,87.7449679178180872,52.8104252671910217]},"#bb44ff":{"lch":[53.942050711908152,123.415863319803691,285.982908620336502],"luv":[53.942050711908152,33.9826318144238115,-118.645084406973112],"rgb":[0.733333333333333282,0.266666666666666663,1],"xyz":[0.4060816999842779,0.219200286550575441,0.967028379413534922],"hpluv":[285.982908620336502,290.323946696930363,53.942050711908152],"hsluv":[285.982908620336502,99.9999999999990621,53.942050711908152]},"#995500":{"lch":[43.167672396478018,69.2675138179999,36.3951762413548678],"luv":[43.167672396478018,55.7564526526882105,41.099956911356287],"rgb":[0.6,0.333333333333333315,0],"xyz":[0.163849333716619028,0.132702616788131222,0.0169856277810444857],"hpluv":[36.3951762413548678,203.615246511519132,43.167672396478018],"hsluv":[36.3951762413548678,100.000000000002288,43.167672396478018]},"#995511":{"lch":[43.2277537555276865,67.4837391190291385,35.2266717066771307],"luv":[43.2277537555276865,55.1258789529511333,38.9254738590266101],"rgb":[0.6,0.333333333333333315,0.0666666666666666657],"xyz":[0.16486099921625616,0.133107282987986075,0.0223137327458001189],"hpluv":[35.2266717066771307,198.096040704981476,43.2277537555276865],"hsluv":[35.2266717066771307,95.1659583326808303,43.2277537555276865]},"#995522":{"lch":[43.3388072781739,64.3407602415628475,32.9528815923873708],"luv":[43.3388072781739,53.9895016234129059,34.998101990218963],"rgb":[0.6,0.333333333333333315,0.133333333333333331],"xyz":[0.166736357354733161,0.133857426243376904,0.0321906189417793115],"hpluv":[32.9528815923873708,188.385971738918272,43.3388072781739],"hsluv":[32.9528815923873708,86.4646465379692302,43.3388072781739]},"#995533":{"lch":[43.5207548807750584,59.6262244551406582,28.8908620435756234],"luv":[43.5207548807750584,52.2052395636471,28.8079781462883915],"rgb":[0.6,0.333333333333333315,0.2],"xyz":[0.169824108087190895,0.13509252653636,0.0484527727993904617],"hpluv":[28.8908620435756234,173.852210644027934,43.5207548807750584],"hsluv":[28.8908620435756234,72.8304069554253601,43.5207548807750584]},"#995544":{"lch":[43.7814988718974831,53.8284560366537335,22.2989672577237812],"luv":[43.7814988718974831,49.8029788080235036,20.4246415179685634],"rgb":[0.6,0.333333333333333315,0.266666666666666663],"xyz":[0.174282103331409782,0.136875724634047596,0.0719315477522771],"hpluv":[22.2989672577237812,156.01294104827457,43.7814988718974831],"hsluv":[22.2989672577237812,54.5318604429391058,43.7814988718974831]},"#995555":{"lch":[44.1267187000120629,47.9518139182857226,12.1770506300620411],"luv":[44.1267187000120629,46.8729201797035,10.1146335514957979],"rgb":[0.6,0.333333333333333315,0.333333333333333315],"xyz":[0.180244517370771795,0.139260690249792429,0.103333595026251],"hpluv":[12.1770506300620411,137.893162706519348,44.1267187000120629],"hsluv":[12.1770506300620411,32.3126421104369754,44.1267187000120629]},"#995566":{"lch":[44.5602350881765048,43.578232165907,357.727809148728397],"luv":[44.5602350881765048,43.5439690351937116,-1.72773822316436432],"rgb":[0.6,0.333333333333333315,0.4],"xyz":[0.187829513144279953,0.14229468855919572,0.143281239433394963],"hpluv":[357.727809148728397,124.097051059849122,44.5602350881765048],"hsluv":[357.727809148728397,36.5660257696708157,44.5602350881765048]},"#995577":{"lch":[45.0842241078155226,42.5628566452735342,339.858530865537546],"luv":[45.0842241078155226,39.9599368331855729,-14.6560640723873874],"rgb":[0.6,0.333333333333333315,0.466666666666666674],"xyz":[0.197143526164481886,0.146020293767276543,0.192335041339792873],"hpluv":[339.858530865537546,119.796876557388956,45.0842241078155226],"hsluv":[339.858530865537546,41.1101378179314167,45.0842241078155226]},"#995588":{"lch":[45.699386409692309,45.957423726275,322.088602167082399],"luv":[45.699386409692309,36.2586549471185506,-28.2381787122006145],"rgb":[0.6,0.333333333333333315,0.533333333333333326],"xyz":[0.208283943266425686,0.150476460608054141,0.25100790474336504],"hpluv":[322.088602167082399,127.609977655436467,45.699386409692309],"hsluv":[322.088602167082399,45.7577454208568852,45.699386409692309]},"#995599":{"lch":[46.4051108942887964,53.2218555896971921,307.715012949244795],"luv":[46.4051108942887964,32.5576366947089113,-42.1018551285561102],"rgb":[0.6,0.333333333333333315,0.6],"xyz":[0.221340907375498414,0.155699246251683299,0.319774582384483],"hpluv":[307.715012949244795,145.533684272522947,46.4051108942887964],"hsluv":[307.715012949244795,50.3502223422482516,46.4051108942887964]},"#9955aa":{"lch":[47.1996461355186625,63.0010233462712037,297.353030705211779],"luv":[47.1996461355186625,28.9471952899390068,-55.9570266143899246],"rgb":[0.6,0.333333333333333315,0.66666666666666663],"xyz":[0.236398600340750942,0.161722323437784393,0.399078432001481576],"hpluv":[297.353030705211779,169.374563019623821,47.1996461355186625],"hsluv":[297.353030705211779,54.7667714505238337,47.1996461355186625]},"#9955bb":{"lch":[48.0802807126223541,74.1194144420538,290.114722102094788],"luv":[48.0802807126223541,25.4897394646759068,-69.5985688017783701],"rgb":[0.6,0.333333333333333315,0.733333333333333282],"xyz":[0.253536192448087616,0.168577360280719152,0.489336417100123322],"hpluv":[290.114722102094788,195.615971831826613,48.0802807126223541],"hsluv":[290.114722102094788,58.9252289891592866,48.0802807126223541]},"#9955cc":{"lch":[49.0435277691913,85.8237639836856658,285.007043429489613],"luv":[49.0435277691913,22.2230153813451068,-82.8966588692685491],"rgb":[0.6,0.333333333333333315,0.8],"xyz":[0.272828567891809315,0.176294310458207953,0.590942927770393478],"hpluv":[285.007043429489613,222.057364979540267,49.0435277691913],"hsluv":[285.007043429489613,65.256702758776143,49.0435277691913]},"#9955dd":{"lch":[50.0853068419578875,97.6800340866365104,281.315028513382344],"luv":[50.0853068419578875,19.1651498984824649,-95.7814496055220843],"rgb":[0.6,0.333333333333333315,0.866666666666666696],"xyz":[0.294346893442442914,0.184901640678461487,0.704272775670399476],"hpluv":[281.315028513382344,247.476970093373268,50.0853068419578875],"hsluv":[281.315028513382344,76.6956878028438638,50.0853068419578875]},"#9955ee":{"lch":[51.2011159126469266,109.450459224116145,278.575243894560685],"luv":[51.2011159126469266,16.3199513369978568,-108.226901520499666],"rgb":[0.6,0.333333333333333315,0.933333333333333348],"xyz":[0.318159073708617623,0.194426512784931532,0.829683591738922699],"hpluv":[278.575243894560685,271.254835109068836,51.2011159126469266],"hsluv":[278.575243894560685,88.2491190723243335,51.2011159126469266]},"#9955ff":{"lch":[52.3861878346365444,121.012399839465246,276.491711029928183],"luv":[52.3861878346365444,13.6815981187824764,-120.2364952409323],"rgb":[0.6,0.333333333333333315,1],"xyz":[0.344330122118449045,0.204894932148864228,0.967517780030704544],"hpluv":[276.491711029928183,293.124692446110771,52.3861878346365444],"hsluv":[276.491711029928183,99.9999999999991,52.3861878346365444]},"#bb5500":{"lch":[48.3398816318057811,94.9450628471467724,27.1627331553413143],"luv":[48.3398816318057811,84.4739036935134,43.344256295703957],"rgb":[0.733333333333333282,0.333333333333333315,0],"xyz":[0.237414168296793876,0.170634484618534699,0.0204339794019901093],"hpluv":[27.1627331553413143,249.233335779464397,48.3398816318057811],"hsluv":[27.1627331553413143,100.000000000002217,48.3398816318057811]},"#bb5511":{"lch":[48.3907029738951735,93.4795954244126364,26.3417432533787057],"luv":[48.3907029738951735,83.7729911103365907,41.4791600823755289],"rgb":[0.733333333333333282,0.333333333333333315,0.0666666666666666657],"xyz":[0.238425833796431,0.171039150818389551,0.0257620843667457425],"hpluv":[26.3417432533787057,245.128732426237889,48.3907029738951735],"hsluv":[26.3417432533787057,96.2613278044251786,48.3907029738951735]},"#bb5522":{"lch":[48.4847005727335869,90.8707197847641623,24.7826102649670759],"luv":[48.4847005727335869,82.5019575685759321,38.090874386840035],"rgb":[0.733333333333333282,0.333333333333333315,0.133333333333333331],"xyz":[0.240301191934908,0.17178929407378038,0.0356389705627249351],"hpluv":[24.7826102649670759,237.825586669453713,48.4847005727335869],"hsluv":[24.7826102649670759,89.48684037186257,48.4847005727335869]},"#bb5533":{"lch":[48.6388719159228629,86.8743588299812473,22.1104535643633149],"luv":[48.6388719159228629,80.4856161939384407,32.6989267102511363],"rgb":[0.733333333333333282,0.333333333333333315,0.2],"xyz":[0.243388942667365771,0.173024394366763479,0.0519011244203360783],"hpluv":[22.1104535643633149,226.64567974804504,48.6388719159228629],"hsluv":[22.1104535643633149,78.7542493880857393,48.6388719159228629]},"#bb5544":{"lch":[48.8601705631915,81.7431600256382751,18.0266646696809296],"luv":[48.8601705631915,77.730600917119915,25.2962031151029265],"rgb":[0.733333333333333282,0.333333333333333315,0.266666666666666663],"xyz":[0.24784693791158463,0.174807592464451073,0.0753798993732227168],"hpluv":[18.0266646696809296,212.293047020031764,48.8601705631915],"hsluv":[18.0266646696809296,64.1199207289341,48.8601705631915]},"#bb5555":{"lch":[49.1538097277392154,76.0172073873862075,12.1770506300619399],"luv":[49.1538097277392154,74.3068552156307,16.0345591439297159],"rgb":[0.733333333333333282,0.333333333333333315,0.333333333333333315],"xyz":[0.253809351950946616,0.177192558080195905,0.106781946647196632],"hpluv":[12.1770506300619399,196.242945408672853,49.1538097277392154],"hsluv":[12.1770506300619399,45.9858047870319879,49.1538097277392154]},"#bb5566":{"lch":[49.523574907380123,70.5220596563995,4.21567942747197],"luv":[49.523574907380123,70.3312550088346882,5.18415538569556134],"rgb":[0.733333333333333282,0.333333333333333315,0.4],"xyz":[0.261394347724454801,0.180226556389599196,0.14672959105434058],"hpluv":[4.21567942747197,180.697576197923894,49.523574907380123],"hsluv":[4.21567942747197,48.7291682320237527,49.523574907380123]},"#bb5577":{"lch":[49.971995559373525,66.3094111666939341,354.014227306533371],"luv":[49.971995559373525,65.9478803557508257,-6.91484532417379327],"rgb":[0.733333333333333282,0.333333333333333315,0.466666666666666674],"xyz":[0.270708360744656706,0.18395216159768002,0.195783392960738489],"hpluv":[354.014227306533371,168.378953180241098,49.971995559373525],"hsluv":[354.014227306533371,51.7390719561838495,49.971995559373525]},"#bb5588":{"lch":[50.5004659153875508,64.4571905510646275,342.016521446261379],"luv":[50.5004659153875508,61.308172080607541,-19.9006896832966476],"rgb":[0.733333333333333282,0.333333333333333315,0.533333333333333326],"xyz":[0.281848777846600562,0.188408328438457617,0.254456256364310685],"hpluv":[342.016521446261379,161.962814057843559,50.5004659153875508],"hsluv":[342.016521446261379,54.9055054808170055,50.5004659153875508]},"#bb5599":{"lch":[51.1093507584050286,65.6961991151429459,329.411862939203161],"luv":[51.1093507584050286,56.5544024759803,-33.4303774845774342],"rgb":[0.733333333333333282,0.333333333333333315,0.6],"xyz":[0.294905741955673262,0.193631114082086775,0.323222934005428564],"hpluv":[329.411862939203161,163.109481188372769,51.1093507584050286],"hsluv":[329.411862939203161,58.1255686218068561,51.1093507584050286]},"#bb55aa":{"lch":[51.7980911374347386,70.0901192661774246,317.660759061539352],"luv":[51.7980911374347386,51.8085124997667563,-47.2070212077450151],"rgb":[0.733333333333333282,0.333333333333333315,0.66666666666666663],"xyz":[0.309963434920925818,0.199654191268187869,0.402526783622427164],"hpluv":[317.660759061539352,171.704773930815691,51.7980911374347386],"hsluv":[317.660759061539352,61.3115173935257403,51.7980911374347386]},"#bb55bb":{"lch":[52.5653152299933737,77.1031380177621344,307.715012949244226],"luv":[52.5653152299933737,47.1666372355911179,-60.9934605025180332],"rgb":[0.733333333333333282,0.333333333333333315,0.733333333333333282],"xyz":[0.327101027028262437,0.206509228111122628,0.492784768721068911],"hpluv":[307.715012949244226,186.128169856082764,52.5653152299933737],"hsluv":[307.715012949244226,64.3946779967479,52.5653152299933737]},"#bb55cc":{"lch":[53.4089544864585,85.9678373228364308,299.780474196008072],"luv":[53.4089544864585,42.6983512805399883,-74.6144748148057175],"rgb":[0.733333333333333282,0.333333333333333315,0.8],"xyz":[0.346393402471984191,0.21422617828861143,0.594391279391339067],"hpluv":[299.780474196008072,204.249617293250537,53.4089544864585],"hsluv":[299.780474196008072,67.3259326792693855,53.4089544864585]},"#bb55dd":{"lch":[54.3263625650166944,95.9883710948233926,293.613183872979789],"luv":[54.3263625650166944,38.4490902963257213,-87.9513208588848698],"rgb":[0.733333333333333282,0.333333333333333315,0.866666666666666696],"xyz":[0.367911728022617734,0.222833508508864964,0.707721127291345065],"hpluv":[293.613183872979789,224.206046477737118,54.3263625650166944],"hsluv":[293.613183872979789,73.8407928406032283,54.3263625650166944]},"#bb55ee":{"lch":[55.314433433552054,106.647677925948784,288.842761327535072],"luv":[55.314433433552054,34.444226028074695,-100.932266893812525],"rgb":[0.733333333333333282,0.333333333333333315,0.933333333333333348],"xyz":[0.391723908288792444,0.232358380615335,0.833131943359868288],"hpluv":[288.842761327535072,244.653966901481454,55.314433433552054],"hsluv":[288.842761327535072,86.7715876359309135,55.314433433552054]},"#bb55ff":{"lch":[56.3697148536960526,117.598184211748716,285.129655441003138],"luv":[56.3697148536960526,30.6936185759692179,-113.521956944959783],"rgb":[0.733333333333333282,0.333333333333333315,1],"xyz":[0.417894956698623865,0.242826799979267705,0.970966131651650133],"hpluv":[285.129655441003138,264.724480425834031,56.3697148536960526],"hsluv":[285.129655441003138,99.9999999999989,56.3697148536960526]},"#996600":{"lch":[47.3343652017352454,63.4240894393546952,48.3260196362919672],"luv":[47.3343652017352454,42.1701199842588,47.3740023823666476],"rgb":[0.6,0.4,0],"xyz":[0.178877391422465504,0.162758732199824563,0.0219949803496598331],"hpluv":[48.3260196362919672,170.026654750900292,47.3343652017352454],"hsluv":[48.3260196362919672,100.000000000002288,47.3343652017352454]},"#996611":{"lch":[47.3868110627231189,61.667674323653,47.4017350737566616],"luv":[47.3868110627231189,41.7399921999205,45.3946594616449133],"rgb":[0.6,0.4,0.0666666666666666657],"xyz":[0.179889056922102636,0.163163398399679416,0.0273230853144154628],"hpluv":[47.4017350737566616,165.135107398016657,47.3868110627231189],"hsluv":[47.4017350737566616,96.0239926064661,47.3868110627231189]},"#996622":{"lch":[47.4838028017404099,58.5263777304533406,45.5834379771503322],"luv":[47.4838028017404099,40.9608465044279413,41.8036594557031336],"rgb":[0.6,0.4,0.133333333333333331],"xyz":[0.181764415060579637,0.163913541655070244,0.0371999715103946624],"hpluv":[45.5834379771503322,156.40314428015364,47.4838028017404099],"hsluv":[45.5834379771503322,88.8298219708016177,47.4838028017404099]},"#996633":{"lch":[47.642855645786625,53.6803525088045674,42.2629253198225712],"luv":[47.642855645786625,39.7270268335614887,36.1018501525199724],"rgb":[0.6,0.4,0.2],"xyz":[0.184852165793037371,0.165148641948053343,0.0534621253680058056],"hpluv":[42.2629253198225712,142.973945144987511,47.642855645786625],"hsluv":[42.2629253198225712,77.4596172761956865,47.642855645786625]},"#996644":{"lch":[47.8710980897590872,47.4159845831850149,36.6424092143452071],"luv":[47.8710980897590872,38.045445264132745,28.298757722676072],"rgb":[0.6,0.4,0.266666666666666663],"xyz":[0.189310161037256258,0.166931840045740937,0.0769409003208924441],"hpluv":[36.6424092143452071,125.687101185572914,47.8710980897590872],"hsluv":[36.6424092143452071,62.0095295256686185,47.8710980897590872]},"#996655":{"lch":[48.173837669734425,40.4765536471140521,27.3183313201514686],"luv":[48.173837669734425,35.9622216701857838,18.5760600691352664],"rgb":[0.6,0.4,0.333333333333333315],"xyz":[0.195272575076618271,0.16931680566148577,0.108342947594866346],"hpluv":[27.3183313201514686,106.618264590322553,48.173837669734425],"hsluv":[27.3183313201514686,42.9499413016611484,48.173837669734425]},"#996666":{"lch":[48.5548823199147819,34.3240193245421,12.1770506300621335],"luv":[48.5548823199147819,33.551744690774747,7.24007809326721219],"rgb":[0.6,0.4,0.4],"xyz":[0.202857570850126429,0.17235080397088906,0.148290592002010307],"hpluv":[12.1770506300621335,89.702502372613651,48.5548823199147819],"hsluv":[12.1770506300621335,21.0200766933302461,48.5548823199147819]},"#996677":{"lch":[49.0167186013709,31.3606600839303482,350.2076113500313],"luv":[49.0167186013709,30.9037509766054157,-5.33377694282222681],"rgb":[0.6,0.4,0.466666666666666674],"xyz":[0.212171583870328362,0.176076409178969884,0.197344393908408217],"hpluv":[350.2076113500313,81.185839798992177,49.0167186013709],"hsluv":[350.2076113500313,25.8881256225468483,49.0167186013709]},"#996688":{"lch":[49.5606396668562752,33.7929953796712823,326.289263208678278],"luv":[49.5606396668562752,28.1107077320421368,-18.7551232343109682],"rgb":[0.6,0.4,0.533333333333333326],"xyz":[0.223312000972272162,0.180532576019747482,0.256017257311980384],"hpluv":[326.289263208678278,86.5225105267045365,49.5606396668562752],"hsluv":[326.289263208678278,30.9767265160446463,49.5606396668562752]},"#996699":{"lch":[50.1868595811773304,41.2886932006772,307.715012949245818],"luv":[50.1868595811773304,25.2577114783499113,-32.6619686653465351],"rgb":[0.6,0.4,0.6],"xyz":[0.236368965081344889,0.185755361663376639,0.324783934953098319],"hpluv":[307.715012949245818,104.395179003902854,50.1868595811773304],"hsluv":[307.715012949245818,36.1175524455388413,50.1868595811773304]},"#9966aa":{"lch":[50.8946289106688141,51.8448774557822,295.617938374847199],"luv":[50.8946289106688141,22.4160699516755599,-46.7483810021979451],"rgb":[0.6,0.4,0.66666666666666663],"xyz":[0.251426658046597418,0.191778438849477734,0.40408778457009692],"hpluv":[295.617938374847199,129.262701065701,50.8946289106688141],"hsluv":[295.617938374847199,41.1705422178494445,50.8946289106688141]},"#9966bb":{"lch":[51.6823563026294,63.8712345518136,287.908782454232437],"luv":[51.6823563026294,19.6405628457828776,-60.776499523036378],"rgb":[0.6,0.4,0.733333333333333282],"xyz":[0.268564250153934092,0.198633475692412492,0.494345769668738666],"hpluv":[287.908782454232437,156.820318415219759,51.6823563026294],"hsluv":[287.908782454232437,49.349420166275209,51.6823563026294]},"#9966cc":{"lch":[52.5477355185796569,76.4825896496335389,282.819195018988751],"luv":[52.5477355185796569,16.9695880464031816,-74.5762670093482285],"rgb":[0.6,0.4,0.8],"xyz":[0.287856625597655791,0.206350425869901294,0.595952280339008822],"hpluv":[282.819195018988751,184.691924030055,52.5477355185796569],"hsluv":[282.819195018988751,61.7185051859638136,52.5477355185796569]},"#9966dd":{"lch":[53.4878747475352725,89.2117449852098758,279.306611445978092],"luv":[53.4878747475352725,14.4271177471338046,-88.0374563286358],"rgb":[0.6,0.4,0.866666666666666696],"xyz":[0.30937495114828939,0.214957756090154828,0.70928212823901482],"hpluv":[279.306611445978092,211.644028054176175,53.4878747475352725],"hsluv":[279.306611445978092,74.2596178074049362,53.4878747475352725]},"#9966ee":{"lch":[54.4994239962059339,101.810849438236403,276.783380903602506],"luv":[54.4994239962059339,12.0254847729914225,-101.098154183495325],"rgb":[0.6,0.4,0.933333333333333348],"xyz":[0.333187131414464099,0.224482628196624873,0.834692944307538],"hpluv":[276.783380903602506,237.050827216632513,54.4994239962059339],"hsluv":[276.783380903602506,86.9990828065156734,54.4994239962059339]},"#9966ff":{"lch":[55.5786963614876,114.151421142661491,274.908981870437117],"luv":[55.5786963614876,9.76829238934238475,-113.732701597586171],"rgb":[0.6,0.4,1],"xyz":[0.359358179824295521,0.234951047560557569,0.972527132599319888],"hpluv":[274.908981870437117,260.622732185953453,55.5786963614876],"hsluv":[274.908981870437117,99.999999999998991,55.5786963614876]},"#bb6600":{"lch":[51.9152024616159622,85.9194467179265899,34.7713476038742],"luv":[51.9152024616159622,70.5771984524152884,49.0001059480794936],"rgb":[0.733333333333333282,0.4,0],"xyz":[0.252442226002640324,0.200690600030228039,0.0254433319706054567],"hpluv":[34.7713476038742,210.008196913669821,51.9152024616159622],"hsluv":[34.7713476038742,100.000000000002217,51.9152024616159622]},"#bb6611":{"lch":[51.960819173128,84.5067938711160735,34.0102696578751846],"luv":[51.960819173128,70.0508360673827184,47.2681560528436],"rgb":[0.733333333333333282,0.4,0.0666666666666666657],"xyz":[0.253453891502277429,0.201095266230082892,0.0307714369353610864],"hpluv":[34.0102696578751846,206.373990798532162,51.960819173128],"hsluv":[34.0102696578751846,96.7960731817087492,51.960819173128]},"#bb6622":{"lch":[52.0452187907305586,81.9745670334704215,32.5563816919222901],"luv":[52.0452187907305586,69.0932729256005587,44.1129150788451909],"rgb":[0.733333333333333282,0.4,0.133333333333333331],"xyz":[0.255329249640754485,0.20184540948547372,0.040648323131340286],"hpluv":[32.5563816919222901,199.865401092535734,52.0452187907305586],"hsluv":[32.5563816919222901,90.9716633106406221,52.0452187907305586]},"#bb6633":{"lch":[52.1837271506259412,78.04817012610809,30.0375791414029081],"luv":[52.1837271506259412,67.5660884046363,39.0684086920722109],"rgb":[0.733333333333333282,0.4,0.2],"xyz":[0.258417000373212191,0.203080509778456819,0.0569104769889514292],"hpluv":[30.0375791414029081,189.787216830323956,52.1837271506259412],"hsluv":[30.0375791414029081,81.6941023093515639,52.1837271506259412]},"#bb6644":{"lch":[52.3827138306128859,72.9081368603095257,26.1184165145312406],"luv":[52.3827138306128859,65.4632041398932,32.0961886238895318],"rgb":[0.733333333333333282,0.4,0.266666666666666663],"xyz":[0.262874995617431106,0.204863707876144413,0.0803892519418380747],"hpluv":[26.1184165145312406,176.614896915735159,52.3827138306128859],"hsluv":[26.1184165145312406,68.9437006343278824,52.3827138306128859]},"#bb6655":{"lch":[52.6470547760809637,67.004522830646,20.3474245095699864],"luv":[52.6470547760809637,62.823537757634746,23.2982656731697979],"rgb":[0.733333333333333282,0.4,0.333333333333333315],"xyz":[0.268837409656793092,0.207248673491889246,0.111791299215811976],"hpluv":[20.3474245095699864,161.498824171429789,52.6470547760809637],"hsluv":[20.3474245095699864,52.9816895309479534,52.6470547760809637]},"#bb6666":{"lch":[52.9804174131186727,61.0960132663801261,12.1770506300620109],"luv":[52.9804174131186727,59.7213810933874498,12.8871826767560087],"rgb":[0.733333333333333282,0.4,0.4],"xyz":[0.276422405430301277,0.210282671801292537,0.151738943622955924],"hpluv":[12.1770506300620109,146.331162504643544,52.9804174131186727],"hsluv":[12.1770506300620109,34.2899270044314335,52.9804174131186727]},"#bb6677":{"lch":[53.3854132757716826,56.2661599102721226,1.17050216666979279],"luv":[53.3854132757716826,56.2544190111897535,1.14938799445880213],"rgb":[0.733333333333333282,0.4,0.466666666666666674],"xyz":[0.285736418450503182,0.21400827700937336,0.200792745529353833],"hpluv":[1.17050216666979279,133.74082367080041,53.3854132757716826],"hsluv":[1.17050216666979279,37.694842795415525,53.3854132757716826]},"#bb6688":{"lch":[53.8636991644475387,53.7950791600554297,347.554026547444039],"luv":[53.8636991644475387,52.5308766640911458,-11.5938578022448873],"rgb":[0.733333333333333282,0.4,0.533333333333333326],"xyz":[0.296876835552447,0.218464443850150958,0.259465608932926028],"hpluv":[347.554026547444039,126.731828674836166,53.8636991644475387],"hsluv":[347.554026547444039,41.3310399817098855,53.8636991644475387]},"#bb6699":{"lch":[54.4160596975863484,54.7145736516266723,332.78581188167891],"luv":[54.4160596975863484,48.6578429809048814,-25.0219680745716886],"rgb":[0.733333333333333282,0.4,0.6],"xyz":[0.309933799661519682,0.223687229493780115,0.328232286574043908],"hpluv":[332.78581188167891,127.589593839900076,54.4160596975863484],"hsluv":[332.78581188167891,45.0871489409768813,54.4160596975863484]},"#bb66aa":{"lch":[55.0424859024436,59.2427277394444332,319.03138367428437],"luv":[55.0424859024436,44.7323366642012274,-38.8422301956323963],"rgb":[0.733333333333333282,0.4,0.66666666666666663],"xyz":[0.324991492626772238,0.22971030667988121,0.407536136191042508],"hpluv":[319.03138367428437,136.57661144398341,55.0424859024436],"hsluv":[319.03138367428437,48.8627280546895548,55.0424859024436]},"#bb66bb":{"lch":[55.7422560614222,66.7541112543564168,307.715012949244738],"luv":[55.7422560614222,40.8357821803987235,-52.8067255477370452],"rgb":[0.733333333333333282,0.4,0.733333333333333282],"xyz":[0.342129084734108913,0.236565343522815968,0.497794121289684255],"hpluv":[307.715012949244738,151.961230908585406,55.7422560614222],"hsluv":[307.715012949244738,52.5739577191036176,55.7422560614222]},"#bb66cc":{"lch":[56.5140206008290704,76.3075420390205466,299.031845144425],"luv":[56.5140206008290704,37.0317190732607671,-66.7195080506142801],"rgb":[0.733333333333333282,0.4,0.8],"xyz":[0.361421460177830611,0.24428229370030477,0.599400631959954411],"hpluv":[299.031845144425,171.336773989457299,56.5140206008290704],"hsluv":[299.031845144425,57.7422914315118732,56.5140206008290704]},"#bb66dd":{"lch":[57.3558903641351208,87.0819801731049523,292.529347086481266],"luv":[57.3558903641351208,33.3660351201831276,-80.4361794917420809],"rgb":[0.733333333333333282,0.4,0.866666666666666696],"xyz":[0.38293978572846421,0.252889623920558304,0.712730479859960409],"hpluv":[292.529347086481266,192.659130793538424,57.3558903641351208],"hsluv":[292.529347086481266,71.4699790991907,57.3558903641351208]},"#bb66ee":{"lch":[58.2655263288606164,98.4965661150924916,287.652756970849339],"luv":[58.2655263288606164,29.8688319231142287,-93.8585447149780805],"rgb":[0.733333333333333282,0.4,0.933333333333333348],"xyz":[0.40675196599463892,0.262414496027028321,0.838141295928483632],"hpluv":[287.652756970849339,214.510592558062115,58.2655263288606164],"hsluv":[287.652756970849339,85.5420625539119186,58.2655263288606164]},"#bb66ff":{"lch":[59.2402283004695533,110.175409569553764,283.948158265715847],"luv":[59.2402283004695533,26.5571064878979755,-106.926801919861816],"rgb":[0.733333333333333282,0.4,1],"xyz":[0.432923014404470341,0.272882915390961045,0.975975484220265477],"hpluv":[283.948158265715847,235.997431668916079,59.2402283004695533],"hsluv":[283.948158265715847,99.9999999999988205,59.2402283004695533]},"#997700":{"lch":[51.799451349173637,61.2288227532233265,61.7368019650066202],"luv":[51.799451349173637,28.9932293289078338,53.9292257391759406],"rgb":[0.6,0.466666666666666674,0],"xyz":[0.197331129475883132,0.19966620830666032,0.028146226367465537],"hpluv":[61.7368019650066202,149.992683828924328,51.799451349173637],"hsluv":[61.7368019650066202,100.000000000002373,51.799451349173637]},"#997711":{"lch":[51.8452237949875752,59.5195003520895298,61.1595916745536812],"luv":[51.8452237949875752,28.7105152364728049,52.1371003894409952],"rgb":[0.6,0.466666666666666674,0.0666666666666666657],"xyz":[0.198342794975520265,0.200070874506515173,0.0334743313322211702],"hpluv":[61.1595916745536812,145.676617799321178,51.8452237949875752],"hsluv":[61.1595916745536812,96.7355174862457687,51.8452237949875752]},"#997722":{"lch":[51.9299107218419778,56.4237897442973448,60.0184197539949],"luv":[51.9299107218419778,28.1961842142201746,48.8735024820856836],"rgb":[0.6,0.466666666666666674,0.133333333333333331],"xyz":[0.200218153113997266,0.200821017761906,0.0433512175282003628],"hpluv":[60.0184197539949,137.874516690543771,51.9299107218419778],"hsluv":[60.0184197539949,90.8032063934702762,51.9299107218419778]},"#997733":{"lch":[52.0688882655341843,51.532107019520943,57.9108306747127841],"luv":[52.0688882655341843,27.375836028403171,43.6591531710973797],"rgb":[0.6,0.466666666666666674,0.2],"xyz":[0.203305903846455027,0.2020561180548891,0.0596133713858115061],"hpluv":[57.9108306747127841,125.585333003110208,52.0688882655341843],"hsluv":[57.9108306747127841,81.359583819486275,52.0688882655341843]},"#997744":{"lch":[52.2685439893789265,44.9234500117750244,54.2507061045172563],"luv":[52.2685439893789265,26.2460613351246792,36.4590266649196622],"rgb":[0.6,0.466666666666666674,0.266666666666666663],"xyz":[0.207763899090673887,0.203839316152576694,0.0830921463386981446],"hpluv":[54.2507061045172563,109.061640425204757,52.2685439893789265],"hsluv":[54.2507061045172563,68.3925961892813632,52.2685439893789265]},"#997755":{"lch":[52.5337646967731615,36.9638675487782962,47.8040559904272229],"luv":[52.5337646967731615,24.8274523779219614,27.3847605902560787],"rgb":[0.6,0.466666666666666674,0.333333333333333315],"xyz":[0.213726313130035872,0.206224281768321527,0.11449419361267206],"hpluv":[47.8040559904272229,89.2849392346346,52.5337646967731615],"hsluv":[47.8040559904272229,52.1784042692219217,52.5337646967731615]},"#997766":{"lch":[52.8682223623880958,28.5307109293219519,35.7342712802299047],"luv":[52.8682223623880958,23.1593577603421643,16.6627012894371447],"rgb":[0.6,0.466666666666666674,0.4],"xyz":[0.221311308903544057,0.209258280077724818,0.154441838019816],"hpluv":[35.7342712802299047,68.4789688439394695,52.8682223623880958],"hsluv":[35.7342712802299047,33.2180784313787072,52.8682223623880958]},"#997777":{"lch":[53.2745272921510349,21.7835186536615062,12.1770506300626185],"luv":[53.2745272921510349,21.2933995119794766,4.59486911213486],"rgb":[0.6,0.466666666666666674,0.466666666666666674],"xyz":[0.230625321923745963,0.212983885285805641,0.203495639926213917],"hpluv":[12.1770506300626185,51.8857087556556777,53.2745272921510349],"hsluv":[12.1770506300626185,12.1864056638809046,53.2745272921510349]},"#997788":{"lch":[53.7543298043441524,21.0694932264164443,336.259644884191403],"luv":[53.7543298043441524,19.28657717102978,-8.48242216845644492],"rgb":[0.6,0.466666666666666674,0.533333333333333326],"xyz":[0.241765739025689819,0.217440052126583239,0.262168503329786085],"hpluv":[336.259644884191403,49.7370433553737143,53.7543298043441524],"hsluv":[336.259644884191403,17.3594920402921318,53.7543298043441524]},"#997799":{"lch":[54.308403390094881,28.1087123643927,307.715012949247921],"luv":[54.308403390094881,17.1950646022419384,-22.235769923906151],"rgb":[0.6,0.466666666666666674,0.6],"xyz":[0.254822703134762518,0.222662837770212396,0.330935180970904],"hpluv":[307.715012949247921,65.67699031054849,54.308403390094881],"hsluv":[307.715012949247921,22.7222383700086681,54.308403390094881]},"#9977aa":{"lch":[54.9367240193748785,39.361724048309469,292.510155009375],"luv":[54.9367240193748785,15.0695247856183894,-36.3628208860492137],"rgb":[0.6,0.466666666666666674,0.66666666666666663],"xyz":[0.269880396100015074,0.228685914956313491,0.41023903058790262],"hpluv":[292.510155009375,90.9181689788077847,54.9367240193748785],"hsluv":[292.510155009375,30.8964586946041671,54.9367240193748785]},"#9977bb":{"lch":[55.6385517902762388,52.2405182414828104,284.355371582691191],"luv":[55.6385517902762388,12.9522722169503091,-50.6093903397058824],"rgb":[0.6,0.466666666666666674,0.733333333333333282],"xyz":[0.287017988207351693,0.235540951799248249,0.500497015686544366],"hpluv":[284.355371582691191,119.143673365147691,55.6385517902762388],"hsluv":[284.355371582691191,44.025050152294007,55.6385517902762388]},"#9977cc":{"lch":[56.4125166695819615,65.6830300518217172,279.531250686135081],"luv":[56.4125166695819615,10.8761592408186605,-64.7763042860340192],"rgb":[0.6,0.466666666666666674,0.8],"xyz":[0.306310363651073447,0.243257901976737051,0.602103526356814522],"hpluv":[279.531250686135081,147.746441920881637,56.4125166695819615],"hsluv":[279.531250686135081,57.5215558896316352,56.4125166695819615]},"#9977dd":{"lch":[57.256707620000924,79.2159287347205,276.425234899334782],"luv":[57.256707620000924,8.86478593594131858,-78.718351962006011],"rgb":[0.6,0.466666666666666674,0.866666666666666696],"xyz":[0.327828689201707,0.251865232196990585,0.71543337425682052],"hpluv":[276.425234899334782,175.559960004438778,57.256707620000924],"hsluv":[276.425234899334782,71.3413917340773764,57.256707620000924]},"#9977ee":{"lch":[58.1687631275758434,92.5981917117116211,274.294200356840065],"luv":[58.1687631275758434,6.93354781471817905,-92.3382424728774822],"rgb":[0.6,0.466666666666666674,0.933333333333333348],"xyz":[0.351640869467881756,0.261390104303460602,0.840844190325343743],"hpluv":[274.294200356840065,202.000294664132923,58.1687631275758434],"hsluv":[274.294200356840065,85.4864748016987903,58.1687631275758434]},"#9977ff":{"lch":[59.1459606243173,105.700835267318482,272.760722153075335],"luv":[59.1459606243173,5.0910859147335179,-105.578157875659116],"rgb":[0.6,0.466666666666666674,1],"xyz":[0.377811917877713122,0.271858523667393326,0.978678378617125588],"hpluv":[272.760722153075335,226.773684284234889,59.1459606243173],"hsluv":[272.760722153075335,99.9999999999988,59.1459606243173]},"#bb7700":{"lch":[55.8465021194210323,78.9426527823167703,44.2288975260652037],"luv":[55.8465021194210323,56.5670601566064,55.0645996403160751],"rgb":[0.733333333333333282,0.466666666666666674,0],"xyz":[0.270895964056058,0.237598076137063796,0.0315945779884111572],"hpluv":[44.2288975260652037,179.372171604304526,55.8465021194210323],"hsluv":[44.2288975260652037,100.000000000002402,55.8465021194210323]},"#bb7711":{"lch":[55.8872675460691113,77.5581898683241775,43.5811171927028127],"luv":[55.8872675460691113,56.1830827877517081,53.4671303149482782],"rgb":[0.733333333333333282,0.466666666666666674,0.0666666666666666657],"xyz":[0.271907629555695085,0.238002742336918649,0.0369226829531667869],"hpluv":[43.5811171927028127,176.097874689063588,55.8872675460691113],"hsluv":[43.5811171927028127,97.2747266570755613,55.8872675460691113]},"#bb7722":{"lch":[55.9627137258116534,75.0570685818031365,42.3362918908129799],"luv":[55.9627137258116534,55.4825342436315907,50.549499878809371],"rgb":[0.733333333333333282,0.466666666666666674,0.133333333333333331],"xyz":[0.273782987694172142,0.238752885592309477,0.0467995691491459864],"hpluv":[42.3362918908129799,170.189263625481374,55.9627137258116534],"hsluv":[42.3362918908129799,92.3060252972229875,55.9627137258116534]},"#bb7733":{"lch":[56.086591241629975,71.12386069085467,40.1553843778465094],"luv":[56.086591241629975,54.3598535070873652,45.8651271257379562],"rgb":[0.733333333333333282,0.466666666666666674,0.2],"xyz":[0.276870738426629848,0.239987985885292576,0.0630617230067571366],"hpluv":[40.1553843778465094,160.914656808849855,56.086591241629975],"hsluv":[40.1553843778465094,84.3528141134219425,56.086591241629975]},"#bb7744":{"lch":[56.2646940492590346,65.8532423012147632,36.6949041745596887],"luv":[56.2646940492590346,52.8030258036740747,39.3508575199960617],"rgb":[0.733333333333333282,0.466666666666666674,0.266666666666666663],"xyz":[0.281328733670848763,0.24177118398298017,0.0865404979596437751],"hpluv":[36.6949041745596887,148.518490760970963,56.2646940492590346],"hsluv":[36.6949041745596887,73.3442464951488517,56.2646940492590346]},"#bb7755":{"lch":[56.5015366957073866,59.5720019456390375,31.4313823601585],"luv":[56.5015366957073866,50.8307220514796256,31.0654327434279267],"rgb":[0.733333333333333282,0.466666666666666674,0.333333333333333315],"xyz":[0.287291147710210748,0.244156149598725,0.117942545233617677],"hpluv":[31.4313823601585,133.789263155984059,56.5015366957073866],"hsluv":[31.4313823601585,59.433527841274838,56.5015366957073866]},"#bb7766":{"lch":[56.8006139195957758,52.9060784141758376,23.584548946691168],"luv":[56.8006139195957758,48.4868685528452588,21.1678225404983067],"rgb":[0.733333333333333282,0.466666666666666674,0.4],"xyz":[0.294876143483718933,0.247190147908128294,0.157890189640761625],"hpluv":[23.584548946691168,118.193030459121616,56.8006139195957758],"hsluv":[23.584548946691168,42.9582981176577476,56.8006139195957758]},"#bb7777":{"lch":[57.1645375630264851,46.8887603377642677,12.1770506300621175],"luv":[57.1645375630264851,45.8337848153679062,9.89040016939892652],"rgb":[0.733333333333333282,0.466666666666666674,0.466666666666666674],"xyz":[0.304190156503920839,0.250915753116209117,0.206943991547159534],"hpluv":[12.1770506300621175,104.083378979503351,57.1645375630264851],"hsluv":[12.1770506300621175,30.9338815185941769,57.1645375630264851]},"#bb7788":{"lch":[57.5951231639082408,43.0166042307866761,356.679907444569722],"luv":[57.5951231639082408,42.9444038116514264,-2.49126891562360298],"rgb":[0.733333333333333282,0.466666666666666674,0.533333333333333326],"xyz":[0.315330573605864639,0.255371919956986715,0.265616854950731729],"hpluv":[356.679907444569722,94.7741152880685149,57.5951231639082408],"hsluv":[356.679907444569722,32.9204937798227419,57.5951231639082408]},"#bb7799":{"lch":[58.0934559183715322,42.8683503206465062,338.533521874652],"luv":[58.0934559183715322,39.8946515879682408,-15.6879646190414519],"rgb":[0.733333333333333282,0.466666666666666674,0.6],"xyz":[0.328387537714937339,0.260594705600615872,0.334383532591849608],"hpluv":[338.533521874652,93.6373004736019823,58.0934559183715322],"hsluv":[338.533521874652,34.9811369830312131,58.0934559183715322]},"#bb77aa":{"lch":[58.6599497668646706,47.0820583870944276,321.324781752589786],"luv":[58.6599497668646706,36.7569990603765,-29.4218157502430451],"rgb":[0.733333333333333282,0.466666666666666674,0.66666666666666663],"xyz":[0.343445230680189895,0.266617782786717,0.413687382208848209],"hpluv":[321.324781752589786,101.848135129910219,58.6599497668646706],"hsluv":[321.324781752589786,37.0556810629478051,58.6599497668646706]},"#bb77bb":{"lch":[59.2944060970233693,54.9189596898792303,307.71501294924542],"luv":[59.2944060970233693,33.5958135510894706,-43.4443718479046765],"rgb":[0.733333333333333282,0.466666666666666674,0.733333333333333282],"xyz":[0.360582822787526569,0.273472819629651753,0.50394536730749],"hpluv":[307.71501294924542,117.529775077760561,59.2944060970233693],"hsluv":[307.71501294924542,40.6617226560308467,59.2944060970233693]},"#bb77cc":{"lch":[59.9960747587738155,65.1135012197087519,297.896140559284788],"luv":[59.9960747587738155,30.4646722292654815,-57.5471266620014177],"rgb":[0.733333333333333282,0.466666666666666674,0.8],"xyz":[0.379875198231248268,0.281189769807140555,0.605551877977760111],"hpluv":[297.896140559284788,137.716994859863917,59.9960747587738155],"hsluv":[297.896140559284788,53.5682479917909,59.9960747587738155]},"#bb77dd":{"lch":[60.7637179337253599,76.6332290650186394,290.953982706702106],"luv":[60.7637179337253599,27.4054240934965065,-71.5653165100750357],"rgb":[0.733333333333333282,0.466666666666666674,0.866666666666666696],"xyz":[0.401393523781881867,0.289797100027394061,0.718881725877766109],"hpluv":[290.953982706702106,160.033945707839,60.7637179337253599],"hsluv":[290.953982706702106,68.5485010485900119,60.7637179337253599]},"#bb77ee":{"lch":[61.5956761624293563,88.8082274030350902,285.979672103614405],"luv":[61.5956761624293563,24.4485758512518743,-85.3766267389077456],"rgb":[0.733333333333333282,0.466666666666666674,0.933333333333333348],"xyz":[0.425205704048056576,0.299321972133864078,0.844292541946289332],"hpluv":[285.979672103614405,182.954165183101395,61.5956761624293563],"hsluv":[285.979672103614405,84.0163684558434909,61.5956761624293563]},"#bb77ff":{"lch":[62.4899351736807773,101.23109143545085,282.328516880108566],"luv":[62.4899351736807773,21.6145233767131266,-98.8966442929694693],"rgb":[0.733333333333333282,0.466666666666666674,1],"xyz":[0.451376752457888,0.309790391497796802,0.982126730238071177],"hpluv":[282.328516880108566,205.562159598045383,62.4899351736807773],"hsluv":[282.328516880108566,99.9999999999986784,62.4899351736807773]},"#998800":{"lch":[56.4673516485332527,62.834492950420568,74.7562721675545561],"luv":[56.4673516485332527,16.5207966112614884,60.6237311922136897],"rgb":[0.6,0.533333333333333326,0],"xyz":[0.219403499200853586,0.243810947756601892,0.0355036829424554834],"hpluv":[74.7562721675545561,141.201731332299261,56.4673516485332527],"hsluv":[74.7562721675545561,100.000000000002331,56.4673516485332527]},"#998811":{"lch":[56.5074221469723881,61.2259080808398366,74.51872844438833],"luv":[56.5074221469723881,16.3426261455871646,59.0044946676862878],"rgb":[0.6,0.533333333333333326,0.0666666666666666657],"xyz":[0.220415164700490718,0.244215613956456745,0.0408317879072111131],"hpluv":[74.51872844438833,137.489352382480689,56.5074221469723881],"hsluv":[74.51872844438833,97.3110722480099781,56.5074221469723881]},"#998822":{"lch":[56.5815852437789744,58.2905156727598666,74.0508275651119],"luv":[56.5815852437789744,16.0173304476746452,56.0466711119068961],"rgb":[0.6,0.533333333333333326,0.133333333333333331],"xyz":[0.222290522838967719,0.244965757211847573,0.0507086741031903127],"hpluv":[74.0508275651119,130.726042229432494,56.5815852437789744],"hsluv":[74.0508275651119,92.4075523300517574,56.5815852437789744]},"#998833":{"lch":[56.7033645714083,53.5858970619529273,73.1917859227149],"luv":[56.7033645714083,15.4953822971072128,51.2966031175623911],"rgb":[0.6,0.533333333333333326,0.2],"xyz":[0.22537827357142548,0.246200857504830672,0.066970827960801449],"hpluv":[73.1917859227149,119.917068416956084,56.7033645714083],"hsluv":[73.1917859227149,84.5557602276611533,56.7033645714083]},"#998844":{"lch":[56.8784692361674189,47.0662938677721456,71.7105236832421156],"luv":[56.8784692361674189,14.7702533586865563,44.6886521856241927],"rgb":[0.6,0.533333333333333326,0.266666666666666663],"xyz":[0.22983626881564434,0.247984055602518266,0.0904496029136880875],"hpluv":[71.7105236832421156,105.00293267331034,56.8784692361674189],"hsluv":[71.7105236832421156,73.6816499137771075,56.8784692361674189]},"#998855":{"lch":[57.1113583918905761,38.8337969655052433,69.1066660847648393],"luv":[57.1113583918905761,13.8492700909341142,36.2803184206870242],"rgb":[0.6,0.533333333333333326,0.333333333333333315],"xyz":[0.235798682855006325,0.250369021218263099,0.121851650187662],"hpluv":[69.1066660847648393,86.2832891510872599,57.1113583918905761],"hsluv":[69.1066660847648393,59.9309888570698774,57.1113583918905761]},"#998866":{"lch":[57.4054971647218224,29.1657433305745144,64.0747883902216],"luv":[57.4054971647218224,12.7511922431808031,26.2306629806110223],"rgb":[0.6,0.533333333333333326,0.4],"xyz":[0.24338367862851451,0.253403019527666418,0.161799294594805965],"hpluv":[64.0747883902216,64.4701815948561574,57.4054971647218224],"hsluv":[64.0747883902216,43.6310875702010321,57.4054971647218224]},"#998877":{"lch":[57.7634914296009612,18.7238256654584347,52.0945218145914097],"luv":[57.7634914296009612,11.5031815844705712,14.773573060880608],"rgb":[0.6,0.533333333333333326,0.466666666666666674],"xyz":[0.252697691648716416,0.257128624735747213,0.210853096501203874],"hpluv":[52.0945218145914097,41.1320618043462858,57.7634914296009612],"hsluv":[52.0945218145914097,25.2418236256697028,57.7634914296009612]},"#998888":{"lch":[58.1871725604667489,10.3706980586515272,12.1770506300640946],"luv":[58.1871725604667489,10.1373621264743505,2.18752539195365081],"rgb":[0.6,0.533333333333333326,0.533333333333333326],"xyz":[0.263838108750660272,0.261584791576524811,0.269525959904776],"hpluv":[12.1770506300640946,22.6162221883482317,58.1871725604667489],"hsluv":[12.1770506300640946,7.14421708061451799,58.1871725604667489]},"#998899":{"lch":[58.6776613659523605,14.2013195506443459,307.715012949254117],"luv":[58.6776613659523605,8.6874348403017283,-11.2341422847952668],"rgb":[0.6,0.533333333333333326,0.6],"xyz":[0.276895072859732971,0.266807577220153969,0.338292637545893948],"hpluv":[307.715012949254117,30.7110899398720818,58.6776613659523605],"hsluv":[307.715012949254117,10.6251017733449729,58.6776613659523605]},"#9988aa":{"lch":[59.2354248002074399,26.2127450059066938,285.910383521223935],"luv":[59.2354248002074399,7.18579172527609789,-25.2085778659891844],"rgb":[0.6,0.533333333333333326,0.66666666666666663],"xyz":[0.291952765824985527,0.272830654406255091,0.417596487162892549],"hpluv":[285.910383521223935,56.1526584479988173,59.2354248002074399],"hsluv":[285.910383521223935,23.5088603674401817,59.2354248002074399]},"#9988bb":{"lch":[59.8603319378123189,39.8857557696632696,278.160160819701673],"luv":[59.8603319378123189,5.66141142610705117,-39.4819190767314581],"rgb":[0.6,0.533333333333333326,0.733333333333333282],"xyz":[0.309090357932322146,0.279685691249189849,0.507854472261534351],"hpluv":[278.160160819701673,84.5508603994872,59.8603319378123189],"hsluv":[278.160160819701673,37.7262541103550291,59.8603319378123189]},"#9988cc":{"lch":[60.55171199345871,53.9990869041691823,274.395593429514747],"luv":[60.55171199345871,4.13861667015410095,-53.8402566723222264],"rgb":[0.6,0.533333333333333326,0.8],"xyz":[0.3283827333760439,0.287402641426678651,0.609460982931804507],"hpluv":[274.395593429514747,113.161661700826286,60.55171199345871],"hsluv":[274.395593429514747,52.5240219153236723,60.55171199345871]},"#9988dd":{"lch":[61.3084150605589855,68.1648195931338563,272.216747448240312],"luv":[61.3084150605589855,2.63660773112319324,-68.1138086575451],"rgb":[0.6,0.533333333333333326,0.866666666666666696],"xyz":[0.349901058926677444,0.296009971646932157,0.722790830831810505],"hpluv":[272.216747448240312,141.084572716849891,61.3084150605589855],"hsluv":[272.216747448240312,67.8395486149695,61.3084150605589855]},"#9988ee":{"lch":[62.128875020953032,82.18421866163294,270.815422264053723],"luv":[62.128875020953032,1.1695901512833331,-82.1758958326656597],"rgb":[0.6,0.533333333333333326,0.933333333333333348],"xyz":[0.373713239192852154,0.305534843753402174,0.848201646900333728],"hpluv":[270.815422264053723,167.854994169255662,62.128875020953032],"hsluv":[270.815422264053723,83.6558877567472905,62.128875020953032]},"#9988ff":{"lch":[63.0111734122257303,95.9388777898474387,269.8490772999765],"luv":[63.0111734122257303,-0.252712116882344406,-95.9385449554102],"rgb":[0.6,0.533333333333333326,1],"xyz":[0.399884287602683575,0.316003263117334898,0.986035835192115462],"hpluv":[269.8490772999765,193.204124490752207,63.0111734122257303],"hsluv":[269.8490772999765,99.9999999999985363,63.0111734122257303]},"#bb8800":{"lch":[60.0458653136574,74.8864062555341832,55.056379834278971],"luv":[60.0458653136574,42.8926945435799,61.3855894869476728],"rgb":[0.733333333333333282,0.533333333333333326,0],"xyz":[0.292968333781028434,0.281742815587005313,0.038952034563401107],"hpluv":[55.056379834278971,158.255644288368103,60.0458653136574],"hsluv":[55.056379834278971,100.000000000002288,60.0458653136574]},"#bb8811":{"lch":[60.0822560315187957,73.5298298886522161,54.5759299869630823],"luv":[60.0822560315187957,42.619621560372849,59.9183089005750773],"rgb":[0.733333333333333282,0.533333333333333326,0.0666666666666666657],"xyz":[0.293979999280665538,0.282147481786860166,0.0442801395281567367],"hpluv":[54.5759299869630823,155.294707870281485,60.0822560315187957],"hsluv":[54.5759299869630823,97.6878818876268866,60.0822560315187957]},"#bb8822":{"lch":[60.1496227929862499,71.0610449842002367,53.6488709316330343],"luv":[60.1496227929862499,42.1201645307819774,57.2325419158225586],"rgb":[0.733333333333333282,0.533333333333333326,0.133333333333333331],"xyz":[0.295855357419142595,0.282897625042250966,0.0541570257241359362],"hpluv":[53.6488709316330343,149.912555699661567,60.1496227929862499],"hsluv":[53.6488709316330343,93.46183514856709,60.1496227929862499]},"#bb8833":{"lch":[60.2602822329103844,67.1261991777524,52.0115270519145412],"luv":[60.2602822329103844,41.3163720666953154,52.9044801061090197],"rgb":[0.733333333333333282,0.533333333333333326,0.2],"xyz":[0.298943108151600301,0.284132725335234093,0.0704191795817470795],"hpluv":[52.0115270519145412,141.351435183858257,60.2602822329103844],"hsluv":[52.0115270519145412,86.668700859176,60.2602822329103844]},"#bb8844":{"lch":[60.4194844691316746,61.7320119628667285,49.374045706205429],"luv":[60.4194844691316746,40.1948297943626258,46.8531424643613406],"rgb":[0.733333333333333282,0.533333333333333326,0.266666666666666663],"xyz":[0.303401103395819216,0.285915923432921659,0.093897954534633718],"hpluv":[49.374045706205429,129.650066203053939,60.4194844691316746],"hsluv":[49.374045706205429,77.207197386412,60.4194844691316746]},"#bb8855":{"lch":[60.6313805732006585,55.0590005000961682,45.2500033552910708],"luv":[60.6313805732006585,38.7623447760430935,39.1020992215604082],"rgb":[0.733333333333333282,0.533333333333333326,0.333333333333333315],"xyz":[0.309363517435181201,0.28830088904866652,0.125300001808607619],"hpluv":[45.2500033552910708,115.231228654446355,60.6313805732006585],"hsluv":[45.2500033552910708,65.1528926573884775,60.6313805732006585]},"#bb8866":{"lch":[60.8992588402534949,47.519038379270981,38.7816256818529581],"luv":[60.8992588402534949,37.0429375720225096,29.7637327048519147],"rgb":[0.733333333333333282,0.533333333333333326,0.4],"xyz":[0.316948513208689386,0.291334887358069838,0.165247646215751581],"hpluv":[38.7816256818529581,99.0136254476035305,60.8992588402534949],"hsluv":[38.7816256818529581,50.7321114426118,60.8992588402534949]},"#bb8877":{"lch":[61.2256685857267087,39.8992767652027354,28.4701407483744688],"luv":[61.2256685857267087,35.0740840991728362,19.0200134329710231],"rgb":[0.733333333333333282,0.533333333333333326,0.466666666666666674],"xyz":[0.326262526228891292,0.295060492566150634,0.21430144812214949],"hpluv":[28.4701407483744688,82.6933933486175761,61.2256685857267087],"hsluv":[28.4701407483744688,34.2887258466009897,61.2256685857267087]},"#bb8888":{"lch":[61.6124959728340684,33.6595928281588499,12.1770506300623627],"luv":[61.6124959728340684,32.9022674846918903,7.09992843085263114],"rgb":[0.733333333333333282,0.533333333333333326,0.533333333333333326],"xyz":[0.337402943330835092,0.299516659406928232,0.272974311525721658],"hpluv":[12.1770506300623627,69.3233245158679,61.6124959728340684],"hsluv":[12.1770506300623627,26.8235367690150284,61.6124959728340684]},"#bb8899":{"lch":[62.0610184830546388,31.1131530731089718,349.361203223606594],"luv":[62.0610184830546388,30.5783355372127765,-5.74401339869088723],"rgb":[0.733333333333333282,0.533333333333333326,0.6],"xyz":[0.350459907439907847,0.304739445050557389,0.341740989166839593],"hpluv":[349.361203223606594,63.6157209963685091,62.0610184830546388],"hsluv":[349.361203223606594,28.7433747177793393,62.0610184830546388]},"#bb88aa":{"lch":[62.5719506337331097,34.1093853871598185,325.627133749050586],"luv":[62.5719506337331097,28.1532372220531357,-19.2573467904743723],"rgb":[0.733333333333333282,0.533333333333333326,0.66666666666666663],"xyz":[0.365517600405160348,0.310762522236658512,0.421044838783838193],"hpluv":[325.627133749050586,69.1725086761469328,62.5719506337331097],"hsluv":[325.627133749050586,30.7007491098828176,62.5719506337331097]},"#bb88bb":{"lch":[63.1454872588298,41.9701566603395477,307.715012949246614],"luv":[63.1454872588298,25.674586077978244,-33.2010493782640808],"rgb":[0.733333333333333282,0.533333333333333326,0.733333333333333282],"xyz":[0.382655192512497,0.31761755907959327,0.51130282388247994],"hpluv":[307.715012949246614,84.3407770596407,63.1454872588298],"hsluv":[307.715012949246614,32.6446535119142354,63.1454872588298]},"#bb88cc":{"lch":[63.7813474201422,52.7335158558763055,296.081540752202443],"luv":[63.7813474201422,23.1842810338905281,-47.3636232510092228],"rgb":[0.733333333333333282,0.533333333333333326,0.8],"xyz":[0.401947567956218776,0.325334509257082072,0.612909334552750096],"hpluv":[296.081540752202443,104.913738848088499,63.7813474201422],"hsluv":[296.081540752202443,48.441096457031712,63.7813474201422]},"#bb88dd":{"lch":[64.4788201663492089,64.9599578897110916,288.597779393076337],"luv":[64.4788201663492089,20.7171971389296665,-61.56779898404492],"rgb":[0.733333333333333282,0.533333333333333326,0.866666666666666696],"xyz":[0.423465893506852264,0.333941839477335578,0.726239182452756094],"hpluv":[288.597779393076337,127.840358269428478,64.4788201663492089],"hsluv":[288.597779393076337,64.9415793589177,64.4788201663492089]},"#bb88ee":{"lch":[65.2368122498474463,77.8541115668441392,283.595470556329246],"luv":[65.2368122498474463,18.300798164755431,-75.6726071600252084],"rgb":[0.733333333333333282,0.533333333333333326,0.933333333333333348],"xyz":[0.44727807377302703,0.343466711583805595,0.851649998521279317],"hpluv":[283.595470556329246,151.435657753316406,65.2368122498474463],"hsluv":[283.595470556329246,82.1213401763518789,65.2368122498474463]},"#bb88ff":{"lch":[66.0538972531437452,90.9819525935223652,280.100148709787334],"luv":[66.0538972531437452,15.9554396417090967,-89.5719802369565201],"rgb":[0.733333333333333282,0.533333333333333326,1],"xyz":[0.473449122182858395,0.353935130947738319,0.989484186813061162],"hpluv":[280.100148709787334,174.781769995450787,66.0538972531437452],"hsluv":[280.100148709787334,99.99999999999838,66.0538972531437452]},"#999900":{"lch":[61.2683639221826866,67.5422828804358772,85.8743202181747449],"luv":[61.2683639221826866,4.85929488236129092,67.3672563635114869],"rgb":[0.6,0.6,0],"xyz":[0.245273099653321058,0.295550148661537559,0.0441268830932777384],"hpluv":[85.8743202181747449,139.887458074797593,61.2683639221826866],"hsluv":[85.8743202181747449,100.000000000002359,61.2683639221826866]},"#999911":{"lch":[61.3036130280217861,66.0751339072958785,85.8743202181746881],"luv":[61.3036130280217861,4.75374160235953358,65.9039093047224185],"rgb":[0.6,0.6,0.0666666666666666657],"xyz":[0.24628476515295819,0.295954814861392412,0.0494549880580333681],"hpluv":[85.8743202181746881,136.770144995815713,61.3036130280217861],"hsluv":[85.8743202181746881,97.7715564197957718,61.3036130280217861]},"#999922":{"lch":[61.3688705786650104,63.38848415762304,85.8743202181745744],"luv":[61.3688705786650104,4.56045196477970372,63.2242216375825663],"rgb":[0.6,0.6,0.133333333333333331],"xyz":[0.248160123291435192,0.296704958116783213,0.0593318742540125676],"hpluv":[85.8743202181745744,131.069475710796667,61.3688705786650104],"hsluv":[85.8743202181745744,93.6963738669960691,61.3688705786650104]},"#999933":{"lch":[61.4760769955270945,59.0559618954583243,85.8743202181743754],"luv":[61.4760769955270945,4.24875087387181871,58.9029265097210484],"rgb":[0.6,0.6,0.2],"xyz":[0.251247874023892925,0.29794005840976634,0.0755940281116237178],"hpluv":[85.8743202181743754,121.898097720990123,61.4760769955270945],"hsluv":[85.8743202181743754,87.1401192062652683,61.4760769955270945]},"#999944":{"lch":[61.6303367515695,52.9921690524208,85.8743202181739775],"luv":[61.6303367515695,3.81249440942850049,52.8548471500809569],"rgb":[0.6,0.6,0.266666666666666663],"xyz":[0.255705869268111841,0.299723256507453906,0.0990728030645103563],"hpluv":[85.8743202181739775,109.10797160418339,61.6303367515695],"hsluv":[85.8743202181739775,77.9969649215058,61.6303367515695]},"#999955":{"lch":[61.8357003743425935,45.2147461889200173,85.8743202181734517],"luv":[61.8357003743425935,3.25295171251598125,45.0975784059909],"rgb":[0.6,0.6,0.333333333333333315],"xyz":[0.261668283307473826,0.302108222123198766,0.130474850338484272],"hpluv":[85.8743202181734517,92.7855058259100218,61.8357003743425935],"hsluv":[85.8743202181734517,66.3286810003367577,61.8357003743425935]},"#999966":{"lch":[62.0953945325949377,35.8293841981041083,85.874320218172457],"luv":[62.0953945325949377,2.57772666020637553,35.7365372872164784],"rgb":[0.6,0.6,0.4],"xyz":[0.269253279080982,0.305142220432602085,0.170422494745628206],"hpluv":[85.874320218172457,73.2182390722606,62.0953945325949377],"hsluv":[85.874320218172457,52.3408174542086542,62.0953945325949377]},"#999977":{"lch":[62.4119425079225749,25.0116267171883422,85.8743202181703],"luv":[62.4119425079225749,1.79944864939855109,24.9468125338318],"rgb":[0.6,0.6,0.466666666666666674],"xyz":[0.278567292101183916,0.30886782564068288,0.219476296652026115],"hpluv":[85.8743202181703,50.8526471570801775,62.4119425079225749],"hsluv":[85.8743202181703,36.3525421484824918,62.4119425079225749]},"#999988":{"lch":[62.7872374999600567,12.9853368609797517,85.8743202181639589],"luv":[62.7872374999600567,0.934223397011331502,12.9516871502363],"rgb":[0.6,0.6,0.533333333333333326],"xyz":[0.289707709203127717,0.313323992481460478,0.27814916005559831],"hpluv":[85.8743202181639589,26.2434647477884546,62.7872374999600567],"hsluv":[85.8743202181639589,18.7604129126121961,62.7872374999600567]},"#999999":{"lch":[63.2225945523589843,3.33307052034688283e-12,0],"luv":[63.2225945523589843,3.14807442966336163e-12,1.09498241031769098e-12],"rgb":[0.6,0.6,0.6],"xyz":[0.302764673312200472,0.318546778125089636,0.346915837696716189],"hpluv":[0,6.68977504875838914e-12,63.2225945523589843],"hsluv":[0,3.10313074237261963e-12,63.2225945523589843]},"#9999aa":{"lch":[63.7187933641432238,13.6904464527836414,265.874320218190064],"luv":[63.7187933641432238,-0.984952144759020598,-13.6549695477167123],"rgb":[0.6,0.6,0.66666666666666663],"xyz":[0.317822366277453,0.324569855311190758,0.42621968731371479],"hpluv":[265.874320218190064,27.2639887848552753,63.7187933641432238],"hsluv":[265.874320218190064,14.5770868731616492,63.7187933641432238]},"#9999bb":{"lch":[64.276118203606174,27.8450519356751158,265.874320218183641],"luv":[64.276118203606174,-2.00329797275791854,-27.7728953213882335],"rgb":[0.6,0.6,0.733333333333333282],"xyz":[0.334959958384789647,0.331424892154125517,0.516477672412356537],"hpluv":[265.874320218183641,54.9715165011475904,64.276118203606174],"hsluv":[265.874320218183641,30.0955931685464577,64.276118203606174]},"#9999cc":{"lch":[64.8943980299807635,42.2483295275786332,265.874320218181538],"luv":[64.8943980299807635,-3.03953438803302189,-42.138848804575062],"rgb":[0.6,0.6,0.8],"xyz":[0.354252333828511401,0.339141842331614318,0.618084183082626692],"hpluv":[265.874320218181538,82.6117192029769,64.8943980299807635],"hsluv":[265.874320218181538,46.4456834766813316,64.8943980299807635]},"#9999dd":{"lch":[65.5730481583578353,56.7175687031348,265.874320218180458],"luv":[65.5730481583578353,-4.08051637559571567,-56.570592941061804],"rgb":[0.6,0.6,0.866666666666666696],"xyz":[0.375770659379144889,0.347749172551867824,0.73141403098263269],"hpluv":[265.874320218180458,109.756831209262941,65.5730481583578353],"hsluv":[265.874320218180458,63.5568222493012627,65.5730481583578353]},"#9999ee":{"lch":[66.311113738117,71.1055788100052695,265.874320218179832],"luv":[66.311113738117,-5.11565437949467672,-70.9213185027987691],"rgb":[0.6,0.6,0.933333333333333348],"xyz":[0.399582839645319654,0.357274044658337842,0.856824847051155913],"hpluv":[265.874320218179832,136.068212717368169,66.311113738117],"hsluv":[265.874320218179832,81.4020980414818922,66.311113738117]},"#9999ff":{"lch":[67.1073146704137145,85.2999068143523829,265.874320218179378],"luv":[67.1073146704137145,-6.13685802391602486,-85.0788638624864149],"rgb":[0.6,0.6,1],"xyz":[0.425753888055151,0.367742464022270565,0.994659035342937758],"hpluv":[265.874320218179378,161.293929533565688,67.1073146704137145],"hsluv":[265.874320218179378,99.9999999999983,67.1073146704137145]},"#bb9900":{"lch":[64.4418646198176219,74.1135014806344117,66.2793330800256228],"luv":[64.4418646198176219,29.8142337654579457,67.8522112145111],"rgb":[0.733333333333333282,0.6,0],"xyz":[0.318837934233495934,0.333482016491941036,0.047575234714223362],"hpluv":[66.2793330800256228,145.938057142603384,64.4418646198176219],"hsluv":[66.2793330800256228,100.000000000002416,64.4418646198176219]},"#bb9911":{"lch":[64.4743890579801331,72.806990252212529,65.9899074816349],"luv":[64.4743890579801331,29.6249863695688624,66.5072778888794147],"rgb":[0.733333333333333282,0.6,0.0666666666666666657],"xyz":[0.319849599733133039,0.333886682691795889,0.0529033396789789917],"hpluv":[65.9899074816349,143.29306400111571,64.4743890579801331],"hsluv":[65.9899074816349,98.0367215419372542,64.4743890579801331]},"#bb9922":{"lch":[64.5346112536789,70.4161712525116599,65.4311312102869636],"luv":[64.5346112536789,29.2781077929992222,64.0408430450799671],"rgb":[0.733333333333333282,0.6,0.133333333333333331],"xyz":[0.321724957871610096,0.334636825947186689,0.0627802258749581843],"hpluv":[65.4311312102869636,138.458312961065701,64.5346112536789],"hsluv":[65.4311312102869636,94.4406497380354892,64.5346112536789]},"#bb9933":{"lch":[64.6335704733000398,66.566957174521292,64.4427367566729146],"luv":[64.6335704733000398,28.7178476591491503,60.0536844273559396],"rgb":[0.733333333333333282,0.6,0.2],"xyz":[0.324812708604067801,0.335871926240169816,0.0790423797325693345],"hpluv":[64.4427367566729146,130.689255588928205,64.6335704733000398],"hsluv":[64.4427367566729146,88.6394107340449153,64.6335704733000398]},"#bb9944":{"lch":[64.7760175449466828,61.1991201001527685,62.8442649593615386],"luv":[64.7760175449466828,27.9319304868930693,54.4530950480162872],"rgb":[0.733333333333333282,0.6,0.266666666666666663],"xyz":[0.329270703848286717,0.337655124337857382,0.102521154685455973],"hpluv":[62.8442649593615386,119.886494259466,64.7760175449466828],"hsluv":[62.8442649593615386,80.5164965868838607,64.7760175449466828]},"#bb9955":{"lch":[64.965753761967747,54.3684881208399204,60.3198292286154],"luv":[64.965753761967747,26.9209928274273445,47.235501963369849],"rgb":[0.733333333333333282,0.6,0.333333333333333315],"xyz":[0.335233117887648702,0.340040089953602243,0.133923201959429888],"hpluv":[60.3198292286154,106.194518749025775,64.965753761967747],"hsluv":[60.3198292286154,70.0945405394646883,64.965753761967747]},"#bb9966":{"lch":[65.2058459998609,46.2670609228556557,56.2614414361724258],"luv":[65.2058459998609,25.6969192719684436,38.4747874116176689],"rgb":[0.733333333333333282,0.6,0.4],"xyz":[0.342818113661156887,0.343074088263005561,0.17387084636657385],"hpluv":[56.2614414361724258,90.0377647384168,65.2058459998609],"hsluv":[56.2614414361724258,57.5177389460533064,65.2058459998609]},"#bb9977":{"lch":[65.4987393303808147,37.2952826673053153,49.3796729345645886],"luv":[65.4987393303808147,24.280853083902965,28.3086255892461871],"rgb":[0.733333333333333282,0.6,0.466666666666666674],"xyz":[0.352132126681358792,0.346799693471086357,0.222924648272971759],"hpluv":[49.3796729345645886,72.2537327682772172,65.4987393303808147],"hsluv":[49.3796729345645886,43.0302399575574199,65.4987393303808147]},"#bb9988":{"lch":[65.8463246780106601,28.3139420599436384,36.7022131699001193],"luv":[65.8463246780106601,22.7007755052872291,16.9220006628175241],"rgb":[0.733333333333333282,0.6,0.533333333333333326],"xyz":[0.363272543783302593,0.351255860311863954,0.281597511676543899],"hpluv":[36.7022131699001193,54.564242001153282,65.8463246780106601],"hsluv":[36.7022131699001193,26.9495650592517677,65.8463246780106601]},"#bb9999":{"lch":[66.2499853133799377,21.4719543680734333,12.1770506300627517],"luv":[66.2499853133799377,20.9888452793887552,4.52914983440691099],"rgb":[0.733333333333333282,0.6,0.6],"xyz":[0.376329507892375292,0.356478645955493112,0.350364189317661834],"hpluv":[12.1770506300627517,41.1268186121042731,66.2499853133799377],"hsluv":[12.1770506300627517,20.948078856310218,66.2499853133799377]},"#bb99aa":{"lch":[66.7106335886793715,21.0368039825091344,335.738246937474969],"luv":[66.7106335886793715,19.1787866223333445,-8.64414631375011489],"rgb":[0.733333333333333282,0.6,0.66666666666666663],"xyz":[0.391387200857627848,0.362501723141594234,0.429668038934660435],"hpluv":[335.738246937474969,40.0151105801343192,66.7106335886793715],"hsluv":[335.738246937474969,22.766845509204984,66.7106335886793715]},"#bb99bb":{"lch":[67.2287438260669887,28.2861274819753,307.715012949249171],"luv":[67.2287438260669887,17.3035955220760833,-22.3761165070024362],"rgb":[0.733333333333333282,0.6,0.733333333333333282],"xyz":[0.408524792964964523,0.369356759984529,0.519926024033302125],"hpluv":[307.715012949249171,53.3897422679679323,67.2287438260669887],"hsluv":[307.715012949249171,24.5905380245485432,67.2287438260669887]},"#bb99cc":{"lch":[67.8043844715017343,39.5775547497090656,292.889275489017223],"luv":[67.8043844715017343,15.393749985076461,-36.4611478338680044],"rgb":[0.733333333333333282,0.6,0.8],"xyz":[0.427817168408686221,0.377073710162017794,0.621532534703572281],"hpluv":[292.889275489017223,74.0679810995506642,67.8043844715017343],"hsluv":[292.889275489017223,42.0187450252511,67.8043844715017343]},"#bb99dd":{"lch":[68.4372510447458353,52.4777928084534082,284.879936967142157],"luv":[68.4372510447458353,13.4760025497769718,-50.718005612655638],"rgb":[0.733333333333333282,0.6,0.866666666666666696],"xyz":[0.449335493959319821,0.385681040382271301,0.734862382603578279],"hpluv":[284.879936967142157,97.3021261982971737,68.4372510447458353],"hsluv":[284.879936967142157,60.4059975969609724,68.4372510447458353]},"#bb99ee":{"lch":[69.1267004581107898,66.0165196934359244,280.096152477623832],"luv":[69.1267004581107898,11.5727364631099334,-64.9942508472035456],"rgb":[0.733333333333333282,0.6,0.933333333333333348],"xyz":[0.47314767422549453,0.395205912488741318,0.860273198672101502],"hpluv":[280.096152477623832,121.184234531677617,69.1267004581107898],"hsluv":[280.096152477623832,79.7264365589122548,69.1267004581107898]},"#bb99ff":{"lch":[69.8717866786541,79.7596884688517207,276.986638727898821],"luv":[69.8717866786541,9.70179942494587877,-79.1674364405365765],"rgb":[0.733333333333333282,0.6,1],"xyz":[0.499318722635325951,0.405674331852674042,0.998107386963883347],"hpluv":[276.986638727898821,144.850809586534439,69.8717866786541],"hsluv":[276.986638727898821,99.9999999999980247,69.8717866786541]},"#880000":{"lch":[27.3946073685119416,92.1289276169810876,12.1770506300617765],"luv":[27.3946073685119416,90.0560691570773,19.4330571920800175],"rgb":[0.533333333333333326,0,0],"xyz":[0.101531161901381561,0.0523520053554009795,0.00475927321412716],"hpluv":[12.1770506300617765,426.746789183125316,27.3946073685119416],"hsluv":[12.1770506300617765,100.000000000002245,27.3946073685119416]},"#880011":{"lch":[27.5061298630582485,89.4551794237446529,10.4692299831444977],"luv":[27.5061298630582485,87.9659862388495242,16.254672889999533],"rgb":[0.533333333333333326,0,0.0666666666666666657],"xyz":[0.10254282740101868,0.0527566715552558324,0.0100873781788827915],"hpluv":[10.4692299831444977,412.68181181873,27.5061298630582485],"hsluv":[10.4692299831444977,99.9999999999965,27.5061298630582485]},"#880022":{"lch":[27.711363673312789,85.0234292319238421,7.23413932290422057],"luv":[27.711363673312789,84.3466296586470463,10.7065206104973338],"rgb":[0.533333333333333326,0,0.133333333333333331],"xyz":[0.104418185539495709,0.0535068148106466537,0.0199642643748619876],"hpluv":[7.23413932290422057,389.331950846774873,27.711363673312789],"hsluv":[7.23413932290422057,99.9999999999967,27.711363673312789]},"#880033":{"lch":[28.0451389930846,79.0521177396887396,1.75350406004841131],"luv":[28.0451389930846,79.0150993176991392,2.41896650323101259],"rgb":[0.533333333333333326,0,0.2],"xyz":[0.107505936271953442,0.0547419151036297666,0.0362264182324731343],"hpluv":[1.75350406004841131,357.680479105960103,28.0451389930846],"hsluv":[1.75350406004841131,99.9999999999969589,28.0451389930846]},"#880044":{"lch":[28.5182895144164306,72.8806899851902585,353.674121255230034],"luv":[28.5182895144164306,72.4369406321056459,-8.0302306678086488],"rgb":[0.533333333333333326,0,0.266666666666666663],"xyz":[0.111963931516172316,0.0565251132013173396,0.0597051931853597728],"hpluv":[353.674121255230034,324.286096087098713,28.5182895144164306],"hsluv":[353.674121255230034,99.9999999999972857,28.5182895144164306]},"#880055":{"lch":[29.1358047874334787,68.1690091719341922,343.056201782139055],"luv":[29.1358047874334787,65.2098664506571453,-19.866734230132252],"rgb":[0.533333333333333326,0,0.333333333333333315],"xyz":[0.117926345555534315,0.0589100788170621725,0.0911072404593336743],"hpluv":[343.056201782139055,296.892542908362316,29.1358047874334787],"hsluv":[343.056201782139055,99.9999999999977405,29.1358047874334787]},"#880066":{"lch":[29.8977347275108087,66.3157421691867768,330.790160549998632],"luv":[29.8977347275108087,57.8829185884671915,-32.3627161272186115],"rgb":[0.533333333333333326,0,0.4],"xyz":[0.125511341329042486,0.0619440771264654841,0.13105488486647765],"hpluv":[330.790160549998632,281.460643767249167,29.8977347275108087],"hsluv":[330.790160549998632,99.9999999999981384,29.8977347275108087]},"#880077":{"lch":[30.8000475559674527,67.8890879971799,318.512376228514142],"luv":[30.8000475559674527,50.8556366042998462,-44.9736866918894549],"rgb":[0.533333333333333326,0,0.466666666666666674],"xyz":[0.13482535434924442,0.0656696823345463,0.180108686772875559],"hpluv":[318.512376228514142,279.697068124812404,30.8000475559674527],"hsluv":[318.512376228514142,99.9999999999984652,30.8000475559674527]},"#880088":{"lch":[31.8355421357531156,72.5162027692933862,307.715012949243601],"luv":[31.8355421357531156,44.3606514294377803,-57.3649045046986288],"rgb":[0.533333333333333326,0,0.533333333333333326],"xyz":[0.14596577145118822,0.0701258491753239,0.238781550176447727],"hpluv":[307.715012949243601,289.042783730483279,31.8355421357531156],"hsluv":[307.715012949243601,99.9999999999987921,31.8355421357531156]},"#880099":{"lch":[32.9947769935272675,79.3376809512942,299.026215263792551],"luv":[32.9947769935272675,38.4954159686478121,-69.3726932454703444],"rgb":[0.533333333333333326,0,0.6],"xyz":[0.159022735560260947,0.0753486348189530558,0.307548227817565634],"hpluv":[299.026215263792551,305.122076286487129,32.9947769935272675],"hsluv":[299.026215263792551,99.9999999999991189,32.9947769935272675]},"#8800aa":{"lch":[34.2669429307518527,87.5167556566874651,292.341813883439613],"luv":[34.2669429307518527,33.2678552259606306,-80.9470958672197298],"rgb":[0.533333333333333326,0,0.66666666666666663],"xyz":[0.174080428525513475,0.0813717120050541642,0.386852077434564234],"hpluv":[292.341813883439613,324.082197305514,34.2669429307518527],"hsluv":[292.341813883439613,99.9999999999993605,34.2669429307518527]},"#8800bb":{"lch":[35.6406160405817047,96.4510237672048589,287.271351738157534],"luv":[35.6406160405817047,28.6360630376966157,-92.1019862947753296],"rgb":[0.533333333333333326,0,0.733333333333333282],"xyz":[0.19121802063285015,0.0882267488479889228,0.477110062533206],"hpluv":[287.271351738157534,343.400533998367337,35.6406160405817047],"hsluv":[287.271351738157534,99.999999999999531,35.6406160405817047]},"#8800cc":{"lch":[37.1043554501127346,105.765919518381835,283.413875530142832],"luv":[37.1043554501127346,24.5359458020369345,-102.880596300606314],"rgb":[0.533333333333333326,0,0.8],"xyz":[0.210510396076571876,0.0959436990254777244,0.578716573203476137],"hpluv":[283.413875530142832,361.709723992276565,37.1043554501127346],"hsluv":[283.413875530142832,99.9999999999998,37.1043554501127346]},"#8800dd":{"lch":[38.6471386159700145,115.245648848701009,280.44740978906907],"luv":[38.6471386159700145,20.8978330626497737,-113.335079087825761],"rgb":[0.533333333333333326,0,0.866666666666666696],"xyz":[0.23202872162720542,0.104551029245731258,0.692046421103482134],"hpluv":[280.44740978906907,378.39598449622531,38.6471386159700145],"hsluv":[280.44740978906907,99.9999999999998863,38.6471386159700145]},"#8800ee":{"lch":[40.258648150966188,124.7713904223,278.13468614008417],"luv":[40.258648150966188,17.6552208530237813,-123.515962711485074],"rgb":[0.533333333333333326,0,0.933333333333333348],"xyz":[0.255840901893380157,0.114075901352201275,0.817457237172005358],"hpluv":[278.13468614008417,393.273926011730225,40.258648150966188],"hsluv":[278.13468614008417,99.9999999999999858,40.258648150966188]},"#8800ff":{"lch":[41.9294357887748674,134.280036872974534,276.305800055850909],"luv":[41.9294357887748674,14.7486383519278057,-133.467621426964229],"rgb":[0.533333333333333326,0,1],"xyz":[0.282011950303211578,0.124544320716133985,0.955291425463787203],"hpluv":[276.305800055850909,406.37947026199555,41.9294357887748674],"hsluv":[276.305800055850909,100.000000000000171,41.9294357887748674]},"#aa0000":{"lch":[35.0982840320529732,118.036634932245676,12.1770506300617765],"luv":[35.0982840320529732,115.380864984340803,24.8978549596859438],"rgb":[0.66666666666666663,0,0],"xyz":[0.165771937912151307,0.08547615548595483,0.00777055958963192815],"hpluv":[12.1770506300617765,426.746789183125145,35.0982840320529732],"hsluv":[12.1770506300617765,100.000000000002217,35.0982840320529732]},"#aa0011":{"lch":[35.178794604810534,115.883637018633408,11.1343823918443601],"luv":[35.178794604810534,113.702354404428164,22.3783808966644813],"rgb":[0.66666666666666663,0,0.0666666666666666657],"xyz":[0.166783603411788439,0.0858808216858096829,0.0130986645543875596],"hpluv":[11.1343823918443601,418.004049663923468,35.178794604810534],"hsluv":[11.1343823918443601,99.9999999999964473,35.178794604810534]},"#aa0022":{"lch":[35.327373324777,112.154849255399441,9.17432067350408431],"luv":[35.327373324777,110.720144559212301,17.8818287736043224],"rgb":[0.66666666666666663,0,0.133333333333333331],"xyz":[0.16865896155026544,0.0866309649412005,0.0229755507503667557],"hpluv":[9.17432067350408431,402.852473647417696,35.327373324777],"hsluv":[9.17432067350408431,99.9999999999965752,35.327373324777]},"#aa0033":{"lch":[35.5701485089931921,106.706281850707128,5.8788523359554592],"luv":[35.5701485089931921,106.14508040487398,10.9294323844098908],"rgb":[0.66666666666666663,0,0.2],"xyz":[0.171746712282723202,0.0878660652341836101,0.0392377046079779],"hpluv":[5.8788523359554592,380.665602767339294,35.5701485089931921],"hsluv":[5.8788523359554592,99.9999999999967741,35.5701485089931921]},"#aa0044":{"lch":[35.9166782648329104,100.198740700315142,1.0062433800652546],"luv":[35.9166782648329104,100.183288799466339,1.75962588401964615],"rgb":[0.66666666666666663,0,0.266666666666666663],"xyz":[0.176204707526942062,0.0896492633318711901,0.0627164795608645409],"hpluv":[1.0062433800652546,354.001763490246503,35.9166782648329104],"hsluv":[1.0062433800652546,99.999999999997,35.9166782648329104]},"#aa0055":{"lch":[36.3730398367095,93.6502679946689369,354.384147096436777],"luv":[36.3730398367095,93.2007806216229113,-9.16445235643848832],"rgb":[0.66666666666666663,0,0.333333333333333315],"xyz":[0.182167121566304047,0.092034228947616023,0.0941185268348384424],"hpluv":[354.384147096436777,326.714758289773386,36.3730398367095],"hsluv":[354.384147096436777,99.9999999999973,36.3730398367095]},"#aa0066":{"lch":[36.9423385777606228,88.2319659172366926,346.039412913085584],"luv":[36.9423385777606228,85.6257622699194,-21.2863488018886251],"rgb":[0.66666666666666663,0,0.4],"xyz":[0.189752117339812232,0.0950682272570193415,0.134066171241982418],"hpluv":[346.039412913085584,303.068568849792825,36.9423385777606228],"hsluv":[346.039412913085584,99.9999999999976126,36.9423385777606228]},"#aa0077":{"lch":[37.6250775946346891,84.9907340508927689,336.365700313169],"luv":[37.6250775946346891,77.8619577045834319,-34.0725757306260348],"rgb":[0.66666666666666663,0,0.466666666666666674],"xyz":[0.199066130360014137,0.0987938324651001509,0.183119973148380327],"hpluv":[336.365700313169,286.637826777930513,37.6250775946346891],"hsluv":[336.365700313169,99.9999999999979536,37.6250775946346891]},"#aa0088":{"lch":[38.4195160158879432,84.5572797483387717,326.161033183527252],"luv":[38.4195160158879432,70.2337789048813761,-47.0866208086656215],"rgb":[0.66666666666666663,0,0.533333333333333326],"xyz":[0.210206547461958,0.103249999305877749,0.241792836551952495],"hpluv":[326.161033183527252,279.279102381419364,38.4195160158879432],"hsluv":[326.161033183527252,99.9999999999982379,38.4195160158879432]},"#aa0099":{"lch":[39.3220484546604681,86.9871636461465272,316.374304421046759],"luv":[39.3220484546604681,62.9667468975572859,-60.0162929906574334],"rgb":[0.66666666666666663,0,0.6],"xyz":[0.223263511571030693,0.108472784949506906,0.310559514193070374],"hpluv":[316.374304421046759,280.710309296009257,39.3220484546604681],"hsluv":[316.374304421046759,99.9999999999986,39.3220484546604681]},"#aa00aa":{"lch":[40.3276007574525863,91.8597353001339627,307.715012949243601],"luv":[40.3276007574525863,56.1937545325413,-72.6668626056414411],"rgb":[0.66666666666666663,0,0.66666666666666663],"xyz":[0.238321204536283249,0.114495862135608,0.389863363810069],"hpluv":[307.715012949243601,289.042783730483393,40.3276007574525863],"hsluv":[307.715012949243601,99.9999999999988205,40.3276007574525863]},"#aa00bb":{"lch":[41.4300227805658849,98.5480850422065089,300.471226581677797],"luv":[41.4300227805658849,49.974285465742625,-84.9370111180893304],"rgb":[0.66666666666666663,0,0.733333333333333282],"xyz":[0.255458796643619868,0.121350898978542759,0.480121348908710721],"hpluv":[300.471226581677797,301.836908489583834,41.4300227805658849],"hsluv":[300.471226581677797,99.9999999999990621,41.4300227805658849]},"#aa00cc":{"lch":[42.6224565622471445,106.453892931925211,294.601049164416338],"luv":[42.6224565622471445,44.3164832708711813,-96.7909119228886681],"rgb":[0.66666666666666663,0,0.8],"xyz":[0.274751172087341622,0.129067849156031561,0.581727859578980877],"hpluv":[294.601049164416338,316.929304470761622,42.6224565622471445],"hsluv":[294.601049164416338,99.9999999999992895,42.6224565622471445]},"#aa00dd":{"lch":[43.8976622887243266,115.112632227118652,289.907671140995035],"luv":[43.8976622887243266,39.1964773946494063,-108.233794436426436],"rgb":[0.66666666666666663,0,0.866666666666666696],"xyz":[0.296269497637975165,0.137675179376285095,0.695057707478986875],"hpluv":[289.907671140995035,332.752186796280228,43.8976622887243266],"hsluv":[289.907671140995035,99.9999999999994174,43.8976622887243266]},"#aa00ee":{"lch":[45.2482911917969233,124.202454763835647,286.162342623679535],"luv":[45.2482911917969233,34.5729825657367655,-119.293581746345012],"rgb":[0.66666666666666663,0,0.933333333333333348],"xyz":[0.320081677904149875,0.14720005148275514,0.820468523547510098],"hpluv":[286.162342623679535,348.311106794177135,45.2482911917969233],"hsluv":[286.162342623679535,99.9999999999996589,45.2482911917969233]},"#aa00ff":{"lch":[46.667101462293175,133.514790614533382,283.159905061129905],"luv":[46.667101462293175,30.397247590160724,-130.008486845225434],"rgb":[0.66666666666666663,0,1],"xyz":[0.346252726313981296,0.157668470846687836,0.958302711839291943],"hpluv":[283.159905061129905,363.042841924949244,46.667101462293175],"hsluv":[283.159905061129905,99.9999999999998153,46.667101462293175]},"#881100":{"lch":[28.4751123640698864,88.1761994811112,13.8943544232398857],"luv":[28.4751123640698864,85.5961768878489124,21.1739617718743069],"rgb":[0.533333333333333326,0.0666666666666666657,0],"xyz":[0.103535562162309969,0.0563608058772578496,0.00542740663443661096],"hpluv":[13.8943544232398857,392.939109149716501,28.4751123640698864],"hsluv":[13.8943544232398857,100.000000000002331,28.4751123640698864]},"#881111":{"lch":[28.5813012406410962,85.6429421929893522,12.1770506300617782],"luv":[28.5813012406410962,83.7160154193071548,18.0649469909557752],"rgb":[0.533333333333333326,0.0666666666666666657,0.0666666666666666657],"xyz":[0.104547227661947087,0.0567654720771127,0.0107555115991922433],"hpluv":[12.1770506300617782,380.232213605760478,28.5813012406410962],"hsluv":[12.1770506300617782,89.1001931926906536,28.5813012406410962]},"#881122":{"lch":[28.776819878520115,81.4294437186752589,8.91447414891876377],"luv":[28.776819878520115,80.445837197505071,12.6183034487767767],"rgb":[0.533333333333333326,0.0666666666666666657,0.133333333333333331],"xyz":[0.106422585800424116,0.0575156153325035238,0.0206323977951714393],"hpluv":[8.91447414891876377,359.069069298387092,28.776819878520115],"hsluv":[8.91447414891876377,89.5522119422979,28.776819878520115]},"#881133":{"lch":[29.0950676619922959,75.7256767264573227,3.35964558590209394],"luv":[29.0950676619922959,75.5955308554484162,4.43777313107212557],"rgb":[0.533333333333333326,0.0666666666666666657,0.2],"xyz":[0.10951033653288185,0.0587507156254866367,0.0368945516527825826],"hpluv":[3.35964558590209394,330.265430862114329,29.0950676619922959],"hsluv":[3.35964558590209394,90.2199940579986475,29.0950676619922959]},"#881144":{"lch":[29.5467689283324617,69.8105982852884779,355.112641815866198],"luv":[29.5467689283324617,69.5567752183087435,-5.94765955478224484],"rgb":[0.533333333333333326,0.0666666666666666657,0.266666666666666663],"xyz":[0.113968331777100723,0.0605339137231742097,0.0603733266056692211],"hpluv":[355.112641815866198,299.81315922456514,29.5467689283324617],"hsluv":[355.112641815866198,91.0462468049379083,29.5467689283324617]},"#881155":{"lch":[30.1372440361953267,65.3247498846549,344.189828060851937],"luv":[30.1372440361953267,62.8534910411243928,-17.7977979378353552],"rgb":[0.533333333333333326,0.0666666666666666657,0.333333333333333315],"xyz":[0.119930745816462722,0.0629188793389190426,0.0917753738796431295],"hpluv":[344.189828060851937,275.05120204756264,30.1372440361953267],"hsluv":[344.189828060851937,91.9552565263170294,30.1372440361953267]},"#881166":{"lch":[30.8672249177773494,63.7021552959616173,331.50461515751158],"luv":[30.8672249177773494,55.9849923977636479,-30.3915319714745138],"rgb":[0.533333333333333326,0.0666666666666666657,0.4],"xyz":[0.127515741589970893,0.0659528776483223611,0.131723018286787091],"hpluv":[331.50461515751158,261.876101180723595,30.8672249177773494],"hsluv":[331.50461515751158,92.8754029221989299,30.8672249177773494]},"#881177":{"lch":[31.7336031237729514,65.5512880923603376,318.81152503011009],"luv":[31.7336031237729514,49.3304506912780525,-43.1680206305895737],"rgb":[0.533333333333333326,0.0666666666666666657,0.466666666666666674],"xyz":[0.136829754610172827,0.0696784828564031705,0.180776820193185],"hpluv":[318.81152503011009,262.120610410187965,31.7336031237729514],"hsluv":[318.81152503011009,93.7528273751248094,31.7336031237729514]},"#881188":{"lch":[32.7302234117729114,70.4946015177073377,307.715012949243658],"luv":[32.7302234117729114,43.1239685223607268,-55.7656900075914663],"rgb":[0.533333333333333326,0.0666666666666666657,0.533333333333333326],"xyz":[0.147970171712116627,0.0741346496971807684,0.239449683596757168],"hpluv":[307.715012949243658,273.304143969878908,32.7302234117729114],"hsluv":[307.715012949243658,94.5549099834012736,32.7302234117729114]},"#881199":{"lch":[33.8487030992268245,77.6382380820710836,298.861624073140206],"luv":[33.8487030992268245,37.4756592651389795,-67.9946393117248249],"rgb":[0.533333333333333326,0.0666666666666666657,0.6],"xyz":[0.161027135821189354,0.0793574353408099259,0.308216361237875103],"hpluv":[298.861624073140206,291.053592363859707,33.8487030992268245],"hsluv":[298.861624073140206,95.267111116431,33.8487030992268245]},"#8811aa":{"lch":[35.0792182273937954,86.1162494337963551,292.107316515455238],"luv":[35.0792182273937954,32.4092110837954692,-79.7850327659882623],"rgb":[0.533333333333333326,0.0666666666666666657,0.66666666666666663],"xyz":[0.176084828786441883,0.0853805125269110343,0.387520210854873703],"hpluv":[292.107316515455238,311.511817997128389,35.0792182273937954],"hsluv":[292.107316515455238,95.8874450484264571,35.0792182273937954]},"#8811bb":{"lch":[36.4111998559147381,95.3124415598142,287.019214731984619],"luv":[36.4111998559147381,27.8972267898096504,-91.1383906678789515],"rgb":[0.533333333333333326,0.0666666666666666657,0.733333333333333282],"xyz":[0.193222420893778557,0.0922355493698457929,0.47777819595351545],"hpluv":[287.019214731984619,332.16504711372977,36.4111998559147381],"hsluv":[287.019214731984619,96.4212920970111753,36.4111998559147381]},"#8811cc":{"lch":[37.8339039869932847,104.849214202707898,283.169050576302368],"luv":[37.8339039869932847,23.8872658659353974,-102.091900993053514],"rgb":[0.533333333333333326,0.0666666666666666657,0.8],"xyz":[0.212514796337500284,0.0999524995473346,0.579384706623785606],"hpluv":[283.169050576302368,351.660305548048939,37.8339039869932847],"hsluv":[283.169050576302368,96.8775739500717776,37.8339039869932847]},"#8811dd":{"lch":[39.3368423655390274,114.513051177954694,280.22024610097435],"luv":[39.3368423655390274,20.3183376083265372,-112.696069349906494],"rgb":[0.533333333333333326,0.0666666666666666657,0.866666666666666696],"xyz":[0.234033121888133827,0.108559829767588129,0.692714554523791604],"hpluv":[280.22024610097435,369.398236331583689,39.3368423655390274],"hsluv":[280.22024610097435,97.2663289333616348,39.3368423655390274]},"#8811ee":{"lch":[40.9100807353410261,124.189527798253138,277.928390028110698],"luv":[40.9100807353410261,17.130123009315259,-123.002429652583771],"rgb":[0.533333333333333326,0.0666666666666666657,0.933333333333333348],"xyz":[0.257845302154308564,0.118084701874058146,0.818125370592314827],"hpluv":[277.928390028110698,385.206818333834917,40.9100807353410261],"hsluv":[277.928390028110698,97.5973562787359867,40.9100807353410261]},"#8811ff":{"lch":[42.5444231432324926,133.820472646418182,276.120297984259253],"luv":[42.5444231432324926,14.2674470621751119,-133.057727523202459],"rgb":[0.533333333333333326,0.0666666666666666657,1],"xyz":[0.28401635056414,0.128553121237990842,0.955959558884096672],"hpluv":[276.120297984259253,399.134479754608662,42.5444231432324926],"hsluv":[276.120297984259253,99.9999999999993605,42.5444231432324926]},"#aa1100":{"lch":[35.8849415951509485,114.659477700983,13.2232466646238507],"luv":[35.8849415951509485,111.619416231509064,26.2278810962561089],"rgb":[0.66666666666666663,0.0666666666666666657,0],"xyz":[0.167776338173079714,0.0894849560078117,0.00843869300994137816],"hpluv":[13.2232466646238507,405.449754626827882,35.8849415951509485],"hsluv":[13.2232466646238507,100.000000000002245,35.8849415951509485]},"#aa1111":{"lch":[35.9630348414680086,112.584844162769954,12.1770506300617871],"luv":[35.9630348414680086,110.051736997450746,23.747890832642895],"rgb":[0.66666666666666663,0.0666666666666666657,0.0666666666666666657],"xyz":[0.168788003672716846,0.089889622207666553,0.0137667979746970096],"hpluv":[12.1770506300617871,397.249101663635656,35.9630348414680086],"hsluv":[12.1770506300617871,93.0877775141683514,35.9630348414680086]},"#aa1122":{"lch":[36.1071812157442409,108.986817867719594,10.2082214608018411],"luv":[36.1071812157442409,107.261576994584843,19.3152936702042],"rgb":[0.66666666666666663,0.0666666666666666657,0.133333333333333331],"xyz":[0.170663361811193848,0.0906397654630573674,0.0236436841706762074],"hpluv":[10.2082214608018411,383.018466712830786,36.1071812157442409],"hsluv":[10.2082214608018411,93.272361347425246,36.1071812157442409]},"#aa1133":{"lch":[36.3427932754706546,103.718469067724868,6.89182233030552727],"luv":[36.3427932754706546,102.969049051934846,12.4457126390109512],"rgb":[0.66666666666666663,0.0666666666666666657,0.2],"xyz":[0.173751112543651609,0.0918748657560404802,0.0399058380282873507],"hpluv":[6.89182233030552727,362.140519718911037,36.3427932754706546],"hsluv":[6.89182233030552727,93.5557024333493388,36.3427932754706546]},"#aa1144":{"lch":[36.6792659124992824,97.4113439982971698,1.97455903872184],"luv":[36.6792659124992824,97.3535035649005778,3.35637947697775552],"rgb":[0.66666666666666663,0.0666666666666666657,0.266666666666666663],"xyz":[0.178209107787870469,0.0936580638537280602,0.0633846129811739822],"hpluv":[1.97455903872184,336.99870087691761,36.6792659124992824],"hsluv":[1.97455903872184,93.9250914747756696,36.6792659124992824]},"#aa1155":{"lch":[37.1226754299384396,91.055498296574811,355.267689161716703],"luv":[37.1226754299384396,90.7450919896636634,-7.51212685096688926],"rgb":[0.66666666666666663,0.0666666666666666657,0.333333333333333315],"xyz":[0.184171521827232454,0.0960430294694729,0.0947866602551479],"hpluv":[355.267689161716703,311.247759321881176,37.1226754299384396],"hsluv":[355.267689161716703,94.3576556410013154,37.1226754299384396]},"#aa1166":{"lch":[37.6762679798416,85.8108023849569577,346.783206271719791],"luv":[37.6762679798416,83.5378398512485205,-19.6194576616503156],"rgb":[0.66666666666666663,0.0666666666666666657,0.4],"xyz":[0.191756517600740639,0.0990770277788762116,0.134734304662291859],"hpluv":[346.783206271719791,289.010360822200312,37.6762679798416],"hsluv":[346.783206271719791,94.8263018378468558,37.6762679798416]},"#aa1177":{"lch":[38.3408051028578285,82.7345113545946163,336.916515476294876],"luv":[38.3408051028578285,76.110335477500783,-32.4378822148708],"rgb":[0.66666666666666663,0.0666666666666666657,0.466666666666666674],"xyz":[0.201070530620942545,0.102802632986957021,0.183788106568689769],"hpluv":[336.916515476294876,273.819772016881302,38.3408051028578285],"hsluv":[336.916515476294876,95.3051408978498387,38.3408051028578285]},"#aa1188":{"lch":[39.1148927869010379,82.477083595297529,326.495944929629673],"luv":[39.1148927869010379,68.7732486834780445,-45.5270203714912753],"rgb":[0.66666666666666663,0.0666666666666666657,0.533333333333333326],"xyz":[0.212210947722886401,0.107258799827734619,0.242460969972261936],"hpluv":[326.495944929629673,267.565723971153261,39.1148927869010379],"hsluv":[326.495944929629673,95.7730681487448,39.1148927869010379]},"#aa1199":{"lch":[39.9953287808464424,85.1038505069809617,316.515705271857257],"luv":[39.9953287808464424,61.7482074461545665,-58.5647013848890552],"rgb":[0.66666666666666663,0.0666666666666666657,0.6],"xyz":[0.2252679118319591,0.112481585471363776,0.311227647613379843],"hpluv":[316.515705271857257,270.00963724100518,39.9953287808464424],"hsluv":[316.515705271857257,96.2151887572794,39.9953287808464424]},"#aa11aa":{"lch":[40.9774666162921406,90.1875437006381588,307.715012949243601],"luv":[40.9774666162921406,55.1708175083225498,-71.3440532505540261],"rgb":[0.66666666666666663,0.0666666666666666657,0.66666666666666663],"xyz":[0.240325604797211656,0.118504662657464871,0.390531497230378444],"hpluv":[307.715012949243601,279.28060733669264,40.9774666162921406],"hsluv":[307.715012949243601,96.6225842874192864,40.9774666162921406]},"#aa11bb":{"lch":[42.0555802442747719,97.087212137786878,300.384453602166161],"luv":[42.0555802442747719,49.106684193967304,-83.7523750598249705],"rgb":[0.66666666666666663,0.0666666666666666657,0.733333333333333282],"xyz":[0.257463196904548275,0.12535969950039963,0.48078948232902019],"hpluv":[300.384453602166161,292.939359498794147,42.0555802442747719],"hsluv":[300.384453602166161,96.9911870522472697,42.0555802442747719]},"#aa11cc":{"lch":[43.2232098485165395,105.192683835863036,294.469145625450437],"luv":[43.2232098485165395,43.5711419401365,-95.7447456658814247],"rgb":[0.66666666666666663,0.0666666666666666657,0.8],"xyz":[0.276755572348270029,0.133076649677888431,0.582395992999290346],"hpluv":[294.469145625450437,308.821726609797679,43.2232098485165395],"hsluv":[294.469145625450437,97.3204020480748255,43.2232098485165395]},"#aa11dd":{"lch":[44.4734721926781518,114.032755796715193,289.757274940509092],"luv":[44.4734721926781518,38.5472014936014489,-107.320001172218454],"rgb":[0.66666666666666663,0.0666666666666666657,0.866666666666666696],"xyz":[0.298273897898903573,0.141683979898141965,0.695725840899296344],"hpluv":[289.757274940509092,325.362808980276498,44.4734721926781518],"hsluv":[289.757274940509092,97.611854654502622,44.4734721926781518]},"#aa11ee":{"lch":[45.7993244881172,123.283094749558884,286.008743686799619],"luv":[45.7993244881172,33.9995108001485136,-118.502129585840351],"rgb":[0.66666666666666663,0.0666666666666666657,0.933333333333333348],"xyz":[0.322086078165078282,0.151208852004612,0.821136656967819567],"hpluv":[286.008743686799619,341.573194884792258,45.7993244881172],"hsluv":[286.008743686799619,97.8684161167955153,45.7993244881172]},"#aa11ff":{"lch":[47.1937769411101868,132.735165800167636,283.011169167098501],"luv":[47.1937769411101868,29.8841269734434611,-129.327348983241365],"rgb":[0.66666666666666663,0.0666666666666666657,1],"xyz":[0.348257126574909703,0.161677271368544706,0.958970845259601412],"hpluv":[283.011169167098501,356.89510187446183,47.1937769411101868],"hsluv":[283.011169167098501,99.9999999999993321,47.1937769411101868]},"#882200":{"lch":[30.3496916993887922,81.7292062801124786,17.2000641303745212],"luv":[30.3496916993887922,78.0741152618852254,24.1680716080335465],"rgb":[0.533333333333333326,0.133333333333333331,0],"xyz":[0.107251185897077911,0.0637920533467938311,0.00666594787935922105],"hpluv":[17.2000641303745212,341.713647377264522,30.3496916993887922],"hsluv":[17.2000641303745212,100.000000000002359,30.3496916993887922]},"#882211":{"lch":[30.4474919309639347,79.3871193031655338,15.4743840495427136],"luv":[30.4474919309639347,76.5093230935452908,21.181080969170015],"rgb":[0.533333333333333326,0.133333333333333331,0.0666666666666666657],"xyz":[0.108262851396715029,0.064196719546648684,0.0119940528441148525],"hpluv":[15.4743840495427136,330.855109199112462,30.4474919309639347],"hsluv":[15.4743840495427136,90.2707057474005,30.4474919309639347]},"#882222":{"lch":[30.6277058928754826,75.4670009360781648,12.1770506300618102],"luv":[30.6277058928754826,73.7690281561900321,15.9185022906448506],"rgb":[0.533333333333333326,0.133333333333333331,0.133333333333333331],"xyz":[0.110138209535192058,0.0649468628020395,0.0218709390400940486],"hpluv":[12.1770506300618102,312.666930334371557,30.6277058928754826],"hsluv":[12.1770506300618102,73.2675530922876277,30.6277058928754826]},"#882233":{"lch":[30.9214262019897674,70.1124269978110135,6.50693872003014],"luv":[30.9214262019897674,69.6607724946186266,7.94538828354938],"rgb":[0.533333333333333326,0.133333333333333331,0.2],"xyz":[0.113225960267649792,0.0661819630950226112,0.0381330928977051953],"hpluv":[6.50693872003014,287.723152758323693,30.9214262019897674],"hsluv":[6.50693872003014,74.8097141082451458,30.9214262019897674]},"#882244":{"lch":[31.3391119188553589,64.5127804411509,357.965654494967],"luv":[31.3391119188553589,64.472119792654567,-2.29011128326569047],"rgb":[0.533333333333333326,0.133333333333333331,0.266666666666666663],"xyz":[0.117683955511868665,0.0679651611927101912,0.0616118678505918338],"hpluv":[357.965654494967,261.215173773686786,31.3391119188553589],"hsluv":[357.965654494967,76.7464797952550839,31.3391119188553589]},"#882255":{"lch":[31.8864840032734449,60.2907989794282599,346.464164292394514],"luv":[31.8864840032734449,58.6161449596217778,-14.1112717942230379],"rgb":[0.533333333333333326,0.133333333333333331,0.333333333333333315],"xyz":[0.123646369551230664,0.0703501268084550241,0.0930139151245657353],"hpluv":[346.464164292394514,239.929545755427228,31.8864840032734449],"hsluv":[346.464164292394514,78.9147131880069566,31.8864840032734449]},"#882266":{"lch":[32.565220274416383,58.9629659850378189,332.945096803324191],"luv":[32.565220274416383,52.5107124518348698,-26.8189566455043362],"rgb":[0.533333333333333326,0.133333333333333331,0.4],"xyz":[0.131231365324738836,0.0733841251178583426,0.132961559531709711],"hpluv":[332.945096803324191,229.754818264706444,32.565220274416383],"hsluv":[332.945096803324191,81.1505919454384923,32.565220274416383]},"#882277":{"lch":[33.3735533542235316,61.2256527964903086,319.411642653163199],"luv":[33.3735533542235316,46.4949769025583564,-39.8346291960518499],"rgb":[0.533333333333333326,0.133333333333333331,0.466666666666666674],"xyz":[0.140545378344940741,0.077109730325939152,0.18201536143810762],"hpluv":[319.411642653163199,232.79320602780777,33.3735533542235316],"hsluv":[319.411642653163199,83.3222334130424116,33.3735533542235316]},"#882288":{"lch":[34.3068967831130962,66.691064714973308,307.715012949243771],"luv":[34.3068967831130962,40.7972144472485709,-52.7568517461189046],"rgb":[0.533333333333333326,0.133333333333333331,0.533333333333333326],"xyz":[0.151685795446884597,0.0815658971667167498,0.240688224841679788],"hpluv":[307.715012949243771,246.675229855048,34.3068967831130962],"hsluv":[307.715012949243771,85.3421167175917,34.3068967831130962]},"#882299":{"lch":[35.3585028262625087,74.3915148492043699,298.539568373309862],"luv":[35.3585028262625087,35.5417034620318262,-65.3520068289902554],"rgb":[0.533333333333333326,0.133333333333333331,0.6],"xyz":[0.164742759555957297,0.0867886828103459074,0.309454902482797667],"hpluv":[298.539568373309862,266.973934190138948,35.3585028262625087],"hsluv":[298.539568373309862,87.1641407220543556,35.3585028262625087]},"#8822aa":{"lch":[36.5201138266519365,83.3993900511107142,291.653660077047903],"luv":[36.5201138266519365,30.7739719973965897,-77.5140045953036463],"rgb":[0.533333333333333326,0.133333333333333331,0.66666666666666663],"xyz":[0.179800452521209853,0.092811759996447,0.388758752099796268],"hpluv":[291.653660077047903,289.781114528802732,36.5201138266519365],"hsluv":[291.653660077047903,88.7734689989794532,36.5201138266519365]},"#8822bb":{"lch":[37.7825623664262196,93.0686060696910857,286.53575696187113],"luv":[37.7825623664262196,26.4885972028076893,-89.2195026548722],"rgb":[0.533333333333333326,0.133333333333333331,0.733333333333333282],"xyz":[0.196938044628546471,0.0996667968393817605,0.479016737198438],"hpluv":[286.53575696187113,312.57276028475934,37.7825623664262196],"hsluv":[286.53575696187113,90.1753980157506874,37.7825623664262196]},"#8822cc":{"lch":[39.1362858369643476,103.012880313051866,282.702767559286599],"luv":[39.1362858369643476,22.6518448072254479,-100.491529181421669],"rgb":[0.533333333333333326,0.133333333333333331,0.8],"xyz":[0.216230420072268226,0.107383747016870562,0.580623247868708225],"hpluv":[282.702767559286599,334.003678399645651,39.1362858369643476],"hsluv":[282.702767559286599,91.3862929083300628,39.1362858369643476]},"#8822dd":{"lch":[40.5717373677475379,113.020349666590874,279.789793007972776],"luv":[40.5717373677475379,19.2172965257181652,-111.374570495248548],"rgb":[0.533333333333333326,0.133333333333333331,0.866666666666666696],"xyz":[0.237748745622901769,0.115991077237124096,0.693953095768714223],"hpluv":[279.789793007972776,353.486121759760863,40.5717373677475379],"hsluv":[279.789793007972776,92.4273238443811209,40.5717373677475379]},"#8822ee":{"lch":[42.0796906219744145,122.982600065668066,277.538986095624125],"luv":[42.0796906219744145,16.1354126197819454,-121.919515986988074],"rgb":[0.533333333333333326,0.133333333333333331,0.933333333333333348],"xyz":[0.261560925889076534,0.125515949343594141,0.819363911837237446],"hpluv":[277.538986095624125,370.860397035002336,42.0796906219744145],"hsluv":[277.538986095624125,93.320628909539181,42.0796906219744145]},"#8822ff":{"lch":[43.6514473624058752,132.848943476626658,275.771185477405766],"luv":[43.6514473624058752,13.3587518063908028,-132.175585994657865],"rgb":[0.533333333333333326,0.133333333333333331,1],"xyz":[0.2877319742989079,0.135984368707526837,0.957198100129019291],"hpluv":[275.771185477405766,386.188007357759091,43.6514473624058752],"hsluv":[275.771185477405766,99.9999999999994,43.6514473624058752]},"#ffaa00":{"lch":[76.0766826449234799,103.646966048157225,46.9849230608437125],"luv":[76.0766826449234799,70.7070052858721,75.7839889059127785],"rgb":[1,0.66666666666666663,0],"xyz":[0.556131758114240538,0.500120923568095,0.0672444716650198171],"hpluv":[46.9849230608437125,173.218766512771339,76.0766826449234799],"hsluv":[46.9849230608437125,100.0000000000028,76.0766826449234799]},"#ffaa11":{"lch":[76.1015101579349533,102.726050652762069,46.6846637022245687],"luv":[76.1015101579349533,70.4714195905473275,74.7423608377930719],"rgb":[1,0.66666666666666663,0.0666666666666666657],"xyz":[0.557143423613877697,0.500525589767949919,0.0725725766297754538],"hpluv":[46.6846637022245687,171.896872437304751,76.1015101579349533],"hsluv":[46.6846637022245687,100.000000000002771,76.1015101579349533]},"#ffaa22":{"lch":[76.1474983763177,101.038792737361192,46.1176753587789605],"luv":[76.1474983763177,70.0380208569547591,72.8252241483965719],"rgb":[1,0.66666666666666663,0.133333333333333331],"xyz":[0.559018781752354643,0.501275733023340719,0.0824494628257546464],"hpluv":[46.1176753587789605,169.470349592440897,76.1474983763177],"hsluv":[46.1176753587789605,100.0000000000028,76.1474983763177]},"#ffaa33":{"lch":[76.2231174741888395,98.3169656691378577,45.1538509265191337],"luv":[76.2231174741888395,69.3336656617894533,69.7070193329597885],"rgb":[1,0.66666666666666663,0.2],"xyz":[0.56210653248481246,0.502510833316323846,0.0987116166833657827],"hpluv":[45.1538509265191337,165.543337136749699,76.2231174741888395],"hsluv":[45.1538509265191337,100.000000000002927,76.2231174741888395]},"#ffaa44":{"lch":[76.3320756204529118,94.5107446089494516,43.6926927141772694],"luv":[76.3320756204529118,68.3364903114306514,65.2870962629968119],"rgb":[1,0.66666666666666663,0.266666666666666663],"xyz":[0.56656452772903132,0.504294031414011412,0.122190391636252421],"hpluv":[43.6926927141772694,160.025535099593441,76.3320756204529118],"hsluv":[43.6926927141772694,100.000000000003,76.3320756204529118]},"#ffaa55":{"lch":[76.4774026026215,89.6489515946998807,41.6012791226812411],"luv":[76.4774026026215,67.0379860163697288,59.5217855318358247],"rgb":[1,0.66666666666666663,0.333333333333333315],"xyz":[0.572526941768393249,0.506678997029756162,0.153592438910226337],"hpluv":[41.6012791226812411,152.933128718005122,76.4774026026215],"hsluv":[41.6012791226812411,100.000000000003,76.4774026026215]},"#ffaa66":{"lch":[76.6616205587261,83.8466863985853905,38.6944265301345354],"luv":[76.6616205587261,65.4416029270402788,52.418159318716242],"rgb":[1,0.66666666666666663,0.4],"xyz":[0.58011193754190149,0.50971299533915948,0.193540083317370298],"hpluv":[38.6944265301345354,144.405277715469396,76.6616205587261],"hsluv":[38.6944265301345354,100.000000000003197,76.6616205587261]},"#ffaa77":{"lch":[76.8868341725165,77.3210793721064533,34.7099370327462324],"luv":[76.8868341725165,63.5614296008349058,44.0283315873505927],"rgb":[1,0.66666666666666663,0.466666666666666674],"xyz":[0.58942595056210334,0.513438600547240331,0.242593885223768208],"hpluv":[34.7099370327462324,134.738986801151128,76.8868341725165],"hsluv":[34.7099370327462324,100.000000000003354,76.8868341725165]},"#ffaa88":{"lch":[77.1547840912050873,70.4186738688562741,29.282319230158226],"luv":[77.1547840912050873,61.4205932059712723,34.4427112706728948],"rgb":[1,0.66666666666666663,0.533333333333333326],"xyz":[0.600566367664047251,0.517894767388017874,0.301266748627340375],"hpluv":[29.282319230158226,124.451835787871019,77.1547840912050873],"hsluv":[29.282319230158226,100.000000000003638,77.1547840912050873]},"#ffaa99":{"lch":[77.466881654564645,63.658531214354845,21.9370110659791244],"luv":[77.466881654564645,59.0493431107362383,23.7820031654092716],"rgb":[1,0.66666666666666663,0.6],"xyz":[0.613623331773119896,0.523117553031647087,0.370033426268458254],"hpluv":[21.9370110659791244,114.385173247539697,77.466881654564645],"hsluv":[21.9370110659791244,100.000000000003624,77.466881654564645]},"#ffaaaa":{"lch":[77.8242336850598,57.783013099698,12.1770506300621957],"luv":[77.8242336850598,56.482921905318662,12.1883606739193855],"rgb":[1,0.66666666666666663,0.66666666666666663],"xyz":[0.628681024738372507,0.529140630217748154,0.44933727588545691],"hpluv":[12.1770506300621957,105.841692205508735,77.8242336850598],"hsluv":[12.1770506300621957,100.000000000003837,77.8242336850598]},"#ffaabb":{"lch":[78.227662021793833,53.7597014753195,359.804273109779956],"luv":[78.227662021793833,53.7593877986938224,-0.183647012281759531],"rgb":[1,0.66666666666666663,0.733333333333333282],"xyz":[0.64581861684570907,0.535995667060682912,0.539595260984098601],"hpluv":[359.804273109779956,100.661858044669231,78.227662021793833],"hsluv":[359.804273109779956,100.000000000004135,78.227662021793833]},"#ffaacc":{"lch":[78.6777204654413254,52.5946111834740293,345.492217824016791],"luv":[78.6777204654413254,50.9175596191628586,-13.1755549397286202],"rgb":[1,0.66666666666666663,0.8],"xyz":[0.665110992289430825,0.543712617238171769,0.641201771654368757],"hpluv":[345.492217824016791,100.966318741741958,78.6777204654413254],"hsluv":[345.492217824016791,100.000000000004306,78.6777204654413254]},"#ffaadd":{"lch":[79.1747106956411244,54.8892328831665353,330.97422205899818],"luv":[79.1747106956411244,47.9952274547753177,-26.6324243745640352],"rgb":[1,0.66666666666666663,0.866666666666666696],"xyz":[0.686629317840064424,0.552319947458425275,0.754531619554374755],"hpluv":[330.97422205899818,108.36723319715793,79.1747106956411244],"hsluv":[330.97422205899818,100.000000000004704,79.1747106956411244]},"#ffaaee":{"lch":[79.718698064048283,60.5009523664383337,318.094564198374599],"luv":[79.718698064048283,45.0277239197174595,-40.4087777080146822],"rgb":[1,0.66666666666666663,0.933333333333333348],"xyz":[0.710441498106239133,0.561844819564895293,0.879942435622898],"hpluv":[318.094564198374599,123.247069988098687,79.718698064048283],"hsluv":[318.094564198374599,100.000000000004945,79.718698064048283]},"#ffaaff":{"lch":[80.3095277487323074,68.733917080261989,307.715012949245647],"luv":[80.3095277487323074,42.0468973903394,-54.3728772187255203],"rgb":[1,0.66666666666666663,1],"xyz":[0.736612546516070554,0.572313238928828,1.01777662391468],"hpluv":[307.715012949245647,144.979279509576116,80.3095277487323074],"hsluv":[307.715012949245647,100.000000000005301,80.3095277487323074]},"#aa2200":{"lch":[37.2831780533064929,108.910935722579069,15.2092016225530191],"luv":[37.2831780533064929,105.096262108869439,28.5721474641225],"rgb":[0.66666666666666663,0.133333333333333331,0],"xyz":[0.171491961907847656,0.0969162034773476816,0.00967723425486398912],"hpluv":[15.2092016225530191,370.67892165569458,37.2831780533064929],"hsluv":[15.2092016225530191,100.000000000002217,37.2831780533064929]},"#aa2211":{"lch":[37.3572350214345619,106.95640568906397,14.158492547926917],"luv":[37.3572350214345619,103.707370245599336,26.1620732103901794],"rgb":[0.66666666666666663,0.133333333333333331,0.0666666666666666657],"xyz":[0.172503627407484789,0.0973208696772025345,0.0150053392196196206],"hpluv":[14.158492547926917,363.305022455593,37.3572350214345619],"hsluv":[14.158492547926917,93.5777596020973732,37.3572350214345619]},"#aa2222":{"lch":[37.4939757158163331,103.55828406892158,12.1770506300617907],"luv":[37.4939757158163331,101.228270350344232,21.8438888748564],"rgb":[0.66666666666666663,0.133333333333333331,0.133333333333333331],"xyz":[0.17437898554596179,0.0980710129325933488,0.0248822254155988166],"hpluv":[12.1770506300617907,350.479546677114797,37.4939757158163331],"hsluv":[12.1770506300617907,82.128221128038831,37.4939757158163331]},"#aa2233":{"lch":[37.7176061419824791,98.5638584928897359,8.82735266140639],"luv":[37.7176061419824791,97.3963926843060506,15.125372494284127],"rgb":[0.66666666666666663,0.133333333333333331,0.2],"xyz":[0.177466736278419523,0.0993061132255764617,0.0411443792732099634],"hpluv":[8.82735266140639,331.598763076121088,37.7176061419824791],"hsluv":[8.82735266140639,82.8309253801110401,37.7176061419824791]},"#aa2244":{"lch":[38.0372287502177358,92.5577577991589209,3.83362915136278648],"luv":[38.0372287502177358,92.350650343690134,6.18836892123021798],"rgb":[0.66666666666666663,0.133333333333333331,0.266666666666666663],"xyz":[0.181924731522638411,0.101089311323264042,0.0646231542260966],"hpluv":[3.83362915136278648,308.775819843535,38.0372287502177358],"hsluv":[3.83362915136278648,83.7532195801290698,38.0372287502177358]},"#aa2255":{"lch":[38.4588905236098242,86.4856662057644172,356.973865768881865],"luv":[38.4588905236098242,86.3650670431288603,-4.56570407393633459],"rgb":[0.66666666666666663,0.133333333333333331,0.333333333333333315],"xyz":[0.187887145562000424,0.103474276939008875,0.0960252015000705],"hpluv":[356.973865768881865,285.355803984318584,38.4588905236098242],"hsluv":[356.973865768881865,84.8422496447961,38.4588905236098242]},"#aa2266":{"lch":[38.9860395203518237,81.4924101374980268,348.227712846231327],"luv":[38.9860395203518237,79.7783138580272464,-16.6262908668256522],"rgb":[0.66666666666666663,0.133333333333333331,0.4],"xyz":[0.195472141335508581,0.106508275248412193,0.135972845907214479],"hpluv":[348.227712846231327,265.245100213362434,38.9860395203518237],"hsluv":[348.227712846231327,86.0332228090823747,38.9860395203518237]},"#aa2277":{"lch":[39.619833929041036,78.6591168776988354,337.990195281021442],"luv":[39.619833929041036,72.9264197190586572,-29.4787037526953952],"rgb":[0.66666666666666663,0.133333333333333331,0.466666666666666674],"xyz":[0.204786154355710515,0.110233880456493,0.185026647813612388],"hpluv":[337.990195281021442,251.92759566726761,39.619833929041036],"hsluv":[337.990195281021442,87.2621982611374278,39.619833929041036]},"#aa2288":{"lch":[40.3594266716885386,78.6767938432408,327.148786779116733],"luv":[40.3594266716885386,66.0949636498191637,-42.6789605025813046],"rgb":[0.66666666666666663,0.133333333333333331,0.533333333333333326],"xyz":[0.215926571457654315,0.1146900472972706,0.243699511217184556],"hpluv":[327.148786779116733,247.366561360315984,40.3594266716885386],"hsluv":[327.148786779116733,88.4751585260979283,40.3594266716885386]},"#aa2299":{"lch":[41.2022629883412748,81.6302410017403162,316.790315261789033],"luv":[41.2022629883412748,59.4964385039503,-55.8898027492302489],"rgb":[0.66666666666666663,0.133333333333333331,0.6],"xyz":[0.228983535566727042,0.119912832940899758,0.312466188858302463],"hpluv":[316.790315261789033,251.402351399829286,41.2022629883412748],"hsluv":[316.790315261789033,89.6322731802278554,41.2022629883412748]},"#aa22aa":{"lch":[42.1443943233873242,87.0780915666379229,307.715012949243715],"luv":[42.1443943233873242,53.2686588598376076,-68.8842798769212834],"rgb":[0.66666666666666663,0.133333333333333331,0.66666666666666663],"xyz":[0.24404122853197957,0.125935910127000866,0.391770038475301063],"hpluv":[307.715012949243715,262.185344504614818,42.1443943233873242],"hsluv":[307.715012949243715,90.7081440057972515,42.1443943233873242]},"#aa22bb":{"lch":[43.1807973125030387,94.3504956605328573,300.218008125398399],"luv":[43.1807973125030387,47.4858085519839577,-81.5298351375283801],"rgb":[0.66666666666666663,0.133333333333333331,0.733333333333333282],"xyz":[0.261178820639316245,0.132790946969935625,0.48202802357394281],"hpluv":[300.218008125398399,277.263598469343151,43.1807973125030387],"hsluv":[300.218008125398399,91.6896384965505291,43.1807973125030387]},"#aa22cc":{"lch":[44.3056820912093627,102.813108633557576,294.217612554784239],"luv":[44.3056820912093627,42.1742864712375294,-93.764944769021767],"rgb":[0.66666666666666663,0.133333333333333331,0.8],"xyz":[0.280471196083037944,0.140507897147424426,0.583634534244213],"hpluv":[294.217612554784239,294.461411899371626,44.3056820912093627],"hsluv":[294.217612554784239,92.5728114271618097,44.3056820912093627]},"#aa22dd":{"lch":[45.5127751844210451,111.980933923074502,289.471886144522102],"luv":[45.5127751844210451,37.3282042805071441,-105.576203414769125],"rgb":[0.66666666666666663,0.133333333333333331,0.866666666666666696],"xyz":[0.301989521633671543,0.14911522736767796,0.696964382144219],"hpluv":[289.471886144522102,312.212361278410071,45.5127751844210451],"hsluv":[289.471886144522102,93.3598993754704622,45.5127751844210451]},"#aa22ee":{"lch":[46.7955661660676938,121.524022862348417,285.718434714393425],"luv":[46.7955661660676938,32.9220942551774698,-116.979587289842115],"rgb":[0.66666666666666663,0.133333333333333331,0.933333333333333348],"xyz":[0.325801701899846252,0.158640099474147978,0.822375198212742187],"hpluv":[285.718434714393425,329.531365671141714,46.7955661660676938],"hsluv":[285.718434714393425,94.0568560040361348,46.7955661660676938]},"#aa22ff":{"lch":[48.1475121680676921,131.233078667623346,282.730941389390409],"luv":[48.1475121680676921,28.9202258451599548,-128.006802450680539],"rgb":[0.66666666666666663,0.133333333333333331,1],"xyz":[0.351972750309677673,0.169108518838080701,0.960209386504524],"hpluv":[282.730941389390409,345.866733454918517,48.1475121680676921],"hsluv":[282.730941389390409,99.9999999999992,48.1475121680676921]},"#883300":{"lch":[33.1414787667816597,73.2165592554870841,22.9600016117944072],"luv":[33.1414787667816597,67.4161530625393084,28.5609323282788417],"rgb":[0.533333333333333326,0.2,0],"xyz":[0.113368907986088716,0.076027497524815621,0.00870518857569610102],"hpluv":[22.9600016117944072,280.334636286210525,33.1414787667816597],"hsluv":[22.9600016117944072,100.000000000002245,33.1414787667816597]},"#883311":{"lch":[33.2285118286029402,71.0572306739368287,21.2511434941679589],"luv":[33.2285118286029402,66.2253841559006844,25.7551650053430592],"rgb":[0.533333333333333326,0.2,0.0666666666666666657],"xyz":[0.114380573485725834,0.0764321637246704738,0.0140332935404517325],"hpluv":[21.2511434941679589,271.354302974885854,33.2285118286029402],"hsluv":[21.2511434941679589,91.7325092821930355,33.2285118286029402]},"#883322":{"lch":[33.389038834633638,67.403958774683133,17.9527330699243208],"luv":[33.389038834633638,64.1221355411587126,20.7760774002325519],"rgb":[0.533333333333333326,0.2,0.133333333333333331],"xyz":[0.116255931624202863,0.0771823069800612882,0.0239101797364309268],"hpluv":[17.9527330699243208,256.165602847605,33.389038834633638],"hsluv":[17.9527330699243208,77.1564226992543354,33.389038834633638]},"#883333":{"lch":[33.6510932573449324,62.3280121609532785,12.1770506300618564],"luv":[33.6510932573449324,60.9256605799824484,13.1470522486492083],"rgb":[0.533333333333333326,0.2,0.2],"xyz":[0.119343682356660596,0.0784174072730444,0.04017233359404207],"hpluv":[12.1770506300618564,235.030067027939708,33.6510932573449324],"hsluv":[12.1770506300618564,55.0748296144977,33.6510932573449324]},"#883344":{"lch":[34.0246284162643136,56.9037682047597428,3.23132728809417369],"luv":[34.0246284162643136,56.8132965471078748,3.20751794249172528],"rgb":[0.533333333333333326,0.2,0.266666666666666663],"xyz":[0.12380167760087947,0.080200605370731981,0.0636511085469287086],"hpluv":[3.23132728809417369,212.220318588139889,34.0246284162643136],"hsluv":[3.23132728809417369,58.083398150148156,34.0246284162643136]},"#883355":{"lch":[34.5156618951709859,52.7529688087382524,350.767304332875],"luv":[34.5156618951709859,52.0695471674777721,-8.46392201697997137],"rgb":[0.533333333333333326,0.2,0.333333333333333315],"xyz":[0.129764091640241469,0.0825855709864768139,0.0950531558209026239],"hpluv":[350.767304332875,193.941176615342812,34.5156618951709859],"hsluv":[350.767304332875,61.5291535706030714,34.5156618951709859]},"#883366":{"lch":[35.1268460128593318,51.5738240122621576,335.705329263136434],"luv":[35.1268460128593318,47.0065260432940519,-21.2189969741481157],"rgb":[0.533333333333333326,0.2,0.4],"xyz":[0.137349087413749654,0.0856195692958801324,0.135000800228046586],"hpluv":[335.705329263136434,186.307141954737205,35.1268460128593318],"hsluv":[335.705329263136434,65.1713869724459869,35.1268460128593318]},"#883377":{"lch":[35.8579115963162849,54.2604071268956929,320.552373035814298],"luv":[35.8579115963162849,41.9001950458929713,-34.4755773946224],"rgb":[0.533333333333333326,0.2,0.466666666666666674],"xyz":[0.14666310043395156,0.0893451745039609418,0.184054602134444495],"hpluv":[320.552373035814298,192.015984070736607,35.8579115963162849],"hsluv":[320.552373035814298,68.798738775930957,35.8579115963162849]},"#883388":{"lch":[36.7061150242973682,60.4128011412536097,307.715012949244056],"luv":[36.7061150242973682,36.9565850245806402,-47.7903480323547711],"rgb":[0.533333333333333326,0.2,0.533333333333333326],"xyz":[0.157803517535895388,0.0938013413447385397,0.242727465538016662],"hpluv":[307.715012949244056,208.847787272345244,36.7061150242973682],"hsluv":[307.715012949244056,72.2549736675254479,36.7061150242973682]},"#883399":{"lch":[37.6667130487112445,68.9141309342046213,297.955533412138379],"luv":[37.6667130487112445,32.3059919210196611,-60.8726566564636684],"rgb":[0.533333333333333326,0.2,0.6],"xyz":[0.170860481644968087,0.0990241269883677,0.311494143179134542],"hpluv":[297.955533412138379,232.161331922109071,37.6667130487112445],"hsluv":[297.955533412138379,75.4431641885032604,37.6667130487112445]},"#8833aa":{"lch":[38.7334497692602824,78.7159372772915162,290.848124870138179],"luv":[38.7334497692602824,28.0143748789862741,-73.5621749378178436],"rgb":[0.533333333333333326,0.2,0.66666666666666663],"xyz":[0.185918174610220643,0.105047204174468806,0.390797992796133142],"hpluv":[290.848124870138179,257.878905714084965,38.7334497692602824],"hsluv":[290.848124870138179,78.3166072053086282,38.7334497692602824]},"#8833bb":{"lch":[39.8990272727434743,89.1142300257769193,285.691107407551272],"luv":[39.8990272727434743,24.1010351313191435,-85.7932753698447073],"rgb":[0.533333333333333326,0.2,0.733333333333333282],"xyz":[0.20305576671755729,0.111902241017403564,0.481055977894774889],"hpluv":[285.691107407551272,283.415812953045702,39.8990272727434743],"hsluv":[285.691107407551272,80.8649153118493444,39.8990272727434743]},"#8833cc":{"lch":[41.1555326498064318,99.7027359993818578,281.897918690971494],"luv":[41.1555326498064318,20.5555775093346966,-97.560769774639283],"rgb":[0.533333333333333326,0.2,0.8],"xyz":[0.222348142161279017,0.119619191194892366,0.5826624885650451],"hpluv":[281.897918690971494,307.410130900702256,41.1555326498064318],"hsluv":[281.897918690971494,83.1006969987668356,41.1555326498064318]},"#8833dd":{"lch":[42.4948021164729042,110.266949448261684,279.053462184119098],"luv":[42.4948021164729042,17.3511661022166734,-108.893237510502843],"rgb":[0.533333333333333326,0.2,0.866666666666666696],"xyz":[0.24386646771191256,0.1282265214151459,0.695992336465051098],"hpluv":[279.053462184119098,329.267506795456711,42.4948021164729042],"hsluv":[279.053462184119098,85.0491409670088103,42.4948021164729042]},"#8833ee":{"lch":[43.9087129541284185,120.703343561802441,276.877390721452173],"luv":[43.9087129541284185,14.4536316684396038,-119.834843341123431],"rgb":[0.533333333333333326,0.2,0.933333333333333348],"xyz":[0.267678647978087325,0.137751393521615917,0.821403152533574321],"hpluv":[276.877390721452173,348.825254458779511,43.9087129541284185],"hsluv":[276.877390721452173,90.7214777394212177,43.9087129541284185]},"#8833ff":{"lch":[45.3894029264418037,130.969293653816607,275.181129330284705],"luv":[45.3894029264418037,11.8271264623124566,-130.43417864894198],"rgb":[0.533333333333333326,0.2,1],"xyz":[0.293849696387918691,0.148219812885548641,0.959237340825356166],"hpluv":[275.181129330284705,366.146040402293636,45.3894029264418037],"hsluv":[275.181129330284705,99.9999999999993179,45.3894029264418037]},"#ffbb00":{"lch":[80.0686585320779614,99.7432534700870832,55.1804439586775146],"luv":[80.0686585320779614,56.9527800089419642,81.8846595037867928],"rgb":[1,0.733333333333333282,0],"xyz":[0.590086256022839262,0.568029919385293569,0.0785626376345524291],"hpluv":[55.1804439586775146,207.400278899961506,80.0686585320779614],"hsluv":[55.1804439586775146,100.000000000004661,80.0686585320779614]},"#ffbb11":{"lch":[80.0914663159454,98.8408701901197304,54.9443852376931758],"luv":[80.0914663159454,56.7713575947746136,80.9106332739172558],"rgb":[1,0.733333333333333282,0.0666666666666666657],"xyz":[0.591097921522476422,0.568434585585148477,0.0838907425993080658],"hpluv":[54.9443852376931758,205.801067903733326,80.0914663159454],"hsluv":[54.9443852376931758,100.000000000004746,80.0914663159454]},"#ffbb22":{"lch":[80.1337172522408849,97.1832370837577173,54.4980435584705063],"luv":[80.1337172522408849,56.4372945908461148,79.11645435270664],"rgb":[1,0.733333333333333282,0.133333333333333331],"xyz":[0.592973279660953367,0.569184728840539278,0.0937676287952872584],"hpluv":[54.4980435584705063,202.856099527528187,80.1337172522408849],"hsluv":[54.4980435584705063,100.00000000000469,80.1337172522408849]},"#ffbb33":{"lch":[80.2032020182086569,94.4967793168558643,53.7374633716008248],"luv":[80.2032020182086569,55.8935303906135772,76.1941898161015558],"rgb":[1,0.733333333333333282,0.2],"xyz":[0.596061030393411184,0.570419829133522405,0.110029782652898395],"hpluv":[53.7374633716008248,198.062979410590685,80.2032020182086569],"hsluv":[53.7374633716008248,100.000000000004576,80.2032020182086569]},"#ffbb44":{"lch":[80.3033451682561,90.7120739700224874,52.5796541788809932],"luv":[80.3033451682561,55.1219083097901148,72.0434284874749835],"rgb":[1,0.733333333333333282,0.266666666666666663],"xyz":[0.60051902563763,0.57220302723121,0.133508557605785033],"hpluv":[52.5796541788809932,191.266883403483888,80.3033451682561],"hsluv":[52.5796541788809932,100.000000000004732,80.3033451682561]},"#ffbb55":{"lch":[80.4369584648287343,85.824023801574981,50.9113466162360169],"luv":[80.4369584648287343,54.1139445833304435,66.614143116349922],"rgb":[1,0.733333333333333282,0.333333333333333315],"xyz":[0.606481439676992,0.57458799284695472,0.164910604879758949],"hpluv":[50.9113466162360169,182.412290123698938,80.4369584648287343],"hsluv":[50.9113466162360169,100.000000000004846,80.4369584648287343]},"#ffbb66":{"lch":[80.6063993458739532,79.8959983704508545,48.5678239065140147],"luv":[80.6063993458739532,52.8698192869345931,59.9011916757752374],"rgb":[1,0.733333333333333282,0.4],"xyz":[0.614066435450500214,0.577621991156358,0.20485824928690291],"hpluv":[48.5678239065140147,171.553596694327723,80.6063993458739532],"hsluv":[48.5678239065140147,100.000000000004945,80.6063993458739532]},"#ffbb77":{"lch":[80.8136549908608828,73.0715029906331353,45.3006510664637219],"luv":[80.8136549908608828,51.397517928562209,51.9397699272266067],"rgb":[1,0.733333333333333282,0.466666666666666674],"xyz":[0.623380448470702064,0.58134759636443889,0.253912051193300847],"hpluv":[45.3006510664637219,158.885762577352,80.8136549908608828],"hsluv":[45.3006510664637219,100.000000000005144,80.8136549908608828]},"#ffbb88":{"lch":[81.0603921498240823,65.5982066090816,40.7273497798256443],"luv":[81.0603921498240823,49.7118280718431649,42.8002203275083914],"rgb":[1,0.733333333333333282,0.533333333333333326],"xyz":[0.634520865572646,0.585803763205216432,0.312584914596873],"hpluv":[40.7273497798256443,144.809180382553194,81.0603921498240823],"hsluv":[40.7273497798256443,100.0000000000054,81.0603921498240823]},"#ffbb99":{"lch":[81.347989327564818,57.8755898316684423,34.2609783084776538],"luv":[81.347989327564818,47.8331272298795724,32.5818329406692087],"rgb":[1,0.733333333333333282,0.6],"xyz":[0.64757782968171862,0.591026548848845645,0.381351592237990866],"hpluv":[34.2609783084776538,130.060421106466862,81.347989327564818],"hsluv":[34.2609783084776538,100.000000000005514,81.347989327564818]},"#ffbbaa":{"lch":[81.6775593509345725,50.5427251754064883,25.056975338279841],"luv":[81.6775593509345725,45.7860019440054415,21.405819165362459],"rgb":[1,0.733333333333333282,0.66666666666666663],"xyz":[0.662635522646971231,0.597049626034946712,0.460655441854989522],"hpluv":[25.056975338279841,115.96007016550756,81.6775593509345725],"hsluv":[25.056975338279841,100.000000000005954,81.6775593509345725]},"#ffbbbb":{"lch":[82.0499666293022,44.6012959670408264,12.1770506300623094],"luv":[82.0499666293022,43.5977873399533138,9.40789779917804125],"rgb":[1,0.733333333333333282,0.733333333333333282],"xyz":[0.679773114754307795,0.603904662877881471,0.550913426953631213],"hpluv":[12.1770506300623094,104.793068167285782,82.0499666293022],"hsluv":[12.1770506300623094,100.000000000006168,82.0499666293022]},"#ffbbcc":{"lch":[82.4658415859876,41.4263127316455169,355.474040938847054],"luv":[82.4658415859876,41.2971323922898534,-3.26898190783910625],"rgb":[1,0.733333333333333282,0.8],"xyz":[0.699065490198029549,0.611621613055370328,0.652519937623901369],"hpluv":[355.474040938847054,100.004408983591958,82.4658415859876],"hsluv":[355.474040938847054,100.000000000006509,82.4658415859876]},"#ffbbdd":{"lch":[82.9255937413379,42.2590852539423381,337.045135839305544],"luv":[82.9255937413379,38.9126886018087319,-16.4812909773061058],"rgb":[1,0.733333333333333282,0.866666666666666696],"xyz":[0.720583815748663148,0.620228943275623834,0.765849785523907367],"hpluv":[337.045135839305544,105.181583048825317,82.9255937413379],"hsluv":[337.045135839305544,100.000000000006992,82.9255937413379]},"#ffbbee":{"lch":[83.4294243398036315,47.2826492521794748,320.476273654572083],"luv":[83.4294243398036315,36.4719970678196077,-30.0905691237235686],"rgb":[1,0.733333333333333282,0.933333333333333348],"xyz":[0.744395996014837857,0.629753815382093851,0.89126060159243059],"hpluv":[320.476273654572083,121.793886282549721,83.4294243398036315],"hsluv":[320.476273654572083,100.000000000007375,83.4294243398036315]},"#ffbbff":{"lch":[83.9773390427358493,55.5806936350452148,307.715012949246614],"luv":[83.9773390427358493,34.0006189291922496,-43.9678452665650781],"rgb":[1,0.733333333333333282,1],"xyz":[0.770567044424669279,0.640222234746026575,1.02909478988421244],"hpluv":[307.715012949246614,148.765749509941259,83.9773390427358493],"hsluv":[307.715012949246614,100.00000000000793,83.9773390427358493]},"#aa3300":{"lch":[39.4372171279304595,100.717281062042773,18.6056676884160446],"luv":[39.4372171279304595,95.4534790945485838,32.1341568004684959],"rgb":[0.66666666666666663,0.2,0],"xyz":[0.177609683996858475,0.109151647655369471,0.0117164749512008691],"hpluv":[18.6056676884160446,324.068678498457416,39.4372171279304595],"hsluv":[18.6056676884160446,100.00000000000226,39.4372171279304595]},"#aa3311":{"lch":[39.5056415087576553,98.9056898290362199,17.5539290045831464],"luv":[39.5056415087576553,94.2999972712563,29.8302865423477179],"rgb":[0.66666666666666663,0.2,0.0666666666666666657],"xyz":[0.178621349496495607,0.109556313855224324,0.0170445799159565023],"hpluv":[17.5539290045831464,317.688492914835,39.5056415087576553],"hsluv":[17.5539290045831464,94.2489803369173558,39.5056415087576553]},"#aa3322":{"lch":[39.6320377265530155,95.7434230458582789,15.5633947922033684],"luv":[39.6320377265530155,92.2329117474569102,25.688383505468213],"rgb":[0.66666666666666663,0.2,0.133333333333333331],"xyz":[0.180496707634972609,0.110306457110615139,0.0269214661119356949],"hpluv":[15.5633947922033684,306.55039093266322,39.6320377265530155],"hsluv":[15.5633947922033684,83.9544037116345123,39.6320377265530155]},"#aa3333":{"lch":[39.8389046640011415,91.0660982539230162,12.1770506300618351],"luv":[39.8389046640011415,89.0171529654153488,19.2088711049089049],"rgb":[0.66666666666666663,0.2,0.2],"xyz":[0.18358445836743037,0.111541557403598252,0.0431836199695468381],"hpluv":[12.1770506300618351,290.060550373943784,39.8389046640011415],"hsluv":[12.1770506300618351,67.9701775681036366,39.8389046640011415]},"#aa3344":{"lch":[40.1348956250933142,85.3951569144799691,7.07959423789482756],"luv":[40.1348956250933142,84.7440953003879116,10.5247867516366789],"rgb":[0.66666666666666663,0.2,0.266666666666666663],"xyz":[0.18804245361164923,0.113324755501285832,0.0666623949224334766],"hpluv":[7.07959423789482756,269.991710008472637,40.1348956250933142],"hsluv":[7.07959423789482756,69.5294395234689659,40.1348956250933142]},"#aa3355":{"lch":[40.5259588707466,79.61783322386637,359.98582832830067],"luv":[40.5259588707466,79.6178307884273693,-0.0196928603108827253],"rgb":[0.66666666666666663,0.2,0.333333333333333315],"xyz":[0.194004867651011215,0.115709721117030664,0.098064442196407392],"hpluv":[359.98582832830067,249.296614878837403,40.5259588707466],"hsluv":[359.98582832830067,71.3920974276079079,40.5259588707466]},"#aa3366":{"lch":[41.0157539995587683,74.8661602955128558,350.806369630673316],"luv":[41.0157539995587683,73.9044320805857,-11.9614746682639641],"rgb":[0.66666666666666663,0.2,0.4],"xyz":[0.2015898634245194,0.118743719426433983,0.138012086603551354],"hpluv":[350.806369630673316,231.619002340768361,41.0157539995587683],"hsluv":[350.806369630673316,73.4562780141226597,41.0157539995587683]},"#aa3377":{"lch":[41.6059173351841167,72.2728884464882668,339.921631600955322],"luv":[41.6059173351841167,67.8804264173117531,-24.8116527825629412],"rgb":[0.66666666666666663,0.2,0.466666666666666674],"xyz":[0.210903876444721305,0.122469324634514792,0.187065888509949263],"hpluv":[339.921631600955322,220.424384448141751,41.6059173351841167],"hsluv":[339.921631600955322,75.6166865764569138,41.6059173351841167]},"#aa3388":{"lch":[42.296293156356171,72.6091331125239918,328.324027314743319],"luv":[42.296293156356171,61.7926517819245191,-38.1281313089174],"rgb":[0.66666666666666663,0.2,0.533333333333333326],"xyz":[0.222044293546665161,0.12692549147529239,0.24573875191352143],"hpluv":[328.324027314743319,217.83530631356345,42.296293156356171],"hsluv":[328.324027314743319,77.7798333688196237,42.296293156356171]},"#aa3399":{"lch":[43.0851702185186838,75.9982874692542794,317.281450106519685],"luv":[43.0851702185186838,55.835561651799118,-51.5570533805758799],"rgb":[0.66666666666666663,0.2,0.6],"xyz":[0.235101257655737861,0.132148277118921548,0.314505429554639337],"hpluv":[317.281450106519685,223.828466633931441,43.0851702185186838],"hsluv":[317.281450106519685,79.8726039522015441,43.0851702185186838]},"#aa33aa":{"lch":[43.9695321467927229,81.9717995507402861,307.715012949243828],"luv":[43.9695321467927229,50.1449646844158607,-64.8448798162617521],"rgb":[0.66666666666666663,0.2,0.66666666666666663],"xyz":[0.250158950620990417,0.138171354305022642,0.393809279171637938],"hpluv":[307.715012949243828,236.565795567314069,43.9695321467927229],"hsluv":[307.715012949243828,81.8445603498948628,43.9695321467927229]},"#aa33bb":{"lch":[44.9453163823579231,89.8045713491188593,299.92695612823394],"luv":[44.9453163823579231,44.8030997809084,-77.8302208992172],"rgb":[0.66666666666666663,0.2,0.733333333333333282],"xyz":[0.267296542728327036,0.145026391147957401,0.484067264270279685],"hpluv":[299.92695612823394,253.543994890590483,44.9453163823579231],"hsluv":[299.92695612823394,83.6659201788580305,44.9453163823579231]},"#aa33cc":{"lch":[46.0076707905516145,98.8168321279874249,293.782406660809556],"luv":[46.0076707905516145,39.8493034294229815,-90.425656359246986],"rgb":[0.66666666666666663,0.2,0.8],"xyz":[0.28658891817204879,0.152743341325446202,0.585673774940549841],"hpluv":[293.782406660809556,272.546121846523647,46.0076707905516145],"hsluv":[293.782406660809556,85.323407183561244,46.0076707905516145]},"#aa33dd":{"lch":[47.1511962508372804,108.497592079042477,288.982430572084695],"luv":[47.1511962508372804,35.2919015872993782,-102.597315604759743],"rgb":[0.66666666666666663,0.2,0.866666666666666696],"xyz":[0.308107243722682334,0.161350671545699736,0.699003622840555838],"hpluv":[288.982430572084695,291.989148013150611,47.1511962508372804],"hsluv":[288.982430572084695,86.8156421407842771,47.1511962508372804]},"#aa33ee":{"lch":[48.3701654903461247,118.505438755587946,285.224041333998457],"luv":[48.3701654903461247,31.1188262963008349,-114.346655677352729],"rgb":[0.66666666666666663,0.2,0.933333333333333348],"xyz":[0.331919423988857099,0.170875543652169781,0.824414438909079061],"hpluv":[285.224041333998457,310.885191630161273,48.3701654903461247],"hsluv":[285.224041333998457,89.3017266962351215,48.3701654903461247]},"#aa33ff":{"lch":[49.6587116356326135,128.627945638670809,282.256374557143658],"luv":[49.6587116356326135,27.305962831451918,-125.696192436653462],"rgb":[0.66666666666666663,0.2,1],"xyz":[0.358090472398688464,0.181343963016102477,0.962248627200860907],"hpluv":[282.256374557143658,328.684490794403757,49.6587116356326135],"hsluv":[282.256374557143658,99.9999999999991616,49.6587116356326135]},"#884400":{"lch":[36.685747441671559,64.5393704655657814,31.8123524502136021],"luv":[36.685747441671559,54.844205976921188,34.0212200082916922],"rgb":[0.533333333333333326,0.266666666666666663,0],"xyz":[0.122201478469054756,0.093692638490747937,0.0116493787366846978],"hpluv":[31.8123524502136021,223.237258003095718,36.685747441671559],"hsluv":[31.8123524502136021,100.000000000002245,36.685747441671559]},"#884411":{"lch":[36.7614898568215622,62.4864851085245405,30.2058215583615599],"luv":[36.7614898568215622,54.0023006087270119,31.4374354899146],"rgb":[0.533333333333333326,0.266666666666666663,0.0666666666666666657],"xyz":[0.123213143968691874,0.0940973046906027899,0.016977483701440331],"hpluv":[30.2058215583615599,215.691146343233044,36.7614898568215622],"hsluv":[30.2058215583615599,93.206231917801162,36.7614898568215622]},"#884422":{"lch":[36.9013237077522405,58.9550348899468375,27.0578850153250627],"luv":[36.9013237077522405,52.5022536375556825,26.8180816214102],"rgb":[0.533333333333333326,0.266666666666666663,0.133333333333333331],"xyz":[0.125088502107168903,0.0948474479459936,0.0268543698974195236],"hpluv":[27.0578850153250627,202.730122118290922,36.9013237077522405],"hsluv":[27.0578850153250627,81.1214838671569822,36.9013237077522405]},"#884433":{"lch":[37.1299605496210461,53.9021323280231357,21.3870333458705382],"luv":[37.1299605496210461,50.1903435049312,19.6562785990819577],"rgb":[0.533333333333333326,0.266666666666666663,0.2],"xyz":[0.128176252839626637,0.0960825482389767171,0.0431165237550306668],"hpluv":[21.3870333458705382,184.213216030002656,37.1299605496210461],"hsluv":[21.3870333458705382,62.5495295304316272,37.1299605496210461]},"#884444":{"lch":[37.4566279620983806,48.2433933618324389,12.1770506300619505],"luv":[37.4566279620983806,47.157939219998795,10.1761373608750691],"rgb":[0.533333333333333326,0.266666666666666663,0.266666666666666663],"xyz":[0.132634248083845524,0.0978657463366643,0.0665952987079173],"hpluv":[12.1770506300619505,163.436290620587812,37.4566279620983806],"hsluv":[12.1770506300619505,38.2981887065726,37.4566279620983806]},"#884455":{"lch":[37.8873893879065804,43.5926938841600631,358.470393497241901],"luv":[37.8873893879065804,43.5771602849424937,-1.16364151632571566],"rgb":[0.533333333333333326,0.266666666666666663,0.333333333333333315],"xyz":[0.138596662123207509,0.10025071195240913,0.0979973459818912207],"hpluv":[358.470393497241901,146.001848007416612,37.8873893879065804],"hsluv":[358.470393497241901,42.6300163695831245,37.8873893879065804]},"#884466":{"lch":[38.425613648805637,41.9872152878557756,340.815857604715632],"luv":[38.425613648805637,39.6555541095459816,-13.7972198610307206],"rgb":[0.533333333333333326,0.266666666666666663,0.4],"xyz":[0.146181657896715694,0.103284710261812449,0.137944990389035183],"hpluv":[340.815857604715632,138.655016432961,38.425613648805637],"hsluv":[340.815857604715632,47.3337116796912767,38.425613648805637]},"#884477":{"lch":[39.0722986805963117,44.7783217464764363,322.645837420375756],"luv":[39.0722986805963117,35.5943002873345478,-27.1688035343115608],"rgb":[0.533333333333333326,0.266666666666666663,0.466666666666666674],"xyz":[0.1554956709169176,0.107010315469893258,0.186998792295433092],"hpluv":[322.645837420375756,145.424700121889231,39.0722986805963117],"hsluv":[322.645837420375756,52.1510622716411,39.0722986805963117]},"#884488":{"lch":[39.8263740522966856,51.5911203050634839,307.71501294924451],"luv":[39.8263740522966856,31.5600599218946343,-40.8118403414738609],"rgb":[0.533333333333333326,0.266666666666666663,0.533333333333333326],"xyz":[0.166636088018861428,0.111466482310670856,0.245671655699005259],"hpluv":[307.71501294924451,164.377933698467302,39.8263740522966856],"hsluv":[307.71501294924451,56.8697587177058,39.8263740522966856]},"#884499":{"lch":[40.6850187117946192,61.0189075542410393,296.969581150574243],"luv":[40.6850187117946192,27.6731358367265301,-54.3829443123034295],"rgb":[0.533333333333333326,0.266666666666666663,0.6],"xyz":[0.179693052127934128,0.116689267954300013,0.314438333340123166],"hpluv":[296.969581150574243,190.313341437332326,40.6850187117946192],"hsluv":[296.969581150574243,61.3383523001243134,40.6850187117946192]},"#8844aa":{"lch":[41.643995358805,71.7935926347933417,289.536616505740085],"luv":[41.643995358805,24.0084388126510113,-67.6602897510042141],"rgb":[0.533333333333333326,0.266666666666666663,0.66666666666666663],"xyz":[0.194750745093186683,0.122712345140401108,0.393742182957121767],"hpluv":[289.536616505740085,218.762371943685849,41.643995358805],"hsluv":[289.536616505740085,65.4647221474276506,41.643995358805]},"#8844bb":{"lch":[42.6979882651059626,83.1164887776927515,284.352541737053286],"luv":[42.6979882651059626,20.6035404121657031,-80.5223250360828757],"rgb":[0.533333333333333326,0.266666666666666663,0.733333333333333282],"xyz":[0.21188833720052333,0.129567381983335866,0.484000168055763513],"hpluv":[284.352541737053286,247.012596783276,42.6979882651059626],"hsluv":[284.352541737053286,69.2054262339616741,42.6979882651059626]},"#8844cc":{"lch":[43.840927241858644,94.5481620176080924,280.647262826657595],"luv":[43.840927241858644,17.4689172853010533,-92.9203522904814463],"rgb":[0.533333333333333326,0.266666666666666663,0.8],"xyz":[0.231180712644245057,0.137284332160824668,0.585606678726033669],"hpluv":[280.647262826657595,273.660859280114778,43.840927241858644],"hsluv":[280.647262826657595,72.5522514276637764,43.840927241858644]},"#8844dd":{"lch":[45.0662821798681108,105.864396975636453,277.925647559652191],"luv":[45.0662821798681108,14.5974213234566292,-104.853163222292139],"rgb":[0.533333333333333326,0.266666666666666663,0.866666666666666696],"xyz":[0.2526990381948786,0.145891662381078202,0.698936526626039667],"hpluv":[277.925647559652191,298.083215805211921,45.0662821798681108],"hsluv":[277.925647559652191,79.9664783418063649,45.0662821798681108]},"#8844ee":{"lch":[46.3673172023828,116.961454232737537,275.874868362231723],"luv":[46.3673172023828,11.97173240994087,-116.347150370524886],"rgb":[0.533333333333333326,0.266666666666666663,0.933333333333333348],"xyz":[0.276511218461053365,0.155416534487548247,0.82434734269456289],"hpluv":[275.874868362231723,320.088534026972411,46.3673172023828],"hsluv":[275.874868362231723,89.9071832422553,46.3673172023828]},"#8844ff":{"lch":[47.7372988913525091,127.801124524511906,274.29427304351259],"luv":[47.7372988913525091,9.5696272486796623,-127.442338585146516],"rgb":[0.533333333333333326,0.266666666666666663,1],"xyz":[0.302682266870884731,0.165884953851480943,0.962181530986344735],"hpluv":[274.29427304351259,339.716123682654541,47.7372988913525091],"hsluv":[274.29427304351259,99.9999999999992468,47.7372988913525091]},"#ffcc00":{"lch":[84.1983464973243,98.3335943421723613,63.5926937648685069],"luv":[84.1983464973243,43.7338065737115329,88.0729807536005751],"rgb":[1,0.8,0],"xyz":[0.628309999332456237,0.644477406004528408,0.0913038854044243842],"hpluv":[63.5926937648685069,267.385577483165775,84.1983464973243],"hsluv":[63.5926937648685069,100.000000000007688,84.1983464973243]},"#ffcc11":{"lch":[84.2193135631731877,97.4576917861448777,63.4272907637844199],"luv":[84.2193135631731877,43.5960552023901897,87.1629833075564164],"rgb":[1,0.8,0.0666666666666666657],"xyz":[0.629321664832093397,0.644882072204383316,0.0966319903691800208],"hpluv":[63.4272907637844199,265.403720884510847,84.2193135631731877],"hsluv":[63.4272907637844199,100.000000000007645,84.2193135631731877]},"#ffcc22":{"lch":[84.2581577251319516,95.845309095571892,63.1144413478925301],"luv":[84.2581577251319516,43.342199386504106,85.4855369519677168],"rgb":[1,0.8,0.133333333333333331],"xyz":[0.631197022970570343,0.645632215459774117,0.106508876565159213],"hpluv":[63.1144413478925301,261.744085553517664,84.2581577251319516],"hsluv":[63.1144413478925301,100.00000000000766,84.2581577251319516]},"#ffcc33":{"lch":[84.3220485899852719,93.2224175872051148,62.5809741236821822],"luv":[84.3220485899852719,42.9284172035605494,82.7500461462124832],"rgb":[1,0.8,0.2],"xyz":[0.63428477370302816,0.646867315752757244,0.12277103042277035],"hpluv":[62.5809741236821822,255.758846695652977,84.3220485899852719],"hsluv":[62.5809741236821822,100.000000000007859,84.3220485899852719]},"#ffcc44":{"lch":[84.41414885501203,89.5051620308737,61.7678249437873745],"luv":[84.41414885501203,42.3400226901080785,78.8574442191356439],"rgb":[1,0.8,0.266666666666666663],"xyz":[0.638742768947247,0.64865051385044481,0.146249805375657],"hpluv":[61.7678249437873745,247.206609954939694,84.41414885501203],"hsluv":[61.7678249437873745,100.000000000007887,84.41414885501203]},"#ffcc55":{"lch":[84.5370662928161,84.6613331238571476,60.5932597011580469],"luv":[84.5370662928161,41.569242864558305,73.7532329730438221],"rgb":[1,0.8,0.333333333333333315],"xyz":[0.644705182986609,0.651035479466189559,0.177651852649630904],"hpluv":[60.5932597011580469,235.935294148211483,84.5370662928161],"hsluv":[60.5932597011580469,100.000000000008015,84.5370662928161]},"#ffcc66":{"lch":[84.6930007913096,78.7104448491835456,58.9357730127494222],"luv":[84.6930007913096,40.6144802919859131,67.4225342075500151],"rgb":[1,0.8,0.4],"xyz":[0.65229017876011719,0.654069477775592878,0.217599497056774865],"hpluv":[58.9357730127494222,221.881579382217893,84.6930007913096],"hsluv":[58.9357730127494222,100.000000000008285,84.6930007913096]},"#ffcc77":{"lch":[84.8838226897762809,71.7288671198513441,56.6053668146737863],"luv":[84.8838226897762809,39.4797505573258718,59.8863897244492378],"rgb":[1,0.8,0.466666666666666674],"xyz":[0.661604191780319,0.657795082983673729,0.266653298963172802],"hpluv":[56.6053668146737863,205.087229042099608,84.8838226897762809],"hsluv":[56.6053668146737863,100.000000000008399,84.8838226897762809]},"#ffcc88":{"lch":[85.1111193079521371,63.8628893840605159,53.2910582019814285],"luv":[85.1111193079521371,38.1740592359010691,51.1977523133063457],"rgb":[1,0.8,0.533333333333333326],"xyz":[0.672744608882263,0.662251249824451271,0.325326162366744942],"hpluv":[53.2910582019814285,185.743844227516831,85.1111193079521371],"hsluv":[53.2910582019814285,100.000000000008683,85.1111193079521371]},"#ffcc99":{"lch":[85.3762249003348899,55.3594884395636555,48.4608196634464292],"luv":[85.3762249003348899,36.710650975629143,41.436711563970924],"rgb":[1,0.8,0.6],"xyz":[0.685801572991335595,0.667474035468080484,0.394092840007862821],"hpluv":[48.4608196634464292,164.300705026796521,85.3762249003348899],"hsluv":[48.4608196634464292,100.000000000008811,85.3762249003348899]},"#ffccaa":{"lch":[85.6802414041430467,46.6394331206389836,41.1740083194267896],"luv":[85.6802414041430467,35.1061374539925311,30.7049806200222122],"rgb":[1,0.8,0.66666666666666663],"xyz":[0.700859265956588207,0.673497112654181551,0.473396689624861478],"hpluv":[41.1740083194267896,141.724192848301414,85.6802414041430467],"hsluv":[41.1740083194267896,100.000000000009393,85.6802414041430467]},"#ffccbb":{"lch":[86.0240539433014106,38.4677176438646384,29.8042196075727404],"luv":[86.0240539433014106,33.3795484258888635,19.1199123327444944],"rgb":[1,0.8,0.733333333333333282],"xyz":[0.71799685806392477,0.68035214949711631,0.563654674723503168],"hpluv":[29.8042196075727404,120.116808153279436,86.0240539433014106],"hsluv":[29.8042196075727404,100.000000000009621,86.0240539433014106]},"#ffcccc":{"lch":[86.4083433793485,32.2775975377643,12.1770506300627517],"luv":[86.4083433793485,31.5513664521307504,6.80841962670093892],"rgb":[1,0.8,0.8],"xyz":[0.737289233507646524,0.688069099674605167,0.665261185393773324],"hpluv":[12.1770506300627517,103.973607583717524,86.4083433793485],"hsluv":[12.1770506300627517,100.000000000010388,86.4083433793485]},"#ffccdd":{"lch":[86.8335972965778637,30.2635044437543748,348.373924949033096],"luv":[86.8335972965778637,29.6426074465171432,-6.09881340826452867],"rgb":[1,0.8,0.866666666666666696],"xyz":[0.758807559058280123,0.696676429894858673,0.778591033293779322],"hpluv":[348.373924949033096,100.994037434302086,86.8335972965778637],"hsluv":[348.373924949033096,100.000000000011042,86.8335972965778637]},"#ffccee":{"lch":[87.3001202800073344,33.8382691858854301,324.868297683069],"luv":[87.3001202800073344,27.6740002852911822,-19.4724977777928352],"rgb":[1,0.8,0.933333333333333348],"xyz":[0.782619739324454833,0.70620130200132869,0.904001849362302545],"hpluv":[324.868297683069,117.528800717138253,87.3001202800073344],"hsluv":[324.868297683069,100.000000000011482,87.3001202800073344]},"#ffccff":{"lch":[87.8080440143565255,41.9549825399590404,307.715012949248376],"luv":[87.8080440143565255,25.6653035474654807,-33.1890456889728],"rgb":[1,0.8,1],"xyz":[0.808790787734286254,0.716669721365261414,1.0418360376540845],"hpluv":[307.715012949248376,152.433043069806,87.8080440143565255],"hsluv":[307.715012949248376,100.000000000012506,87.8080440143565255]},"#aa4400":{"lch":[42.2796461632011074,91.196234940608619,23.7609213617016479],"luv":[42.2796461632011074,83.4659581293579578,36.7448921741641357],"rgb":[0.66666666666666663,0.266666666666666663,0],"xyz":[0.186442254479824487,0.126816788621301801,0.0146606651121894659],"hpluv":[23.7609213617016479,273.706361359402308,42.2796461632011074],"hsluv":[23.7609213617016479,100.000000000002331,42.2796461632011074]},"#aa4411":{"lch":[42.3415695164373815,89.5099073241138399,22.7237862619920179],"luv":[42.3415695164373815,82.5619515402106572,34.5766925405446202],"rgb":[0.66666666666666663,0.266666666666666663,0.0666666666666666657],"xyz":[0.18745391997946162,0.127221454821156654,0.0199887700769451],"hpluv":[22.7237862619920179,268.252316854423896,42.3415695164373815],"hsluv":[22.7237862619920179,95.0030043013494634,42.3415695164373815]},"#aa4422":{"lch":[42.4560124733741162,86.5487219398638,20.7501492775311753],"luv":[42.4560124733741162,80.9346773489764075,30.663647399501361],"rgb":[0.66666666666666663,0.266666666666666663,0.133333333333333331],"xyz":[0.189329278117938621,0.127971598076547483,0.0298656562729242916],"hpluv":[20.7501492775311753,258.678767688655569,42.4560124733741162],"hsluv":[20.7501492775311753,86.0172479577967692,42.4560124733741162]},"#aa4433":{"lch":[42.643470741830761,82.1252826930209494,17.3597256589108966],"luv":[42.643470741830761,78.3845002494828691,24.5037176372775498],"rgb":[0.66666666666666663,0.266666666666666663,0.2],"xyz":[0.192417028850396354,0.129206698369530582,0.0461278101305354349],"hpluv":[17.3597256589108966,244.378874013338617,42.643470741830761],"hsluv":[17.3597256589108966,71.9602068881057733,42.643470741830761]},"#aa4444":{"lch":[42.9120210749329871,76.685866981555165,12.1770506300619239],"luv":[42.9120210749329871,74.9604702767477704,16.1756017075590073],"rgb":[0.66666666666666663,0.266666666666666663,0.266666666666666663],"xyz":[0.196875024094615242,0.130989896467218175,0.0696065850834220734],"hpluv":[12.1770506300619239,226.764824908056937,42.9120210749329871],"hsluv":[12.1770506300619239,53.1380271992519795,42.9120210749329871]},"#aa4455":{"lch":[43.2674147484635299,71.0489272172787594,4.80785478807657096],"luv":[43.2674147484635299,70.7989329223205,5.9549270177674023],"rgb":[0.66666666666666663,0.266666666666666663,0.333333333333333315],"xyz":[0.202837438133977255,0.133374862082963,0.101008632357395989],"hpluv":[4.80785478807657096,208.370342069187018,43.2674147484635299],"hsluv":[4.80785478807657096,55.6796565441877931,43.2674147484635299]},"#aa4466":{"lch":[43.7134526285125489,66.3411716499448261,355.020980864279068],"luv":[43.7134526285125489,66.0908363196155477,-5.75781299290188],"rgb":[0.66666666666666663,0.266666666666666663,0.4],"xyz":[0.210422433907485412,0.136408860392366299,0.140956276764539951],"hpluv":[355.020980864279068,192.578302395247789,43.7134526285125489],"hsluv":[355.020980864279068,58.5402216503940949,43.7134526285125489]},"#aa4477":{"lch":[44.252209356870793,63.7921835342278598,343.127789968560137],"luv":[44.252209356870793,61.046215168807521,-18.5149208377531842],"rgb":[0.66666666666666663,0.266666666666666663,0.466666666666666674],"xyz":[0.219736446927687346,0.140134465600447122,0.19001007867093786],"hpluv":[343.127789968560137,182.924482874911519,44.252209356870793],"hsluv":[343.127789968560137,61.5848400189491372,44.252209356870793]},"#aa4488":{"lch":[44.8842146397509367,64.3242328637060865,330.281311898752961],"luv":[44.8842146397509367,55.8636578331810938,-31.8882214461946916],"rgb":[0.66666666666666663,0.266666666666666663,0.533333333333333326],"xyz":[0.230876864029631146,0.14459063244122472,0.248682942074510027],"hpluv":[330.281311898752961,181.852933643495049,44.8842146397509367],"hsluv":[330.281311898752961,64.6866121014520274,44.8842146397509367]},"#aa4499":{"lch":[45.6086312393750077,68.1395242873703779,318.091147538790551],"luv":[45.6086312393750077,50.7100032224043318,-45.5136281051387854],"rgb":[0.66666666666666663,0.266666666666666663,0.6],"xyz":[0.243933828138703873,0.149813418084853878,0.317449619715627906],"hpluv":[318.091147538790551,189.579504981677246,45.6086312393750077],"hsluv":[318.091147538790551,67.7395528675925,45.6086312393750077]},"#aa44aa":{"lch":[46.4234422285949293,74.7240378323112822,307.715012949244056],"luv":[46.4234422285949293,45.7112599542092468,-59.1114417296972476],"rgb":[0.66666666666666663,0.266666666666666663,0.66666666666666663],"xyz":[0.258991521103956401,0.155836495270954972,0.396753469332626507],"hpluv":[307.715012949244056,204.25011915803762,46.4234422285949293],"hsluv":[307.715012949244056,70.6643205278868862,46.4234422285949293]},"#aa44bb":{"lch":[47.3256474704596144,83.2556513741305224,299.464802712285689],"luv":[47.3256474704596144,40.9525224701243289,-72.4872015535482177],"rgb":[0.66666666666666663,0.266666666666666663,0.733333333333333282],"xyz":[0.276129113211293076,0.162691532113889731,0.487011454431268254],"hpluv":[299.464802712285689,223.2320179514779,47.3256474704596144],"hsluv":[299.464802712285689,73.4081717041738244,47.3256474704596144]},"#aa44cc":{"lch":[48.311463406953564,92.9774863668884564,293.103270963637385],"luv":[48.311463406953564,36.4834012629607827,-85.5206080625642073],"rgb":[0.66666666666666663,0.266666666666666663,0.8],"xyz":[0.29542148865501483,0.170408482291378532,0.58861796510153841],"hpluv":[293.103270963637385,244.211962975346665,48.311463406953564],"hsluv":[293.103270963637385,75.9413806031634806,48.311463406953564]},"#aa44dd":{"lch":[49.376518181476186,103.335675962773564,288.229438001673088],"luv":[49.376518181476186,32.3257723855767125,-98.1494083851717676],"rgb":[0.66666666666666663,0.266666666666666663,0.866666666666666696],"xyz":[0.316939814205648318,0.179015812511632066,0.701947813001544407],"hpluv":[288.229438001673088,265.563967984367252,49.376518181476186],"hsluv":[288.229438001673088,78.2521754793284572,49.376518181476186]},"#aa44ee":{"lch":[50.5160343838387149,113.969241853628489,284.471970959088878],"luv":[50.5160343838387149,28.4816380653286,-110.35299897060564],"rgb":[0.66666666666666663,0.266666666666666663,0.933333333333333348],"xyz":[0.340751994471823083,0.188540684618102111,0.82735862907006763],"hpluv":[284.471970959088878,286.284434407824506,50.5160343838387149],"hsluv":[284.471970959088878,88.5420288112715355,50.5160343838387149]},"#aa44ff":{"lch":[51.7249932896939271,124.658572052901789,281.540806859048416],"luv":[51.7249932896939271,24.9399169363974949,-122.138282816953421],"rgb":[0.66666666666666663,0.266666666666666663,1],"xyz":[0.366923042881654449,0.199009103982034807,0.965192817361849476],"hpluv":[281.540806859048416,305.816582895375404,51.7249932896939271],"hsluv":[281.540806859048416,99.9999999999991189,51.7249932896939271]},"#885500":{"lch":[40.7868302215615941,57.8204075903908716,44.0255445375638317],"luv":[40.7868302215615941,41.5746091122878738,40.1839695784202107],"rgb":[0.533333333333333326,0.333333333333333315,0],"xyz":[0.134014735183400707,0.117319151919440201,0.0155871309747999068],"hpluv":[44.0255445375638317,179.887306981779091,40.7868302215615941],"hsluv":[44.0255445375638317,100.000000000002402,40.7868302215615941]},"#885511":{"lch":[40.8520464566488215,55.8013246771799061,42.6953812551229817],"luv":[40.8520464566488215,41.012258348334349,37.838901951530346],"rgb":[0.533333333333333326,0.333333333333333315,0.0666666666666666657],"xyz":[0.135026400683037839,0.117723818119295054,0.0209152359395555383],"hpluv":[42.6953812551229817,173.328515822040885,40.8520464566488215],"hsluv":[42.6953812551229817,94.5141207032234121,40.8520464566488215]},"#885522":{"lch":[40.9725457623763205,52.2529579480882163,40.0436802938645613],"luv":[40.9725457623763205,40.0024704692244413,33.6180601862079769],"rgb":[0.533333333333333326,0.333333333333333315,0.133333333333333331],"xyz":[0.136901758821514841,0.118473961374685868,0.0307921221355347344],"hpluv":[40.0436802938645613,161.829338044896133,40.9725457623763205],"hsluv":[40.0436802938645613,84.6783920295854813,40.9725457623763205]},"#885533":{"lch":[41.169842808691,46.965215190705,35.0963808532685348],"luv":[41.169842808691,38.426283274472091,27.0028182162390955],"rgb":[0.533333333333333326,0.333333333333333315,0.2],"xyz":[0.139989509553972602,0.119709061667668981,0.0470542759931458776],"hpluv":[35.0963808532685348,144.75595347357384,41.169842808691],"hsluv":[35.0963808532685348,69.3663942781120113,41.169842808691]},"#885544":{"lch":[41.4523140669009891,40.5881659839312263,26.5063976077417607],"luv":[41.4523140669009891,36.321721997537459,18.1144066718387258],"rgb":[0.533333333333333326,0.333333333333333315,0.266666666666666663],"xyz":[0.144447504798191462,0.121492259765356561,0.0705330509460325161],"hpluv":[26.5063976077417607,124.248162385526584,41.4523140669009891],"hsluv":[26.5063976077417607,49.0053368988820708,41.4523140669009891]},"#885555":{"lch":[41.8258216452066449,34.5587016635497619,12.1770506300621708],"luv":[41.8258216452066449,33.7811467851905647,7.28958040957408926],"rgb":[0.533333333333333326,0.333333333333333315,0.333333333333333315],"xyz":[0.150409918837553447,0.123877225381101394,0.101935098220006432],"hpluv":[12.1770506300621708,104.846095879990827,41.8258216452066449],"hsluv":[12.1770506300621708,24.5686900376428454,41.8258216452066449]},"#885566":{"lch":[42.2941086985740071,31.3312262907584227,350.801819307985852],"luv":[42.2941086985740071,30.9283487442626033,-5.00829160852097477],"rgb":[0.533333333333333326,0.333333333333333315,0.4],"xyz":[0.157994914611061632,0.126911223690504699,0.141882742627150393],"hpluv":[350.801819307985852,94.0019456509277092,42.2941086985740071],"hsluv":[350.801819307985852,29.8132814869556348,42.2941086985740071]},"#885577":{"lch":[42.8590433503379202,33.3514130793808121,326.760730108285],"luv":[42.8590433503379202,27.8947491372056646,-18.2811302977648822],"rgb":[0.533333333333333326,0.333333333333333315,0.466666666666666674],"xyz":[0.167308927631263538,0.130636828898585522,0.190936544533548302],"hpluv":[326.760730108285,98.7440857113442263,42.8590433503379202],"hsluv":[326.760730108285,35.3342565461126838,42.8590433503379202]},"#885588":{"lch":[43.5208237898043535,40.5407907233736822,307.71501294924542],"luv":[43.5208237898043535,24.8001938501248809,-32.0703304858651137],"rgb":[0.533333333333333326,0.333333333333333315,0.533333333333333326],"xyz":[0.178449344733207393,0.13509299573936312,0.24960940793712047],"hpluv":[307.71501294924542,118.204615389413121,43.5208237898043535],"hsluv":[307.71501294924542,40.8951968507306276,43.5208237898043535]},"#885599":{"lch":[44.278184332936334,50.8805981998246,295.296495298175159],"luv":[44.278184332936334,21.7414099229374891,-46.0015909261276477],"rgb":[0.533333333333333326,0.333333333333333315,0.6],"xyz":[0.191506308842280093,0.140315781382992277,0.318376085578238377],"hpluv":[295.296495298175159,145.814841874582299,44.278184332936334],"hsluv":[295.296495298175159,46.3068912836000735,44.278184332936334]},"#8855aa":{"lch":[45.1286132569148819,62.6826496939872868,287.441560465434577],"luv":[45.1286132569148819,18.7880516159354372,-59.8006997378464717],"rgb":[0.533333333333333326,0.333333333333333315,0.66666666666666663],"xyz":[0.206564001807532649,0.146338858569093372,0.397679935195237],"hpluv":[287.441560465434577,176.252255995348207,45.1286132569148819],"hsluv":[287.441560465434577,51.4349240401982044,45.1286132569148819]},"#8855bb":{"lch":[46.0685799041538857,75.0110486022347374,282.303621490188448],"luv":[46.0685799041538857,15.9842650126874819,-73.2882029006783284],"rgb":[0.533333333333333326,0.333333333333333315,0.733333333333333282],"xyz":[0.223701593914869268,0.15319389541202813,0.487937920293878724],"hpluv":[282.303621490188448,206.613996430434867,46.0685799041538857],"hsluv":[282.303621490188448,56.1963190544194191,46.0685799041538857]},"#8855cc":{"lch":[47.0937627302438173,87.3889723072186229,278.789341148015808],"luv":[47.0937627302438173,13.3532090014702405,-86.3627482788434406],"rgb":[0.533333333333333326,0.333333333333333315,0.8],"xyz":[0.242993969358591022,0.160910845589516932,0.58954443096414888],"hpluv":[278.789341148015808,235.468364438494291,47.0937627302438173],"hsluv":[278.789341148015808,67.0071532265272083,47.0937627302438173]},"#8855dd":{"lch":[48.1992684502362323,99.579643468316263,276.285619014825784],"luv":[48.1992684502362323,10.9024601244232162,-98.9810171523426163],"rgb":[0.533333333333333326,0.333333333333333315,0.866666666666666696],"xyz":[0.264512294909224566,0.169518175809770466,0.702874278864154878],"hpluv":[276.285619014825784,262.161822059859048,48.1992684502362323],"hsluv":[276.285619014825784,77.9008511174594673,48.1992684502362323]},"#8855ee":{"lch":[49.3798334670730128,111.473561000814087,274.439637972028379],"luv":[49.3798334670730128,8.62903279282213198,-111.139077714648238],"rgb":[0.533333333333333326,0.333333333333333315,0.933333333333333348],"xyz":[0.288324475175399275,0.179043047916240511,0.828285094932678101],"hpluv":[274.439637972028379,286.45841220928196,49.3798334670730128],"hsluv":[274.439637972028379,88.8665998649397295,49.3798334670730128]},"#8855ff":{"lch":[50.6300011250937416,123.030386306339324,273.039422554437692],"luv":[50.6300011250937416,6.52344684402536235,-122.857318039912712],"rgb":[0.533333333333333326,0.333333333333333315,1],"xyz":[0.314495523585230696,0.189511467280173207,0.96611928322446],"hpluv":[273.039422554437692,308.349875308867752,50.6300011250937416],"hsluv":[273.039422554437692,99.9999999999992,50.6300011250937416]},"#ffdd00":{"lch":[88.435570144315335,99.3071523162376195,71.7429005549186911],"luv":[88.435570144315335,31.1110916577435432,94.3080615696447211],"rgb":[1,0.866666666666666696,0],"xyz":[0.670943989879631442,0.729745387098879927,0.105515215586815703],"hpluv":[71.7429005549186911,382.363935262913174,88.435570144315335],"hsluv":[71.7429005549186911,100.000000000012946,88.435570144315335]},"#ffdd11":{"lch":[88.454870819445,98.4678340856778,71.6448189166009826],"luv":[88.454870819445,31.0081800872079896,93.4580500395971683],"rgb":[1,0.866666666666666696,0.0666666666666666657],"xyz":[0.671955655379268602,0.730150053298734836,0.110843320551571339],"hpluv":[71.6448189166009826,379.826472639876158,88.454870819445],"hsluv":[71.6448189166009826,100.00000000001296,88.454870819445]},"#ffdd22":{"lch":[88.4906302718539735,96.9204819130462,71.4594307996413],"luv":[88.4906302718539735,30.8183922605744947,91.8901872494037093],"rgb":[1,0.866666666666666696,0.133333333333333331],"xyz":[0.673831013517745547,0.730900196554125636,0.120720206747550532],"hpluv":[71.4594307996413,375.129750349680876,88.4906302718539735],"hsluv":[71.4594307996413,100.00000000001296,88.4906302718539735]},"#ffdd33":{"lch":[88.5494544369894641,94.3967280931520776,71.1436744567929793],"luv":[88.5494544369894641,30.5086598694284135,89.330643945199526],"rgb":[1,0.866666666666666696,0.2],"xyz":[0.676918764250203364,0.732135296847108763,0.136982360605161668],"hpluv":[71.1436744567929793,367.416320973762822,88.5494544369894641],"hsluv":[71.1436744567929793,100.000000000013216,88.5494544369894641]},"#ffdd44":{"lch":[88.6342662809689301,90.8049878425315455,70.6631891871382152],"luv":[88.6342662809689301,30.0674100616276441,85.6825342136204284],"rgb":[1,0.866666666666666696,0.266666666666666663],"xyz":[0.681376759494422224,0.733918494944796329,0.160461135558048307],"hpluv":[70.6631891871382152,356.322085242203968,88.6342662809689301],"hsluv":[70.6631891871382152,100.000000000013173,88.6342662809689301]},"#ffdd55":{"lch":[88.7474847112806486,86.0957791731635353,69.970644696948483],"luv":[88.7474847112806486,29.4879375414461293,80.8884709398435433],"rgb":[1,0.866666666666666696,0.333333333333333315],"xyz":[0.687339173533784153,0.736303460560541079,0.191863182832022222],"hpluv":[69.970644696948483,341.559684906391112,88.7474847112806486],"hsluv":[69.970644696948483,100.000000000013429,88.7474847112806486]},"#ffdd66":{"lch":[88.8911610589964454,80.258955992054581,68.9956984045855819],"luv":[88.8911610589964454,28.7678627944319345,74.9260307715235427],"rgb":[1,0.866666666666666696,0.4],"xyz":[0.694924169307292394,0.739337458869944397,0.231810827239166184],"hpluv":[68.9956984045855819,322.902183683526573,88.8911610589964454],"hsluv":[68.9956984045855819,100.000000000013586,88.8911610589964454]},"#ffdd77":{"lch":[89.0670520916409885,73.323747836811151,67.6276760217336346],"luv":[89.0670520916409885,27.9087592291374555,67.8046691248198812],"rgb":[1,0.866666666666666696,0.466666666666666674],"xyz":[0.704238182327494244,0.743063064078025248,0.280864629145564093],"hpluv":[67.6276760217336346,300.178104609939055,89.0670520916409885],"hsluv":[67.6276760217336346,100.000000000014367,89.0670520916409885]},"#ffdd88":{"lch":[89.2766635023192379,65.3617696880632622,65.6822421460803554],"luv":[89.2766635023192379,26.9157684368328205,59.5625918359016637],"rgb":[1,0.866666666666666696,0.533333333333333326],"xyz":[0.715378599429438156,0.747519230918802791,0.339537492549136233],"hpluv":[65.6822421460803554,273.280966903928913,89.2766635023192379],"hsluv":[65.6822421460803554,100.00000000001468,89.2766635023192379]},"#ffdd99":{"lch":[89.5212778802452362,56.4966374008110606,62.8311838382076928],"luv":[89.5212778802452362,25.7971434460875209,50.2630821540094814],"rgb":[1,0.866666666666666696,0.6],"xyz":[0.7284355635385108,0.752742016562432,0.408304170190254168],"hpluv":[62.8311838382076928,242.212083001239,89.5212778802452362],"hsluv":[62.8311838382076928,100.000000000014893,89.5212778802452362]},"#ffddaa":{"lch":[89.8019739344538408,46.9317870748453103,58.439957868293348],"luv":[89.8019739344538408,24.5637119196041205,39.9902074859498],"rgb":[1,0.866666666666666696,0.66666666666666663],"xyz":[0.743493256503763411,0.75876509374853307,0.487608019807252768],"hpluv":[58.439957868293348,207.216087370130765,89.8019739344538408],"hsluv":[58.439957868293348,100.000000000015916,89.8019739344538408]},"#ffddbb":{"lch":[90.1196406145249114,37.0342016806554142,51.1553076529108282],"luv":[90.1196406145249114,23.228278171915747,28.8440494260352231],"rgb":[1,0.866666666666666696,0.733333333333333282],"xyz":[0.7606308486111,0.765620130591467829,0.57786600490589457],"hpluv":[51.1553076529108282,169.207898233907059,90.1196406145249114],"hsluv":[51.1553076529108282,100.00000000001647,90.1196406145249114]},"#ffddcc":{"lch":[90.4749882420216665,27.6093496047032829,37.8361109659034085],"luv":[90.4749882420216665,21.8049964890922183,16.9357111957368183],"rgb":[1,0.866666666666666696,0.8],"xyz":[0.779923224054821729,0.773337080768956686,0.679472515576164726],"hpluv":[37.8361109659034085,131.228146902908946,90.4749882420216665],"hsluv":[37.8361109659034085,100.000000000017565,90.4749882420216665]},"#ffdddd":{"lch":[90.8685579434819743,20.7762078419716971,12.1770506300632935],"luv":[90.8685579434819743,20.3087527298379129,4.38239373528981613],"rgb":[1,0.866666666666666696,0.866666666666666696],"xyz":[0.801441549605455328,0.781944410989210192,0.792802363476170724],"hpluv":[12.1770506300632935,103.332662997484363,90.8685579434819743],"hsluv":[12.1770506300632935,100.000000000018645,90.8685579434819743]},"#ffddee":{"lch":[91.3007301977477255,20.6730653908416642,335.121130580225611],"luv":[91.3007301977477255,18.7545890012647547,-8.69718483462634318],"rgb":[1,0.866666666666666696,0.933333333333333348],"xyz":[0.82525372987163,0.791469283095680209,0.918213179544694],"hpluv":[335.121130580225611,108.301670079840079,91.3007301977477255],"hsluv":[335.121130580225611,100.000000000019696,91.3007301977477255]},"#ffddff":{"lch":[91.7717330140538081,28.0468143452174594,307.715012949251673],"luv":[91.7717330140538081,17.1571994583452359,-22.1868046744377736],"rgb":[1,0.866666666666666696,1],"xyz":[0.851424778281461458,0.801937702459612933,1.05604736783647568],"hpluv":[307.715012949251673,155.925616416863875,91.7717330140538081],"hsluv":[307.715012949251673,100.000000000021274,91.7717330140538081]},"#aa5500":{"lch":[45.6948541105979729,81.8101604081173406,31.0178153240564285],"luv":[45.6948541105979729,70.1118895783240674,42.1571498770823254],"rgb":[0.66666666666666663,0.333333333333333315,0],"xyz":[0.198255511194170453,0.150443302049994065,0.0185984173503046732],"hpluv":[31.0178153240564285,227.184802334875343,45.6948541105979729],"hsluv":[31.0178153240564285,100.000000000002132,45.6948541105979729]},"#aa5511":{"lch":[45.7501207141343542,80.2053049231342357,30.0334267749456458],"luv":[45.7501207141343542,69.4364235827854088,40.1431690060082786],"rgb":[0.66666666666666663,0.333333333333333315,0.0666666666666666657],"xyz":[0.199267176693807585,0.150847968249848918,0.0239265223150603029],"hpluv":[30.0334267749456458,222.459100300712947,45.7501207141343542],"hsluv":[30.0334267749456458,95.7485290168496874,45.7501207141343542]},"#aa5522":{"lch":[45.8523093955831129,77.3637164970789826,28.1463245173948593],"luv":[45.8523093955831129,68.2151287979892231,36.4943945464800308],"rgb":[0.66666666666666663,0.333333333333333315,0.133333333333333331],"xyz":[0.201142534832284586,0.151598111505239747,0.0338034085110395],"hpluv":[28.1463245173948593,214.099393521154866,45.8523093955831129],"hsluv":[28.1463245173948593,88.0687786146531835,45.8523093955831129]},"#aa5533":{"lch":[46.0198296754266707,73.057054041475979,24.8605966968797674],"luv":[46.0198296754266707,66.2871018342682845,30.7140566456547255],"rgb":[0.66666666666666663,0.333333333333333315,0.2],"xyz":[0.20423028556474232,0.152833211798222846,0.0500655623686506457],"hpluv":[24.8605966968797674,201.444992058953261,46.0198296754266707],"hsluv":[24.8605966968797674,75.9647480733224683,46.0198296754266707]},"#aa5544":{"lch":[46.260105303202792,67.6400753638857,19.7251402693972757],"luv":[46.260105303202792,63.6711277752059743,22.829088529013422],"rgb":[0.66666666666666663,0.333333333333333315,0.266666666666666663],"xyz":[0.208688280808961207,0.154616409895910439,0.0735443373215372842],"hpluv":[19.7251402693972757,185.539675327038225,46.260105303202792],"hsluv":[19.7251402693972757,59.5831884891410581,46.260105303202792]},"#aa5555":{"lch":[46.5785950143652201,61.8404850960729462,12.1770506300619488],"luv":[46.5785950143652201,60.4491026496292108,13.0442165641410206],"rgb":[0.66666666666666663,0.333333333333333315,0.333333333333333315],"xyz":[0.21465069484832322,0.157001375511655272,0.1049463845955112],"hpluv":[12.1770506300619488,168.471262237657498,46.5785950143652201],"hsluv":[12.1770506300619488,39.4780386186733381,46.5785950143652201]},"#aa5566":{"lch":[46.9791292969753727,56.7719582569154682,1.70455911852653919],"luv":[46.9791292969753727,56.7468364589401801,1.68872621441415594],"rgb":[0.66666666666666663,0.333333333333333315,0.4],"xyz":[0.222235690621831378,0.160035373821058563,0.144894029002655161],"hpluv":[1.70455911852653919,153.34451205140752,46.9791292969753727],"hsluv":[1.70455911852653919,42.9013314457092818,46.9791292969753727]},"#aa5577":{"lch":[47.4641008255870247,53.815805251865207,348.374645401059922],"luv":[47.4641008255870247,52.7118371029350072,-10.8444974129891012],"rgb":[0.66666666666666663,0.333333333333333315,0.466666666666666674],"xyz":[0.231549703642033311,0.163760979029139386,0.193947830909053071],"hpluv":[348.374645401059922,143.874527939012694,47.4641008255870247],"hsluv":[348.374645401059922,46.6096363259647291,47.4641008255870247]},"#aa5588":{"lch":[48.0346061313586716,54.1759936988691209,333.519859036575326],"luv":[48.0346061313586716,48.4923339918738,-24.1564036495598238],"rgb":[0.66666666666666663,0.333333333333333315,0.533333333333333326],"xyz":[0.242690120743977111,0.168217145869916984,0.252620694312625238],"hpluv":[333.519859036575326,143.117248614217317,48.0346061313586716],"hsluv":[333.519859036575326,50.4580944804944309,48.0346061313586716]},"#aa5599":{"lch":[48.6905763376225,58.2309730669685877,319.412334073918828],"luv":[48.6905763376225,44.2212637341432782,-37.885697275903027],"rgb":[0.66666666666666663,0.333333333333333315,0.6],"xyz":[0.255747084853049866,0.173439931513546142,0.321387371953743117],"hpluv":[319.412334073918828,151.756904292295189,48.6905763376225],"hsluv":[319.412334073918828,54.3174516364451492,48.6905763376225]},"#aa55aa":{"lch":[49.4309115490906095,65.3990862514302904,307.715012949244453],"luv":[49.4309115490906095,40.0068668547544135,-51.7348150377284242],"rgb":[0.66666666666666663,0.333333333333333315,0.66666666666666663],"xyz":[0.270804777818302367,0.179463008699647236,0.400691221570741718],"hpluv":[307.715012949244453,167.885190443837445,49.4309115490906095],"hsluv":[307.715012949244453,58.0831627335764651,49.4309115490906095]},"#aa55bb":{"lch":[50.2536225490081137,74.6889496830887651,298.754319252296796],"luv":[50.2536225490081137,35.9294822147829578,-65.4790921786531896],"rgb":[0.66666666666666663,0.333333333333333315,0.733333333333333282],"xyz":[0.287942369925639041,0.186318045542582,0.490949206669383464],"hpluv":[298.754319252296796,188.594188212432869,50.2536225490081137],"hsluv":[298.754319252296796,61.6784311565058445,50.2536225490081137]},"#aa55cc":{"lch":[51.1559779262539394,85.2173265065914194,292.086991032215337],"luv":[51.1559779262539394,32.0428980728004476,-78.9635702082114],"rgb":[0.66666666666666663,0.333333333333333315,0.8],"xyz":[0.307234745369360795,0.194034995720070796,0.59255571733965362],"hpluv":[292.086991032215337,211.383381159177,51.1559779262539394],"hsluv":[292.086991032215337,65.0527897247966536,51.1559779262539394]},"#aa55dd":{"lch":[52.1346521614624407,96.3659410029227,287.126655540846059],"luv":[52.1346521614624407,28.3783197098194826,-92.0927008824589137],"rgb":[0.66666666666666663,0.333333333333333315,0.866666666666666696],"xyz":[0.328753070919994284,0.20264232594032433,0.705885565239659618],"hpluv":[287.126655540846059,234.550526854663673,52.1346521614624407],"hsluv":[287.126655540846059,75.3446722268955256,52.1346521614624407]},"#aa55ee":{"lch":[53.1858694266106227,107.745747725204239,283.388779775386126],"luv":[53.1858694266106227,24.9493252566021582,-104.817352199450397],"rgb":[0.66666666666666663,0.333333333333333315,0.933333333333333348],"xyz":[0.352565251186169049,0.212167198046794375,0.831296381308182841],"hpluv":[283.388779775386126,257.065149407391289,53.1858694266106227],"hsluv":[283.388779775386126,87.5522298773574335,53.1858694266106227]},"#aa55ff":{"lch":[54.3055382240479361,119.125691570750178,280.523377624217346],"luv":[54.3055382240479361,21.7567225446561139,-117.12205350114192],"rgb":[0.66666666666666663,0.333333333333333315,1],"xyz":[0.378736299596000414,0.222635617410727071,0.969130569599964686],"hpluv":[280.523377624217346,278.356033354379861,54.3055382240479361],"hsluv":[280.523377624217346,99.999999999999,54.3055382240479361]},"#886600":{"lch":[45.272583339231268,54.7393681124008964,58.6614018365849361],"luv":[45.272583339231268,28.4696504737342408,46.7533680417607513],"rgb":[0.533333333333333326,0.4,0],"xyz":[0.149042792889247183,0.147375267331133541,0.020596483543415256],"hpluv":[58.6614018365849361,153.427719347991228,45.272583339231268],"hsluv":[58.6614018365849361,100.000000000002288,45.272583339231268]},"#886611":{"lch":[45.3286132830504442,52.7569286908504935,57.8019218571504112],"luv":[45.3286132830504442,28.1114182485843394,44.6434954830448234],"rgb":[0.533333333333333326,0.4,0.0666666666666666657],"xyz":[0.150054458388884315,0.147779933530988394,0.0259245885081708857],"hpluv":[57.8019218571504112,147.688404254652824,45.3286132830504442],"hsluv":[57.8019218571504112,95.5933263309827765,45.3286132830504442]},"#886622":{"lch":[45.4322079122274616,49.2027541487777427,56.0700181971155658],"luv":[45.4322079122274616,27.4639619392241023,40.8245246197174367],"rgb":[0.533333333333333326,0.4,0.133333333333333331],"xyz":[0.151929816527361317,0.148530076786379223,0.0358014747041500853],"hpluv":[56.0700181971155658,137.424731357888106,45.4322079122274616],"hsluv":[56.0700181971155658,87.640709221506242,45.4322079122274616]},"#886633":{"lch":[45.6020177209920377,43.6934420281053448,52.7580970187872822],"luv":[45.6020177209920377,26.4424624059276816,34.7838045385277539],"rgb":[0.533333333333333326,0.4,0.2],"xyz":[0.155017567259819078,0.149765177079362322,0.0520636285617612285],"hpluv":[52.7580970187872822,121.582627853675135,45.6020177209920377],"hsluv":[52.7580970187872822,75.126145239043538,45.6020177209920377]},"#886644":{"lch":[45.8455444844743383,36.5157977851307862,46.6690567683987183],"luv":[45.8455444844743383,25.057552877875338,26.56167411246971],"rgb":[0.533333333333333326,0.4,0.266666666666666663],"xyz":[0.159475562504037938,0.151548375177049915,0.0755424035146478601],"hpluv":[46.6690567683987183,101.07016738030697,45.8455444844743383],"hsluv":[46.6690567683987183,58.2269221932267413,45.8455444844743383]},"#886655":{"lch":[46.1682850891648,28.5288655346450497,35.057100942904512],"luv":[46.1682850891648,23.3531590809093643,16.3867669061227161],"rgb":[0.533333333333333326,0.4,0.333333333333333315],"xyz":[0.165437976543399923,0.153933340792794748,0.106944450788621775],"hpluv":[35.057100942904512,78.4115584201214517,46.1682850891648],"hsluv":[35.057100942904512,37.5458750067509825,46.1682850891648]},"#886666":{"lch":[46.5740725388720946,21.8884171395184417,12.1770506300623786],"luv":[46.5740725388720946,21.3959378301945833,4.61699569417310141],"rgb":[0.533333333333333326,0.4,0.4],"xyz":[0.173022972316908108,0.156967339102198039,0.146892095195765737],"hpluv":[12.1770506300623786,59.6361320849851921,46.5740725388720946],"hsluv":[12.1770506300623786,13.9745942082290213,46.5740725388720946]},"#886677":{"lch":[47.0652698878111053,20.9860757761626395,336.621799391030947],"luv":[47.0652698878111053,19.2632377900225293,-8.32724722389627559],"rgb":[0.533333333333333326,0.4,0.466666666666666674],"xyz":[0.18233698533711,0.160692944310278862,0.195945897102163646],"hpluv":[336.621799391030947,56.5809206524471051,47.0652698878111053],"hsluv":[336.621799391030947,19.7183189325496855,47.0652698878111053]},"#886688":{"lch":[47.6429159175320649,27.8420771343032278,307.715012949247239],"luv":[47.6429159175320649,17.0319546757823481,-22.0248445868429776],"rgb":[0.533333333333333326,0.4,0.533333333333333326],"xyz":[0.193477402439053869,0.16514911115105646,0.254618760505735842],"hpluv":[307.715012949247239,74.1553731862279335,47.6429159175320649],"hsluv":[307.715012949247239,25.6555006249089494,47.6429159175320649]},"#886699":{"lch":[48.306860672000596,39.0046617113806562,292.251886736336132],"luv":[48.306860672000596,14.770249996667463,-36.0999078981538304],"rgb":[0.533333333333333326,0.4,0.6],"xyz":[0.206534366548126569,0.170371896794685618,0.323385438146853721],"hpluv":[292.251886736336132,102.458272059709785,48.306860672000596],"hsluv":[292.251886736336132,31.5854767603208231,48.306860672000596]},"#8866aa":{"lch":[49.0559053000777112,51.7871044207240132,284.005102499462396],"luv":[49.0559053000777112,12.5329093477081912,-50.2476901714407305],"rgb":[0.533333333333333326,0.4,0.66666666666666663],"xyz":[0.221592059513379125,0.176394973980786712,0.402689287763852322],"hpluv":[284.005102499462396,133.958310232957899,49.0559053000777112],"hsluv":[284.005102499462396,39.6059098285329867,49.0559053000777112]},"#8866bb":{"lch":[49.8879495217490074,65.0723394771694501,279.16089377463328],"luv":[49.8879495217490074,10.3599978518109275,-64.242352148271],"rgb":[0.533333333333333326,0.4,0.733333333333333282],"xyz":[0.238729651620715744,0.183250010823721471,0.492947272862494068],"hpluv":[279.16089377463328,165.516042277675325,49.8879495217490074],"hsluv":[279.16089377463328,51.4342030459355897,49.8879495217490074]},"#8866cc":{"lch":[50.800144438276476,78.3702679805165161,276.063171305995638],"luv":[50.800144438276476,8.2778522611756955,-77.9318680982312912],"rgb":[0.533333333333333326,0.4,0.8],"xyz":[0.258022027064437498,0.190966961001210273,0.594553783532764224],"hpluv":[276.063171305995638,195.760791019658512,50.800144438276476],"hsluv":[276.063171305995638,63.370404435102877,50.800144438276476]},"#8866dd":{"lch":[51.7890458420015278,91.4433004674113903,273.951375062119212],"luv":[51.7890458420015278,6.3013441888180548,-91.225929766636682],"rgb":[0.533333333333333326,0.4,0.866666666666666696],"xyz":[0.279540352615071042,0.199574291221463807,0.707883631432770222],"hpluv":[273.951375062119212,224.054313572832513,51.7890458420015278],"hsluv":[273.951375062119212,75.4110532620532,51.7890458420015278]},"#8866ee":{"lch":[52.8507624936088831,104.176067138923727,272.440799986921],"luv":[52.8507624936088831,4.4365578942807,-104.081554170680207],"rgb":[0.533333333333333326,0.4,0.933333333333333348],"xyz":[0.303352532881245751,0.209099163327933851,0.833294447501293445],"hpluv":[272.440799986921,250.124381092910085,52.8507624936088831],"hsluv":[272.440799986921,87.5962217171162365,52.8507624936088831]},"#8866ff":{"lch":[53.9810943197935273,116.520298408763196,271.319576027424205],"luv":[53.9810943197935273,2.6833355157121912,-116.48939716462327],"rgb":[0.533333333333333326,0.4,1],"xyz":[0.329523581291077172,0.219567582691866547,0.97112863579307529],"hpluv":[271.319576027424205,273.904539658900717,53.9810943197935273],"hsluv":[271.319576027424205,99.9999999999990621,53.9810943197935273]},"#ffee00":{"lch":[92.75564548426334,102.358730475882979,79.2433869538170228],"luv":[92.75564548426334,19.1039702538988,100.560171167180329],"rgb":[1,0.933333333333333348,0],"xyz":[0.718122766220146147,0.824102939779910892,0.121241474366986887],"hpluv":[79.2433869538170228,651.393632104361359,92.75564548426334],"hsluv":[79.2433869538170228,100.000000000024428,92.75564548426334]},"#ffee11":{"lch":[92.7734436379168,101.564402459740549,79.2015044483446218],"luv":[92.7734436379168,19.0286516433192254,99.765917344759373],"rgb":[1,0.933333333333333348,0.0666666666666666657],"xyz":[0.719134431719783307,0.824507605979765801,0.12656957933174251],"hpluv":[79.2015044483446218,648.021125158270593,92.7734436379168],"hsluv":[79.2015044483446218,100.000000000024428,92.7734436379168]},"#ffee22":{"lch":[92.8064212727168183,100.098587827824673,79.1224559985664797],"luv":[92.8064212727168183,18.8896613956421291,98.3000914418838079],"rgb":[1,0.933333333333333348,0.133333333333333331],"xyz":[0.721009789858260253,0.825257749235156601,0.136446465527721716],"hpluv":[79.1224559985664797,641.762708667564539,92.8064212727168183],"hsluv":[79.1224559985664797,100.000000000024357,92.8064212727168183]},"#ffee33":{"lch":[92.8606749716073665,97.7038183815635506,78.9881622996309147],"luv":[92.8606749716073665,18.6625824309063972,95.9048702796014396],"rgb":[1,0.933333333333333348,0.2],"xyz":[0.72409754059071807,0.826492849528139728,0.152708619385332867],"hpluv":[78.9881622996309147,631.438241912838748,92.8606749716073665],"hsluv":[78.9881622996309147,100.000000000024599,92.8606749716073665]},"#ffee44":{"lch":[92.9389094487226828,94.2867391890675606,78.7846200921967181],"luv":[92.9389094487226828,18.3385503337116411,92.4861436030564192],"rgb":[1,0.933333333333333348,0.266666666666666663],"xyz":[0.728555535834936929,0.828276047625827294,0.176187394338219505],"hpluv":[78.7846200921967181,616.484076987319668,92.9389094487226828],"hsluv":[78.7846200921967181,100.000000000025381,92.9389094487226828]},"#ffee55":{"lch":[93.0433700241155179,89.7896797607108,78.4929149488566082],"luv":[93.0433700241155179,17.9120631143144244,87.984911129805738],"rgb":[1,0.933333333333333348,0.333333333333333315],"xyz":[0.734517949874298859,0.830661013241572,0.207589441612193393],"hpluv":[78.4929149488566082,596.384103057951847,93.0433700241155179],"hsluv":[78.4929149488566082,100.000000000025906,93.0433700241155179]},"#ffee66":{"lch":[93.1759694096933,84.1867368500463,78.0854442567743661],"luv":[93.1759694096933,17.3805845725397461,82.3730656305550895],"rgb":[1,0.933333333333333348,0.4],"xyz":[0.7421029456478071,0.833695011550975362,0.247537086019337382],"hpluv":[78.0854442567743661,570.62648367707834,93.1759694096933],"hsluv":[78.0854442567743661,100.000000000026517,93.1759694096933]},"#ffee77":{"lch":[93.3383558005883742,77.4816602435733586,77.5195453952684659],"luv":[93.3383558005883742,16.7442947506152713,75.6507519288807515],"rgb":[1,0.933333333333333348,0.466666666666666674],"xyz":[0.751416958668009,0.837420616759056213,0.296590887925735291],"hpluv":[77.5195453952684659,538.663675570032183,93.3383558005883742],"hsluv":[77.5195453952684659,100.00000000002693,93.3383558005883742]},"#ffee88":{"lch":[93.5319535615141433,69.7063855050026433,76.7254067288761235],"luv":[93.5319535615141433,16.0058531534094222,67.8438858336072599],"rgb":[1,0.933333333333333348,0.533333333333333326],"xyz":[0.762557375769952861,0.841876783599833756,0.355263751329307431],"hpluv":[76.7254067288761235,499.867858345774721,93.5319535615141433],"hsluv":[76.7254067288761235,100.000000000028109,93.5319535615141433]},"#ffee99":{"lch":[93.7579894103796647,60.9203426164438397,75.5807218945013517],"luv":[93.7579894103796647,15.1701259512809905,59.0013171304435744],"rgb":[1,0.933333333333333348,0.6],"xyz":[0.775614339879025505,0.847099569243463,0.424030428970425366],"hpluv":[75.5807218945013517,453.479030486808085,93.7579894103796647],"hsluv":[75.5807218945013517,100.000000000029459,93.7579894103796647]},"#ffeeaa":{"lch":[94.0175103342715204,51.2122166590618946,73.8511258956299],"luv":[94.0175103342715204,14.2438643230739057,49.191497886124175],"rgb":[1,0.933333333333333348,0.66666666666666663],"xyz":[0.790672032844278116,0.853122646429564,0.503334278587424],"hpluv":[73.8511258956299,398.552269307706354,94.0175103342715204],"hsluv":[73.8511258956299,100.00000000003169,94.0175103342715204]},"#ffeebb":{"lch":[94.3113965930375855,40.7102572776027571,71.0277189369888],"luv":[94.3113965930375855,13.2353397134719373,38.4987120599845625],"rgb":[1,0.933333333333333348,0.733333333333333282],"xyz":[0.80780962495161468,0.859977683272498794,0.593592263686065658],"hpluv":[71.0277189369888,333.94796839081863,94.3113965930375855],"hsluv":[71.0277189369888,100.000000000032855,94.3113965930375855]},"#ffeecc":{"lch":[94.6403717602024841,29.6267857036886042,65.7803861656043125],"luv":[94.6403717602024841,12.1539519061426287,27.0190281874729799],"rgb":[1,0.933333333333333348,0.8],"xyz":[0.827102000395336434,0.867694633449987651,0.695198774356335814],"hpluv":[65.7803861656043125,258.601677072085806,94.6403717602024841],"hsluv":[65.7803861656043125,100.000000000035726,94.6403717602024841]},"#ffeedd":{"lch":[95.0050109981125814,18.4911495042727,53.4580761074439366],"luv":[95.0050109981125814,11.0098304435300403,14.8561853648264481],"rgb":[1,0.933333333333333348,0.866666666666666696],"xyz":[0.84862032594597,0.876301963670241157,0.808528622256341811],"hpluv":[53.4580761074439366,173.670551799097524,95.0050109981125814],"hsluv":[53.4580761074439366,100.000000000039279,95.0050109981125814]},"#ffeeee":{"lch":[95.4057483293867,10.0393308083340358,12.1770506300655121],"luv":[95.4057483293867,9.81345048674430487,2.11762900985580904],"rgb":[1,0.933333333333333348,0.933333333333333348],"xyz":[0.872432506212144743,0.885826835776711174,0.933939438324865],"hpluv":[12.1770506300655121,102.829227108855335,95.4057483293867],"hsluv":[12.1770506300655121,100.000000000042746,95.4057483293867]},"#ffeeff":{"lch":[95.8428833991312104,14.017983351086059,307.715012949261848],"luv":[95.8428833991312104,8.57528179129596,-11.0891117512266888],"rgb":[1,0.933333333333333348,1],"xyz":[0.898603554621976164,0.896295255140643898,1.07177362661664688],"hpluv":[307.715012949261848,159.207478793902965,95.8428833991312104],"hsluv":[307.715012949261848,100.000000000047876,95.8428833991312104]},"#aa6600":{"lch":[49.5566255632669623,74.0434564420528574,40.5370999312324685],"luv":[49.5566255632669623,56.2719368465296,48.1238253407432595],"rgb":[0.66666666666666663,0.4,0],"xyz":[0.213283568900016929,0.180499417461687406,0.0236077699189200241],"hpluv":[40.5370999312324685,189.593866720893345,49.5566255632669623],"hsluv":[40.5370999312324685,100.000000000002302,49.5566255632669623]},"#aa6611":{"lch":[49.6055800152373934,72.4782904829715449,39.6736286483530876],"luv":[49.6055800152373934,55.7860674256664097,46.2711278500211662],"rgb":[0.66666666666666663,0.4,0.0666666666666666657],"xyz":[0.214295234399654061,0.180904083661542259,0.0289358748836756538],"hpluv":[39.6736286483530876,185.402990863318706,49.6055800152373934],"hsluv":[39.6736286483530876,96.4267217319678878,49.6055800152373934]},"#aa6622":{"lch":[49.6961357673044404,69.6784302133091,38.0044715349972151],"luv":[49.6961357673044404,54.9040042209680124,42.902610147809348],"rgb":[0.66666666666666663,0.4,0.133333333333333331],"xyz":[0.216170592538131062,0.181654226916933087,0.0388127610796548533],"hpluv":[38.0044715349972151,177.916023719914563,49.6961357673044404],"hsluv":[38.0044715349972151,89.9454244119252593,49.6961357673044404]},"#aa6633":{"lch":[49.8446929303716502,65.3554895773238798,35.0519229290669685],"luv":[49.8446929303716502,53.5020897896209959,37.5348692023167061],"rgb":[0.66666666666666663,0.4,0.2],"xyz":[0.219258343270588796,0.182889327209916186,0.055074914937266],"hpluv":[35.0519229290669685,166.380518722129068,49.8446929303716502],"hsluv":[35.0519229290669685,79.6601301034586,49.8446929303716502]},"#aa6644":{"lch":[50.0579996788189163,59.7471791719702878,30.3078082111971625],"luv":[50.0579996788189163,51.5813401714318687,30.1511320703974341],"rgb":[0.66666666666666663,0.4,0.266666666666666663],"xyz":[0.223716338514807683,0.18467252530760378,0.0785536898901526282],"hpluv":[30.3078082111971625,151.454869534606559,50.0579996788189163],"hsluv":[30.3078082111971625,65.6016329960131,50.0579996788189163]},"#aa6655":{"lch":[50.3411543587309183,53.4384070136854916,23.0123473649378063],"luv":[50.3411543587309183,49.1858121787411307,20.8906492114991877],"rgb":[0.66666666666666663,0.4,0.333333333333333315],"xyz":[0.229678752554169696,0.187057490923348613,0.109955737164126544],"hpluv":[23.0123473649378063,134.70064023894011,50.3411543587309183],"hsluv":[23.0123473649378063,48.1262851503794238,50.3411543587309183]},"#aa6666":{"lch":[50.6979081899742283,47.4599132867605107,12.1770506300620198],"luv":[50.6979081899742283,46.3920870859415544,10.0108753362152232],"rgb":[0.66666666666666663,0.4,0.4],"xyz":[0.237263748327677854,0.190091489232751903,0.149903381571270505],"hpluv":[12.1770506300620198,118.788999996072334,50.6979081899742283],"hsluv":[12.1770506300620198,27.8359446414257086,50.6979081899742283]},"#aa6677":{"lch":[51.1308297914663399,43.3502150416948382,357.146673366158041],"luv":[51.1308297914663399,43.29647113668576,-2.15794607701909591],"rgb":[0.66666666666666663,0.4,0.466666666666666674],"xyz":[0.246577761347879787,0.193817094440832727,0.198957183477668414],"hpluv":[357.146673366158041,107.584013476394517,51.1308297914663399],"hsluv":[357.146673366158041,31.9217683762365354,51.1308297914663399]},"#aa6688":{"lch":[51.6414184020027,42.8134625942885876,339.120025752150127],"luv":[51.6414184020027,40.0018640870324234,-15.2592086582212207],"rgb":[0.66666666666666663,0.4,0.533333333333333326],"xyz":[0.257718178449823587,0.198273261281610325,0.257630046881240582],"hpluv":[339.120025752150127,105.201399585535427,51.6414184020027],"hsluv":[339.120025752150127,36.2396804223311,51.6414184020027]},"#aa6699":{"lch":[52.2302006219705675,46.6703467022409342,321.661853982703349],"luv":[52.2302006219705675,36.6065194780657563,-28.949680361091449],"rgb":[0.66666666666666663,0.4,0.6],"xyz":[0.270775142558896342,0.203496046925239482,0.326396724522358461],"hpluv":[321.661853982703349,113.385797667979,52.2302006219705675],"hsluv":[321.661853982703349,40.6514838109423,52.2302006219705675]},"#aa66aa":{"lch":[52.8968256208086274,54.2656136904176165,307.715012949245079],"luv":[52.8968256208086274,33.1961393674155048,-42.9275338250028753],"rgb":[0.66666666666666663,0.4,0.66666666666666663],"xyz":[0.285832835524148843,0.209519124111340577,0.405700574139357117],"hpluv":[307.715012949245079,130.177052782763241,52.8968256208086274],"hsluv":[307.715012949245079,45.0372955528084091,52.8968256208086274]},"#aa66bb":{"lch":[53.6401644756464293,64.2916348467718848,297.653919381785329],"luv":[53.6401644756464293,29.8396642728746109,-56.9474209016772193],"rgb":[0.66666666666666663,0.4,0.733333333333333282],"xyz":[0.302970427631485517,0.216374160954275335,0.495958559237998808],"hpluv":[297.653919381785329,152.091062924306783,53.6401644756464293],"hsluv":[297.653919381785329,49.3013965401631964,53.6401644756464293]},"#aa66cc":{"lch":[54.4584144535918853,75.6506824974921699,290.576693925999962],"luv":[54.4584144535918853,26.5882539678026326,-70.824363839571447],"rgb":[0.66666666666666663,0.4,0.8],"xyz":[0.322262803075207271,0.224091111131764137,0.597565069908269],"hpluv":[290.576693925999962,176.273563499159138,54.4584144535918853],"hsluv":[290.576693925999962,59.8478295858589107,54.4584144535918853]},"#aa66dd":{"lch":[55.3492064676394619,87.6329338161637423,285.539109011475546],"luv":[55.3492064676394619,23.4765185392287,-84.4297587732275],"rgb":[0.66666666666666663,0.4,0.866666666666666696],"xyz":[0.343781128625840759,0.232698441352017671,0.710894917808275],"hpluv":[285.539109011475546,200.907097340780666,55.3492064676394619],"hsluv":[285.539109011475546,72.9499123576365,55.3492064676394619]},"#aa66ee":{"lch":[56.3097127205812171,99.8160041995885337,281.866291349003632],"luv":[56.3097127205812171,20.525011879724925,-97.6829492885499775],"rgb":[0.66666666666666663,0.4,0.933333333333333348],"xyz":[0.367593308892015525,0.242223313458487716,0.836305733876798185],"hpluv":[281.866291349003632,224.934563930918017,56.3097127205812171],"hsluv":[281.866291349003632,86.3166325899195215,56.3097127205812171]},"#aa66ff":{"lch":[57.3367512293125543,111.956114799504135,279.118878442970129],"luv":[57.3367512293125543,17.7431860168323468,-110.541173283857603],"rgb":[0.66666666666666663,0.4,1],"xyz":[0.39376435730184689,0.252691732822420412,0.97413992216858],"hpluv":[279.118878442970129,247.773048158040382,57.3367512293125543],"hsluv":[279.118878442970129,99.9999999999988631,57.3367512293125543]},"#887700":{"lch":[50.0114915023736586,55.8665567864094825,73.357205010908],"luv":[50.0114915023736586,16.0004093344436384,53.5262465366231766],"rgb":[0.533333333333333326,0.466666666666666674,0],"xyz":[0.167496530942664812,0.184282743437969299,0.0267477295612209565],"hpluv":[73.357205010908,141.749463920516746,50.0114915023736586],"hsluv":[73.357205010908,100.000000000002359,50.0114915023736586]},"#887711":{"lch":[50.0597743565714524,53.993823922257576,73.0031869817398302],"luv":[50.0597743565714524,15.783394234863108,51.6354286142242103],"rgb":[0.533333333333333326,0.466666666666666674,0.0666666666666666657],"xyz":[0.168508196442301944,0.184687409637824151,0.0320758345259765862],"hpluv":[73.0031869817398302,136.865669051735267,50.0597743565714524],"hsluv":[73.0031869817398302,96.4507191106164328,50.0597743565714524]},"#887722":{"lch":[50.1490916772086592,50.5946145563497751,72.2920831328592755],"luv":[50.1490916772086592,15.3890953737340599,48.1974145124374616],"rgb":[0.533333333333333326,0.466666666666666674,0.133333333333333331],"xyz":[0.170383554580778945,0.18543755289321498,0.0419527207219557857],"hpluv":[72.2920831328592755,128.020802989304741,50.1490916772086592],"hsluv":[72.2920831328592755,90.012010730737714,50.1490916772086592]},"#887733":{"lch":[50.2956280558193356,45.1970113165044083,70.9372107781068735],"luv":[50.2956280558193356,14.7615306672340392,42.718462569532349],"rgb":[0.533333333333333326,0.466666666666666674,0.2],"xyz":[0.173471305313236679,0.186672653186198079,0.058214874579566929],"hpluv":[70.9372107781068735,114.029917097227894,50.2956280558193356],"hsluv":[70.9372107781068735,79.7918184760720237,50.2956280558193356]},"#887744":{"lch":[50.5060566549544916,37.8272673959478567,68.4411772520018076],"luv":[50.5060566549544916,13.89986571870684,35.1809023711225777],"rgb":[0.533333333333333326,0.466666666666666674,0.266666666666666663],"xyz":[0.177929300557455566,0.188455851283885673,0.0816936495324535605],"hpluv":[68.4411772520018076,95.0387759917387598,50.5060566549544916],"hsluv":[68.4411772520018076,65.8173762074568316,50.5060566549544916]},"#887755":{"lch":[50.7854328179731453,28.7445471843262688,63.5083223958924279],"luv":[50.7854328179731453,12.8220173934607509,25.7263456945161408],"rgb":[0.533333333333333326,0.466666666666666674,0.333333333333333315],"xyz":[0.183891714596817579,0.190840816899630505,0.113095696806427476],"hpluv":[63.5083223958924279,71.82169329487634,50.7854328179731453],"hsluv":[63.5083223958924279,48.4385690265679756,50.7854328179731453]},"#887766":{"lch":[51.1374932189691549,18.6360854649452037,51.6613245975388082],"luv":[51.1374932189691549,11.5601245482137447,14.6173596072111405],"rgb":[0.533333333333333326,0.466666666666666674,0.4],"xyz":[0.191476710370325737,0.193874815209033796,0.153043341213571438],"hpluv":[51.6613245975388082,46.2439140208651,51.1374932189691549],"hsluv":[51.6613245975388082,28.2492665088726049,51.1374932189691549]},"#887777":{"lch":[51.5648179079599629,10.388802862097231,12.1770506300635812],"luv":[51.5648179079599629,10.1550595801770775,2.19134429758843829],"rgb":[0.533333333333333326,0.466666666666666674,0.466666666666666674],"xyz":[0.20079072339052767,0.197600420417114619,0.202097143119969347],"hpluv":[12.1770506300635812,25.5653264810281158,51.5648179079599629],"hsluv":[12.1770506300635812,5.9907484084339373,51.5648179079599629]},"#887788":{"lch":[52.0689409540354262,14.1414171783799034,307.715012949252923],"luv":[52.0689409540354262,8.65079050214889378,-11.1867557182995974],"rgb":[0.533333333333333326,0.466666666666666674,0.533333333333333326],"xyz":[0.21193114049247147,0.202056587257892217,0.260770006523541542],"hpluv":[307.715012949252923,34.4630346227371902,52.0689409540354262],"hsluv":[307.715012949252923,11.9231603633022036,52.0689409540354262]},"#887799":{"lch":[52.6504441343355154,26.1446518461971777,285.73365348909897],"luv":[52.6504441343355154,7.08953673880610147,-25.1650807467009763],"rgb":[0.533333333333333326,0.466666666666666674,0.6],"xyz":[0.224988104601544198,0.207279372901521375,0.329536684164659421],"hpluv":[285.73365348909897,63.0115482025775862,52.6504441343355154],"hsluv":[285.73365348909897,20.7849368541844512,52.6504441343355154]},"#8877aa":{"lch":[53.3090485775123142,39.8165287152511951,277.951975125090712],"luv":[53.3090485775123142,5.50833871717125412,-39.4336678931764482],"rgb":[0.533333333333333326,0.466666666666666674,0.66666666666666663],"xyz":[0.240045797566796726,0.213302450087622469,0.408840533781658],"hpluv":[277.951975125090712,94.7767450693341118,53.3090485775123142],"hsluv":[277.951975125090712,33.2193336653547036,53.3090485775123142]},"#8877bb":{"lch":[54.043710164283695,53.8841311835491,274.190220195010625],"luv":[54.043710164283695,3.93720379281895738,-53.7400969453883732],"rgb":[0.533333333333333326,0.466666666666666674,0.733333333333333282],"xyz":[0.2571833896741334,0.220157486930557228,0.499098518880299769],"hpluv":[274.190220195010625,126.518797380186697,54.043710164283695],"hsluv":[274.190220195010625,46.027457746288988,54.043710164283695]},"#8877cc":{"lch":[54.8527197178713095,67.9360625264533695,272.023364737824068],"luv":[54.8527197178713095,2.39862107173988059,-67.8937052203839215],"rgb":[0.533333333333333326,0.466666666666666674,0.8],"xyz":[0.276475765117855099,0.22787443710804603,0.600705029550569924],"hpluv":[272.023364737824068,157.159823716941304,54.8527197178713095],"hsluv":[272.023364737824068,59.1220253911564413,54.8527197178713095]},"#8877dd":{"lch":[55.7338064566187228,81.7667290312133,270.636302714775695],"luv":[55.7338064566187228,0.90804807322034331,-81.7616867803042595],"rgb":[0.533333333333333326,0.466666666666666674,0.866666666666666696],"xyz":[0.297994090668488698,0.236481767328299564,0.714034877450575922],"hpluv":[270.636302714775695,186.164661983392193,55.7338064566187228],"hsluv":[270.636302714775695,72.4679508704990809,55.7338064566187228]},"#8877ee":{"lch":[56.6842419440431939,95.2620356561917419,269.684203716511661],"luv":[56.6842419440431939,-0.525051666249150784,-95.2605886928551229],"rgb":[0.533333333333333326,0.466666666666666674,0.933333333333333348],"xyz":[0.321806270934663408,0.246006639434769608,0.839445693519099145],"hpluv":[269.684203716511661,213.253830698535069,56.6842419440431939],"hsluv":[269.684203716511661,86.076772525698,56.6842419440431939]},"#8877ff":{"lch":[57.7009414002340577,108.362660778640901,268.997474997449615],"luv":[57.7009414002340577,-1.89596396936046907,-108.346073171359961],"rgb":[0.533333333333333326,0.466666666666666674,1],"xyz":[0.347977319344494829,0.256475058798702304,0.977279881810881],"hpluv":[268.997474997449615,238.306609639193027,57.7009414002340577],"hsluv":[268.997474997449615,99.9999999999988631,57.7009414002340577]},"#ffff00":{"lch":[97.1385593417967357,107.085608846920664,85.8743202181747307],"luv":[97.1385593417967357,7.70421917727499928,106.808111250898],"rgb":[1,1,0],"xyz":[0.76997513864982,0.92780768463926,0.138525598510210984],"hpluv":[85.8743202181747307,1784.23591835690763,97.1385593417967357],"hsluv":[85.8743202181747307,100.000000000072717,97.1385593417967357]},"#ffff11":{"lch":[97.1550055288865337,106.340968495662651,85.8743202181747307],"luv":[97.1550055288865337,7.65064640931757278,106.065400532478591],"rgb":[1,1,0.0666666666666666657],"xyz":[0.770986804149457194,0.928212350839114908,0.143853703474966621],"hpluv":[85.8743202181747307,1782.29032599077573,97.1550055288865337],"hsluv":[85.8743202181747307,100.000000000072447,97.1550055288865337]},"#ffff22":{"lch":[97.1854797367251564,104.966044999604463,85.8743202181747],"luv":[97.1854797367251564,7.5517282439387623,104.694039961158666],"rgb":[1,1,0.133333333333333331],"xyz":[0.77286216228793414,0.928962494094505709,0.1537305896709458],"hpluv":[85.8743202181747,1778.69938503976459,97.1854797367251564],"hsluv":[85.8743202181747,100.00000000007401,97.1854797367251564]},"#ffff33":{"lch":[97.2356193677236291,102.717517786777336,85.8743202181746312],"luv":[97.2356193677236291,7.38995910744871409,102.451339496695468],"rgb":[1,1,0.2],"xyz":[0.775949913020392,0.930197594387488835,0.16999274352855695],"hpluv":[85.8743202181746312,1772.83090468185333,97.2356193677236291],"hsluv":[85.8743202181746312,100.000000000075445,97.2356193677236291]},"#ffff44":{"lch":[97.3079311184623776,99.5042093292491,85.874320218174546],"luv":[97.3079311184623776,7.15877927938833114,99.2463578851537704],"rgb":[1,1,0.266666666666666663],"xyz":[0.780407908264610817,0.931980792485176401,0.193471518481443588],"hpluv":[85.874320218174546,1764.45330998562531,97.3079311184623776],"hsluv":[85.874320218174546,100.000000000077918,97.3079311184623776]},"#ffff55":{"lch":[97.4045015397841212,95.2663481722239283,85.8743202181744323],"luv":[97.4045015397841212,6.8538885331141568,95.0194785612246875],"rgb":[1,1,0.333333333333333315],"xyz":[0.786370322303972746,0.934365758100921151,0.224873565755417504],"hpluv":[85.8743202181744323,1753.42077174454698,97.4045015397841212],"hsluv":[85.8743202181744323,100.000000000080163,97.4045015397841212]},"#ffff66":{"lch":[97.5271149532436539,89.9715947326486258,85.8743202181742333],"luv":[97.5271149532436539,6.47296021391862286,89.7384457454272706],"rgb":[1,1,0.4],"xyz":[0.793955318077481,0.93739975641032447,0.264821210162561438],"hpluv":[85.8743202181742333,1739.66322518688298,97.5271149532436539],"hsluv":[85.8743202181742333,100.000000000084981,97.5271149532436539]},"#ffff77":{"lch":[97.6773170086398608,83.6127156419164663,85.8743202181740202],"luv":[97.6773170086398608,6.01547392080898469,83.3960448134325389],"rgb":[1,1,0.466666666666666674],"xyz":[0.803269331097682837,0.941125361618405321,0.313875012068959403],"hpluv":[85.8743202181740202,1723.18045161093028,97.6773170086398608],"hsluv":[85.8743202181740202,100.00000000009112,97.6773170086398608]},"#ffff88":{"lch":[97.8564527859654589,76.2055692953657342,85.8743202181736791],"luv":[97.8564527859654589,5.48257057790026181,76.0080930657330214],"rgb":[1,1,0.533333333333333326],"xyz":[0.814409748199626748,0.945581528459182863,0.372547875472531542],"hpluv":[85.8743202181736791,1704.03672017478311,97.8564527859654589],"hsluv":[85.8743202181736791,100.000000000099803,97.8564527859654589]},"#ffff99":{"lch":[98.0656913545514612,67.7868897983338741,85.8743202181732102],"luv":[98.0656913545514612,4.87689300155069283,67.6112294162950889],"rgb":[1,1,0.6],"xyz":[0.827466712308699393,0.950804314102812076,0.441314553113649422],"hpluv":[85.8743202181732102,1682.35465810463256,98.0656913545514612],"hsluv":[85.8743202181732102,100.000000000112891,98.0656913545514612]},"#ffffaa":{"lch":[98.3060425431328611,58.4116937234916094,85.8743202181725707],"luv":[98.3060425431328611,4.20239933084915052,58.260327869924204],"rgb":[1,1,0.66666666666666663],"xyz":[0.842524405273952,0.956827391288913143,0.520618402730648078],"hpluv":[85.8743202181725707,1658.30791632356272,98.3060425431328611],"hsluv":[85.8743202181725707,100.000000000127613,98.3060425431328611]},"#ffffbb":{"lch":[98.5783690162300559,48.1503065934375414,85.8743202181715759],"luv":[98.5783690162300559,3.46414909943131732,48.0255317103199246],"rgb":[1,1,0.733333333333333282],"xyz":[0.859661997381288567,0.963682428131847901,0.610876387829289769],"hpluv":[85.8743202181715759,1632.1126639545671,98.5783690162300559],"hsluv":[85.8743202181715759,100.000000000152809,98.5783690162300559]},"#ffffcc":{"lch":[98.8833954570195317,37.0851031688938804,85.8743202181698706],"luv":[98.8833954570195317,2.66806871718659799,36.9890022353654899],"rgb":[1,1,0.8],"xyz":[0.878954372825010322,0.971399378309336758,0.712482898499559925],"hpluv":[85.8743202181698706,1604.018210645404,98.8833954570195317],"hsluv":[85.8743202181698706,100.00000000019709,98.8833954570195317]},"#ffffdd":{"lch":[99.2217159651800245,25.3071072074552177,85.8743202181663889],"luv":[99.2217159651800245,1.82070684164607655,25.2415273271332552],"rgb":[1,1,0.866666666666666696],"xyz":[0.900472698375643921,0.980006708529590265,0.825812746399565922],"hpluv":[85.8743202181663889,1574.29719653830034,99.2217159651800245],"hsluv":[85.8743202181663889,100.000000000286278,99.2217159651800245]},"#ffffee":{"lch":[99.5938003805277248,12.9126149352850259,85.8743202181558161],"luv":[99.5938003805277248,0.928991455386458775,12.8791536733888243],"rgb":[1,1,0.933333333333333348],"xyz":[0.92428487864181863,0.989531580636060282,0.951223562468089145],"hpluv":[85.8743202181558161,1543.23583838085528,99.5938003805277248],"hsluv":[85.8743202181558161,100.000000000556355,99.5938003805277248]},"#ffffff":{"lch":[99.99999999999973,5.29610712429325706e-12,0],"luv":[99.99999999999973,4.97935026544381416e-12,1.80411241501587473e-12],"rgb":[1,1,1],"xyz":[0.95045592705165,0.999999999999993,1.0890577507598711],"hpluv":[0,0,100],"hsluv":[0,0,100]},"#aa7700":{"lch":[53.7507838912622304,69.116848270999057,51.9676330333141223],"luv":[53.7507838912622304,42.5833417137676875,54.4407726194696622],"rgb":[0.66666666666666663,0.466666666666666674,0],"xyz":[0.231737306953434558,0.217406893568523163,0.0297590159367257245],"hpluv":[51.9676330333141223,163.169299961930307,53.7507838912622304],"hsluv":[51.9676330333141223,100.000000000002359,53.7507838912622304]},"#aa7711":{"lch":[53.7940335015026,67.5786316453491906,51.3090056740019378],"luv":[53.7940335015026,42.244752971039,52.7470596476588653],"rgb":[0.66666666666666663,0.466666666666666674,0.0666666666666666657],"xyz":[0.23274897245307169,0.217811559768378016,0.0350871209014813543],"hpluv":[51.3090056740019378,159.40965108533166,53.7940335015026],"hsluv":[51.3090056740019378,97.0120153186068,53.7940335015026]},"#aa7722":{"lch":[53.874065271669366,64.7981771198060272,50.0272013346139],"luv":[53.874065271669366,41.6278947732915157,49.6580520640260588],"rgb":[0.66666666666666663,0.466666666666666674,0.133333333333333331],"xyz":[0.234624330591548691,0.218561703023768844,0.0449640070974605538],"hpluv":[50.0272013346139,152.623836787181489,53.874065271669366],"hsluv":[50.0272013346139,91.5730337049880632,53.874065271669366]},"#aa7733":{"lch":[54.0054384284815,60.4215101577181812,47.7291529037971785],"luv":[54.0054384284815,40.6416884431496115,44.7103125713654705],"rgb":[0.66666666666666663,0.466666666666666674,0.2],"xyz":[0.237712081324006452,0.219796803316751943,0.0612261609550717],"hpluv":[47.7291529037971785,141.968961696257139,54.0054384284815],"hsluv":[47.7291529037971785,82.890357503842381,54.0054384284815]},"#aa7744":{"lch":[54.1942453736720324,54.5501661616690754,43.9413891432679051],"luv":[54.1942453736720324,39.2788485799816911,37.8535689532252277],"rgb":[0.66666666666666663,0.466666666666666674,0.266666666666666663],"xyz":[0.242170076568225312,0.221580001414439537,0.0847049359079583286],"hpluv":[43.9413891432679051,127.726858599491337,54.1942453736720324],"hsluv":[43.9413891432679051,70.9191698542686453,54.1942453736720324]},"#aa7755":{"lch":[54.4451912879813307,47.55778496198932,37.8352816528713],"luv":[54.4451912879813307,37.5600659479400178,29.1716361638701045],"rgb":[0.66666666666666663,0.466666666666666674,0.333333333333333315],"xyz":[0.248132490607587297,0.22396496703018437,0.116106983181932244],"hpluv":[37.8352816528713,110.841250641501858,54.4451912879813307],"hsluv":[37.8352816528713,55.8697139193963039,54.4451912879813307]},"#aa7766":{"lch":[54.7618668139504621,40.2221891209492881,27.9562221290694595],"luv":[54.7618668139504621,35.5285027246357359,18.8560333004309904],"rgb":[0.66666666666666663,0.466666666666666674,0.4],"xyz":[0.255717486381095482,0.226998965339587661,0.156054627589076206],"hpluv":[27.9562221290694595,93.2023334238246264,54.7618668139504621],"hsluv":[27.9562221290694595,38.157009054435612,54.7618668139504621]},"#aa7777":{"lch":[55.1468928183874851,34.0080558607991321,12.1770506300622881],"luv":[55.1468928183874851,33.2428902595124569,7.17343088244713467],"rgb":[0.66666666666666663,0.466666666666666674,0.466666666666666674],"xyz":[0.265031499401297388,0.230724570547668484,0.205108429495474115],"hpluv":[12.1770506300622881,78.2528356679829074,55.1468928183874851],"hsluv":[12.1770506300622881,20.6006796366476941,55.1468928183874851]},"#aa7788":{"lch":[55.6020140468043849,31.2700131437067519,349.739442339375785],"luv":[55.6020140468043849,30.7699397165362107,-5.56996695217490778],"rgb":[0.66666666666666663,0.466666666666666674,0.533333333333333326],"xyz":[0.276171916503241244,0.235180737388446082,0.263781292899046282],"hpluv":[349.739442339375785,71.363619208349732,55.6020140468043849],"hsluv":[349.739442339375785,23.0952607722130772,55.6020140468043849]},"#aa7799":{"lch":[56.1281730235999845,34.0192547961324365,325.92167501088062],"luv":[56.1281730235999845,28.1772086346441704,-19.0618627223027133],"rgb":[0.66666666666666663,0.466666666666666674,0.6],"xyz":[0.289228880612313943,0.240403523032075239,0.332547970540164162],"hpluv":[325.92167501088062,76.9100717288581706,56.1281730235999845],"hsluv":[325.92167501088062,27.5449434619861648,56.1281730235999845]},"#aa77aa":{"lch":[56.7255784680210127,41.7295245342496131,307.715012949246272],"luv":[56.7255784680210127,25.5273831431779215,-33.0106941416859],"rgb":[0.66666666666666663,0.466666666666666674,0.66666666666666663],"xyz":[0.304286573577566499,0.246426600218176334,0.411851820157162818],"hpluv":[307.715012949246272,93.3477446513022642,56.7255784680210127],"hsluv":[307.715012949246272,32.2954766233998285,56.7255784680210127]},"#aa77bb":{"lch":[57.3937746480490176,52.417961949749369,295.873528074876958],"luv":[57.3937746480490176,22.8744713506946127,-47.1635589771554891],"rgb":[0.66666666666666663,0.466666666666666674,0.733333333333333282],"xyz":[0.321424165684903118,0.25328163706111112,0.502109805255804509],"hpluv":[295.873528074876958,115.892323381948941,57.3937746480490176],"hsluv":[295.873528074876958,41.7229864085831679,57.3937746480490176]},"#aa77cc":{"lch":[58.1317139736185,64.5762938068646548,288.286403622885132],"luv":[58.1317139736185,20.2619194712353625,-61.3151885031081],"rgb":[0.66666666666666663,0.466666666666666674,0.8],"xyz":[0.340716541128624872,0.260998587238599922,0.603716315926074665],"hpluv":[288.286403622885132,140.961111207958226,58.1317139736185],"hsluv":[288.286403622885132,55.678510160825347,58.1317139736185]},"#aa77dd":{"lch":[58.9378328182195759,77.3666791836153,283.242275299631103],"luv":[58.9378328182195759,17.7223199365118553,-75.3095108466943088],"rgb":[0.66666666666666663,0.466666666666666674,0.866666666666666696],"xyz":[0.362234866679258416,0.269605917458853428,0.717046163826080662],"hpluv":[283.242275299631103,166.570895286205939,58.9378328182195759],"hsluv":[283.242275299631103,70.0408478070886105,58.9378328182195759]},"#aa77ee":{"lch":[59.8101292792768646,90.3373867943789151,279.736895248195651],"luv":[59.8101292792768646,15.2782276108220607,-89.0360556960445138],"rgb":[0.66666666666666663,0.466666666666666674,0.933333333333333348],"xyz":[0.386047046945433125,0.279130789565323445,0.842456979894603886],"hpluv":[279.736895248195651,191.660275847677298,59.8101292792768646],"hsluv":[279.736895248195651,84.8029379630096685,59.8101292792768646]},"#aa77ff":{"lch":[60.7462409754246551,103.238062985892157,277.202485092995744],"luv":[60.7462409754246551,12.9436026905507742,-102.423438716283115],"rgb":[0.66666666666666663,0.466666666666666674,1],"xyz":[0.412218095355264547,0.289599208929256169,0.980291168186385731],"hpluv":[277.202485092995744,215.655115976047284,60.7462409754246551],"hsluv":[277.202485092995744,99.999999999998721,60.7462409754246551]},"#888800":{"lch":[54.9099926918455452,60.532810441385358,85.8743202181747449],"luv":[54.9099926918455452,4.35500198466006783,60.375948006191166],"rgb":[0.533333333333333326,0.533333333333333326,0],"xyz":[0.189568900667635265,0.228427482887910871,0.0341051861362109063],"hpluv":[85.8743202181747449,139.887458074797593,54.9099926918455452],"hsluv":[85.8743202181747449,100.000000000002331,54.9099926918455452]},"#888811":{"lch":[54.9518410557904673,58.8347385736240369,85.8743202181746739],"luv":[54.9518410557904673,4.23283507550337568,58.6822764576347353],"rgb":[0.533333333333333326,0.533333333333333326,0.0666666666666666657],"xyz":[0.190580566167272397,0.228832149087765724,0.039433291100966536],"hpluv":[85.8743202181746739,135.85978011465275,54.9518410557904673],"hsluv":[85.8743202181746739,97.1207726442580395,54.9518410557904673]},"#888822":{"lch":[55.0292864560463215,55.7361292450240882,85.8743202181745602],"luv":[55.0292864560463215,4.00990721741558787,55.5916967480373643],"rgb":[0.533333333333333326,0.533333333333333326,0.133333333333333331],"xyz":[0.192455924305749398,0.229582292343156552,0.0493101772969457355],"hpluv":[85.8743202181745602,128.523412903997382,55.0292864560463215],"hsluv":[85.8743202181745602,91.8762944675706,55.0292864560463215]},"#888833":{"lch":[55.1564325013520573,50.7686053645684225,85.8743202181742902],"luv":[55.1564325013520573,3.65252126093227947,50.6370455210582335],"rgb":[0.533333333333333326,0.533333333333333326,0.2],"xyz":[0.195543675038207132,0.230817392636139651,0.0655723311545568788],"hpluv":[85.8743202181742902,116.798802852822334,55.1564325013520573],"hsluv":[85.8743202181742902,83.4948353914423,55.1564325013520573]},"#888844":{"lch":[55.3392041906722767,43.8756115710196184,85.8743202181737786],"luv":[55.3392041906722767,3.15660835961073616,43.7619139708837039],"rgb":[0.533333333333333326,0.533333333333333326,0.266666666666666663],"xyz":[0.20000167028242602,0.232600590733827245,0.0890511061074435173],"hpluv":[85.8743202181737786,100.607324583255647,55.3392041906722767],"hsluv":[85.8743202181737786,71.9201892491773833,55.3392041906722767]},"#888855":{"lch":[55.5822005995452173,35.1333862553221152,85.8743202181729],"luv":[55.5822005995452173,2.5276534453655044,35.0423429271758167],"rgb":[0.533333333333333326,0.533333333333333326,0.333333333333333315],"xyz":[0.205964084321788032,0.234985556349572078,0.120453153381417433],"hpluv":[85.8743202181729,80.2090919262666233,55.5822005995452173],"hsluv":[85.8743202181729,57.3383011101545321,55.5822005995452173]},"#888866":{"lch":[55.8889601924437187,24.7258905438507242,85.874320218171],"luv":[55.8889601924437187,1.778891507033598,24.6618168064052092],"rgb":[0.533333333333333326,0.533333333333333326,0.4],"xyz":[0.21354908009529619,0.238019554658975369,0.160400797788561394],"hpluv":[85.874320218171,56.1390732800859524,55.8889601924437187],"hsluv":[85.874320218171,40.1315986813270698,55.8889601924437187]},"#888877":{"lch":[56.2621011123828509,12.9137749110131566,85.8743202181651668],"luv":[56.2621011123828509,0.929074909242871283,12.8803106431998842],"rgb":[0.533333333333333326,0.533333333333333326,0.466666666666666674],"xyz":[0.222863093115498123,0.241745159867056192,0.209454599694959304],"hpluv":[85.8743202181651668,29.1257147579972724,56.2621011123828509],"hsluv":[85.8743202181651668,20.8208192205656601,56.2621011123828509]},"#888888":{"lch":[56.703410756754252,2.95076376078202623e-12,0],"luv":[56.703410756754252,2.78254170310414444e-12,9.82073542272051e-13],"rgb":[0.533333333333333326,0.533333333333333326,0.533333333333333326],"xyz":[0.234003510217441923,0.24620132670783379,0.268127463098531471],"hpluv":[0,6.60335407213460764e-12,56.703410756754252],"hsluv":[0,2.14018342731852893e-12,56.703410756754252]},"#888899":{"lch":[57.2139150634865246,13.7029898302256612,265.874320218188814],"luv":[57.2139150634865246,-0.985854571612734376,-13.6674804207248872],"rgb":[0.533333333333333326,0.533333333333333326,0.6],"xyz":[0.247060474326514651,0.251424112351462947,0.33689414073964935],"hpluv":[265.874320218188814,30.3915601408835876,57.2139150634865246],"hsluv":[265.874320218188814,12.5386286039598396,57.2139150634865246]},"#8888aa":{"lch":[57.7939415002624486,27.9001972781706051,265.874320218182902],"luv":[57.7939415002624486,-2.00726537612613365,-27.8278977623291475],"rgb":[0.533333333333333326,0.533333333333333326,0.66666666666666663],"xyz":[0.262118167291767179,0.25744718953756407,0.416197990356647951],"hpluv":[265.874320218182902,61.2582077856443377,57.7939415002624486],"hsluv":[265.874320218182902,25.8334660761224093,57.7939415002624486]},"#8888bb":{"lch":[58.4431822360017605,42.3326731508362428,265.874320218181083],"luv":[58.4431822360017605,-3.04560244672749647,-42.2229738629578222],"rgb":[0.533333333333333326,0.533333333333333326,0.733333333333333282],"xyz":[0.279255759399103853,0.264302226380498828,0.506455975455289753],"hpluv":[265.874320218181083,91.9138937804104756,58.4431822360017605],"hsluv":[265.874320218181083,39.7348050695490116,58.4431822360017605]},"#8888cc":{"lch":[59.1607600358786812,56.7874726838639603,265.874320218180117],"luv":[59.1607600358786812,-4.0855455816182138,-56.6403157752595448],"rgb":[0.533333333333333326,0.533333333333333326,0.8],"xyz":[0.298548134842825608,0.27201917655798763,0.608062486125559909],"hpluv":[265.874320218180117,121.803038601679276,59.1607600358786812],"hsluv":[265.874320218180117,54.1372084350884322,59.1607600358786812]},"#8888dd":{"lch":[59.9452971965242654,71.1002375720468649,265.874320218179605],"luv":[59.9452971965242654,-5.11527010687093497,-70.9159911059223447],"rgb":[0.533333333333333326,0.533333333333333326,0.866666666666666696],"xyz":[0.320066460393459096,0.280626506778241136,0.721392334025565907],"hpluv":[265.874320218179605,150.506501481916018,59.9452971965242654],"hsluv":[265.874320218179605,68.9826297466640881,59.9452971965242654]},"#8888ee":{"lch":[60.7949865781877747,85.1524606014505,265.874320218179207],"luv":[60.7949865781877747,-6.12625008179143,-84.9317997361231676],"rgb":[0.533333333333333326,0.533333333333333326,0.933333333333333348],"xyz":[0.343878640659633861,0.290151378884711153,0.84680315009408913],"hpluv":[265.874320218179207,177.733282428962553,60.7949865781877747],"hsluv":[265.874320218179207,84.2595641984559194,60.7949865781877747]},"#8888ff":{"lch":[61.7076631467729726,98.8655769196339,265.874320218179],"luv":[61.7076631467729726,-7.11283319838656247,-98.6093804034077408],"rgb":[0.533333333333333326,0.533333333333333326,1],"xyz":[0.370049689069465226,0.300619798248643877,0.984637338385871],"hpluv":[265.874320218179,203.303722842755434,61.7076631467729726],"hsluv":[265.874320218179,99.9999999999986073,61.7076631467729726]},"#aa8800":{"lch":[58.1840377660698493,67.6904417424552634,64.2288134226940173],"luv":[58.1840377660698493,29.4303340948507071,60.9577832467208225],"rgb":[0.66666666666666663,0.533333333333333326,0],"xyz":[0.253809676678405038,0.261551633018464735,0.0371164725117156744],"hpluv":[64.2288134226940173,147.625988392398114,58.1840377660698493],"hsluv":[64.2288134226940173,100.000000000002373,58.1840377660698493]},"#aa8811":{"lch":[58.2222766199063955,66.2027965316335809,63.8264905250604926],"luv":[58.2222766199063955,29.2014551434886229,59.4145208354969085],"rgb":[0.66666666666666663,0.533333333333333326,0.0666666666666666657],"xyz":[0.254821342178042143,0.261956299218319588,0.0424445774764713041],"hpluv":[63.8264905250604926,144.286759049554206,58.2222766199063955],"hsluv":[63.8264905250604926,97.5015111084285877,58.2222766199063955]},"#aa8822":{"lch":[58.2930572278629,63.4916551128893474,63.0419050459203],"luv":[58.2930572278629,28.7832252220538578,56.5925455761676304],"rgb":[0.66666666666666663,0.533333333333333326,0.133333333333333331],"xyz":[0.2566967003165192,0.262706442473710389,0.0523214636724505036],"hpluv":[63.0419050459203,138.209896631886636,58.2930572278629],"hsluv":[63.0419050459203,92.9399945222758106,58.2930572278629]},"#aa8833":{"lch":[58.4093035212624585,59.1585039849960737,61.628621374019076],"luv":[58.4093035212624585,28.1112178941065629,52.0527426967384628],"rgb":[0.66666666666666663,0.533333333333333326,0.2],"xyz":[0.259784451048976905,0.263941542766693515,0.0685836175300616468],"hpluv":[61.628621374019076,128.521114132395894,58.4093035212624585],"hsluv":[61.628621374019076,85.621599137751673,58.4093035212624585]},"#aa8844":{"lch":[58.5764981609594315,53.1878639814319953,59.2736460930020499],"luv":[58.5764981609594315,27.1757201885359478,45.7212106919940453],"rgb":[0.66666666666666663,0.533333333333333326,0.266666666666666663],"xyz":[0.264242446293195821,0.265724740864381082,0.0920623924829482854],"hpluv":[59.2736460930020499,115.22015920662389,58.5764981609594315],"hsluv":[59.2736460930020499,75.4571473133808581,58.5764981609594315]},"#aa8855":{"lch":[58.7989500318507083,45.736161182952344,55.3795129841665315],"luv":[58.7989500318507083,25.9844527075537677,37.6378088793954433],"rgb":[0.66666666666666663,0.533333333333333326,0.333333333333333315],"xyz":[0.270204860332557806,0.268109706480125942,0.123464439756922201],"hpluv":[55.3795129841665315,98.7027982667044483,58.7989500318507083],"hsluv":[55.3795129841665315,62.5553187882680319,58.7989500318507083]},"#aa8866":{"lch":[59.0800404303715112,37.1980666756204,48.681601920545944],"luv":[59.0800404303715112,24.5597583059268025,27.9376884576795419],"rgb":[0.66666666666666663,0.533333333333333326,0.4],"xyz":[0.277789856106066,0.271143704789529261,0.163412084164066163],"hpluv":[48.681601920545944,79.8948730878687883,59.0800404303715112],"hsluv":[48.681601920545944,47.1909371341698645,59.0800404303715112]},"#aa8877":{"lch":[59.4223523155875881,28.4467220316745042,36.2691810942760355],"luv":[59.4223523155875881,22.9350730451589406,16.8285001934390941],"rgb":[0.66666666666666663,0.533333333333333326,0.466666666666666674],"xyz":[0.287103869126267897,0.274869309997610056,0.212465886070464072],"hpluv":[36.2691810942760355,60.7465636644032,59.4223523155875881],"hsluv":[36.2691810942760355,29.7643761063162415,59.4223523155875881]},"#aa8888":{"lch":[59.8277504540149323,21.6376696880998622,12.1770506300627677],"luv":[59.8277504540149323,21.1508320810015036,4.56410471095846049],"rgb":[0.66666666666666663,0.533333333333333326,0.533333333333333326],"xyz":[0.298244286228211697,0.279325476838387654,0.271138749474036211],"hpluv":[12.1770506300627677,45.8930730764781174,59.8277504540149323],"hsluv":[12.1770506300627677,15.9793094134510145,59.8277504540149323]},"#aa8899":{"lch":[60.2974403890441693,21.076671863141442,335.972081494736813],"luv":[60.2974403890441693,19.2503183610400761,-8.58203587880762697],"rgb":[0.66666666666666663,0.533333333333333326,0.6],"xyz":[0.311301250337284396,0.284548262482016812,0.339905427115154146],"hpluv":[335.972081494736813,44.3549898137704872,60.2974403890441693],"hsluv":[335.972081494736813,18.3674189175529285,60.2974403890441693]},"#aa88aa":{"lch":[60.8320193568852119,28.2409959286201691,307.715012949248376],"luv":[60.8320193568852119,17.2759870010776844,-22.3404145928166677],"rgb":[0.66666666666666663,0.533333333333333326,0.66666666666666663],"xyz":[0.326358943302536952,0.290571339668117934,0.419209276732152747],"hpluv":[307.715012949248376,58.9097393716334068,60.8320193568852119],"hsluv":[307.715012949248376,20.7885743891348937,60.8320193568852119]},"#aa88bb":{"lch":[61.4315255818646904,39.5305448534603343,292.718173175904553],"luv":[61.4315255818646904,15.2666424694527869,-36.4635928581008],"rgb":[0.66666666666666663,0.533333333333333326,0.733333333333333282],"xyz":[0.343496535409873627,0.297426376511052692,0.509467261830794493],"hpluv":[292.718173175904553,81.6546320542196185,61.4315255818646904],"hsluv":[292.718173175904553,35.3775178816614826,61.4315255818646904]},"#aa88cc":{"lch":[62.0954889075932783,52.4408733717370339,284.64164926901276],"luv":[62.0954889075932783,13.2556230251873277,-50.737891739849438],"rgb":[0.66666666666666663,0.533333333333333326,0.8],"xyz":[0.362788910853595326,0.305143326688541494,0.611073772501064649],"hpluv":[284.64164926901276,107.164068097081099,62.0954889075932783],"hsluv":[284.64164926901276,50.6369924233865092,62.0954889075932783]},"#aa88dd":{"lch":[62.8229837406334894,65.9589053782665644,279.83800714750987],"luv":[62.8229837406334894,11.2699451472508105,-64.988964717689413],"rgb":[0.66666666666666663,0.533333333333333326,0.866666666666666696],"xyz":[0.384307236404228925,0.313750656908795,0.724403620401070647],"hpluv":[279.83800714750987,133.227600809414753,62.8229837406334894],"hsluv":[279.83800714750987,66.50088929558828,62.8229837406334894]},"#aa88ee":{"lch":[63.6126841134072,79.6308922643202237,276.728713669089302],"luv":[63.6126841134072,9.33022805769535,-79.0823990986816767],"rgb":[0.66666666666666663,0.533333333333333326,0.933333333333333348],"xyz":[0.408119416670403634,0.323275529015265,0.84981443646959387],"hpluv":[276.728713669089302,158.846330872338797,63.6126841134072],"hsluv":[276.728713669089302,82.9476730407324112,63.6126841134072]},"#aa88ff":{"lch":[64.4629200033750323,93.219110130063271,274.584640952303687],"luv":[64.4629200033750323,7.4511637136690565,-92.9208407880221756],"rgb":[0.66666666666666663,0.533333333333333326,1],"xyz":[0.434290465080235055,0.333743948379197741,0.987648624761375715],"hpluv":[274.584640952303687,183.499254977583263,64.4629200033750323],"hsluv":[274.584640952303687,99.999999999998451,64.4629200033750323]},"#889900":{"lch":[59.9037942457991477,67.5360782410098892,95.4734085527772578],"luv":[59.9037942457991477,-6.44184579214223074,67.2281524881211396],"rgb":[0.533333333333333326,0.6,0],"xyz":[0.215438501120102766,0.280166683792846538,0.0427283862870331613],"hpluv":[95.4734085527772578,143.060860652479761,59.9037942457991477],"hsluv":[95.4734085527772578,100.000000000002359,59.9037942457991477]},"#889911":{"lch":[59.9403212197486,66.0293008977046867,95.6505578181906628],"luv":[59.9403212197486,-6.50131434341495318,65.7084582747741166],"rgb":[0.533333333333333326,0.6,0.0666666666666666657],"xyz":[0.216450166619739898,0.280571349992701391,0.048056491251788791],"hpluv":[95.6505578181906628,139.783837686775883,59.9403212197486],"hsluv":[95.6505578181906628,97.642419329775592,59.9403212197486]},"#889922":{"lch":[60.0079397017320275,63.2737960078627495,95.9966659299995655],"luv":[60.0079397017320275,-6.6102508868722456,62.9275602932231308],"rgb":[0.533333333333333326,0.6,0.133333333333333331],"xyz":[0.218325524758216899,0.281321493248092191,0.0579333774477679905],"hpluv":[95.9966659299995655,133.799503075015934,60.0079397017320275],"hsluv":[95.9966659299995655,93.3344688530494864,60.0079397017320275]},"#889933":{"lch":[60.1190111745068521,58.8410136656902196,96.6225595920901696],"luv":[60.1190111745068521,-6.78603238946032139,58.4483930798370039],"rgb":[0.533333333333333326,0.6,0.2],"xyz":[0.221413275490674633,0.282556593541075318,0.0741955313053791338],"hpluv":[96.6225595920901696,124.196009967059197,60.1190111745068521],"hsluv":[96.6225595920901696,86.4129060235578,60.1190111745068521]},"#889944":{"lch":[60.2788030378330859,52.6619605596060651,97.6740140778758104],"luv":[60.2788030378330859,-7.03230554676784081,52.1903129773946],"rgb":[0.533333333333333326,0.6,0.266666666666666663],"xyz":[0.22587127073489352,0.284339791638762884,0.0976743062582657723],"hpluv":[97.6740140778758104,110.859197411007315,60.2788030378330859],"hsluv":[97.6740140778758104,76.7791514013919,60.2788030378330859]},"#889955":{"lch":[60.491478208304315,44.7890969420590679,99.4433583384469557],"luv":[60.491478208304315,-7.34865909500015935,44.1821277711999301],"rgb":[0.533333333333333326,0.6,0.333333333333333315],"xyz":[0.231833684774255533,0.286724757254507745,0.129076353532239674],"hpluv":[99.4433583384469557,93.954467458231008,60.491478208304315],"hsluv":[99.4433583384469557,64.5165507795669555,60.491478208304315]},"#889966":{"lch":[60.7603321241253269,35.3998784596055387,102.614945913325585],"luv":[60.7603321241253269,-7.73125582812020351,34.5453191948634597],"rgb":[0.533333333333333326,0.6,0.4],"xyz":[0.23941868054776369,0.289758755563911063,0.169023997939383636],"hpluv":[102.614945913325585,73.9300429237522394,60.7603321241253269],"hsluv":[102.614945913325585,49.862982431557576,60.7603321241253269]},"#889977":{"lch":[61.0879169406466644,24.8557994274465628,109.198389045907604],"luv":[61.0879169406466644,-8.17358342252196,23.4734594640953418],"rgb":[0.533333333333333326,0.6,0.466666666666666674],"xyz":[0.248732693567965624,0.293484360771991859,0.218077799845781545],"hpluv":[109.198389045907604,51.6311437806165543,61.0879169406466644],"hsluv":[109.198389045907604,33.1759220302134779,61.0879169406466644]},"#889988":{"lch":[61.4761176658877702,14.1684419896747276,127.715012949229816],"luv":[61.4761176658877702,-8.66732250724137,11.2081340539023326],"rgb":[0.533333333333333326,0.6,0.533333333333333326],"xyz":[0.259873110669909424,0.297940527612769457,0.276750663249353712],"hpluv":[127.715012949229816,29.2452265306994263,61.4761176658877702],"hsluv":[127.715012949229816,14.8910328511789984,61.4761176658877702]},"#889999":{"lch":[61.9262069462763094,9.41507553536713537,192.177050630058915],"luv":[61.9262069462763094,-9.20324067004397861,-1.98595279549067061],"rgb":[0.533333333333333326,0.6,0.6],"xyz":[0.272930074778982124,0.303163313256398614,0.345517340890471647],"hpluv":[192.177050630058915,19.2925065058214678,61.9262069462763094],"hsluv":[192.177050630058915,19.2169899754877207,61.9262069462763094]},"#8899aa":{"lch":[62.4388911462841207,18.6148502867865133,238.334617604481764],"luv":[62.4388911462841207,-9.77200531832159669,-15.8436284751369474],"rgb":[0.533333333333333326,0.6,0.66666666666666663],"xyz":[0.28798776774423468,0.309186390442499737,0.424821190507470248],"hpluv":[238.334617604481764,37.8306403353000036,62.4388911462841207],"hsluv":[238.334617604481764,23.6900457250072343,62.4388911462841207]},"#8899bb":{"lch":[63.0143540484962,31.8509402607766567,251.009167860858838],"luv":[63.0143540484962,-10.3648329189902189,-30.1173145226625429],"rgb":[0.533333333333333326,0.6,0.733333333333333282],"xyz":[0.305125359851571354,0.316041427285434495,0.515079175606111939],"hpluv":[251.009167860858838,64.1389868285616132,63.0143540484962],"hsluv":[251.009167860858838,32.2218698989210282,63.0143540484962]},"#8899cc":{"lch":[63.6523012354060143,45.9199042321153357,256.173658840600297],"luv":[63.6523012354060143,-10.9739341944061159,-44.5893526863026821],"rgb":[0.533333333333333326,0.6,0.8],"xyz":[0.324417735295293053,0.323758377462923297,0.616685686276382095],"hpluv":[256.173658840600297,91.543221315317254,63.6523012354060143],"hsluv":[256.173658840600297,48.1563502503440546,63.6523012354060143]},"#8899dd":{"lch":[64.3520063546654,60.2052734177332738,258.898139298145679],"luv":[64.3520063546654,-11.5927562398827622,-59.0786166905309358],"rgb":[0.533333333333333326,0.6,0.866666666666666696],"xyz":[0.345936060845926652,0.332365707683176803,0.730015534176388092],"hpluv":[258.898139298145679,118.716686841439611,64.3520063546654],"hsluv":[258.898139298145679,64.7736147673059435,64.3520063546654]},"#8899ee":{"lch":[65.1123593572591091,74.4513212160393465,260.556144021857],"luv":[65.1123593572591091,-12.2160522582942246,-73.442271874149526],"rgb":[0.533333333333333326,0.6,0.933333333333333348],"xyz":[0.369748241112101361,0.34189057978964682,0.855426350244911315],"hpluv":[260.556144021857,145.093615685215838,65.1123593572591091],"hsluv":[260.556144021857,82.0482136329290626,65.1123593572591091]},"#8899ff":{"lch":[65.9319161385595862,88.5102230179824829,261.65889869963604],"luv":[65.9319161385595862,-12.8398242875011679,-87.5739601191992],"rgb":[0.533333333333333326,0.6,1],"xyz":[0.395919289521932782,0.352358999153579544,0.993260538536693161],"hpluv":[261.65889869963604,170.348009793708229,65.9319161385595862],"hsluv":[261.65889869963604,99.9999999999983373,65.9319161385595862]},"#aa9900":{"lch":[62.7844580943873609,69.6780489210530618,75.8779002673010297],"luv":[62.7844580943873609,17.0006834702273615,67.5722373685362072],"rgb":[0.66666666666666663,0.6,0],"xyz":[0.279679277130872483,0.313290833923400402,0.0457396726625379293],"hpluv":[75.8779002673010297,140.82610179048271,62.7844580943873609],"hsluv":[75.8779002673010297,100.000000000002217,62.7844580943873609]},"#aa9911":{"lch":[62.8183644916567232,68.2796688580209548,75.7117398414304],"luv":[62.8183644916567232,16.8514534980901978,66.1675274916835576],"rgb":[0.66666666666666663,0.6,0.0666666666666666657],"xyz":[0.280690942630509588,0.313695500123255255,0.0510677776272935591],"hpluv":[75.7117398414304,137.925354096716262,62.8183644916567232],"hsluv":[75.7117398414304,97.9039601429264792,62.8183644916567232]},"#aa9922":{"lch":[62.8811408657966098,65.7186920323652259,75.3888160486312415],"luv":[62.8811408657966098,16.5780820569936154,63.5933461751813311],"rgb":[0.66666666666666663,0.6,0.133333333333333331],"xyz":[0.282566300768986645,0.314445643378646056,0.0609446638232727586],"hpluv":[75.3888160486312415,132.619634057532949,62.8811408657966098],"hsluv":[75.3888160486312415,94.0678156084237287,62.8811408657966098]},"#aa9933":{"lch":[62.984284118013818,61.5887344728930373,74.8105333616033477],"luv":[62.984284118013818,16.1369729495721401,59.4371122952427768],"rgb":[0.66666666666666663,0.6,0.2],"xyz":[0.28565405150144435,0.315680743671629183,0.0772068176808839],"hpluv":[74.8105333616033477,124.08189266143988,62.984284118013818],"hsluv":[74.8105333616033477,87.8877322232676335,62.984284118013818]},"#aa9944":{"lch":[63.1327254984845325,55.810649390305,73.8551623649617284],"luv":[63.1327254984845325,15.5190685808424753,53.6095802609072862],"rgb":[0.66666666666666663,0.6,0.266666666666666663],"xyz":[0.290112046745663266,0.317463941769316749,0.10068559263377054],"hpluv":[73.8551623649617284,112.176494362550613,63.1327254984845325],"hsluv":[73.8551623649617284,79.2518346201028407,63.1327254984845325]},"#aa9955":{"lch":[63.330394330910508,48.4114193249398497,72.2912631539462893],"luv":[63.330394330910508,14.725704471349518,46.1174495053405593],"rgb":[0.66666666666666663,0.6,0.333333333333333315],"xyz":[0.296074460785025251,0.319848907385061609,0.132087639907744442],"hpluv":[72.2912631539462893,97.0007181904759,63.330394330910508],"hsluv":[72.2912631539462893,68.2014618333714253,63.330394330910508]},"#aa9966":{"lch":[63.5804407621292285,39.5252766283835086,69.6158026784446662],"luv":[63.5804407621292285,13.7671883687516523,37.0501284339143524],"rgb":[0.66666666666666663,0.6,0.4],"xyz":[0.303659456558533436,0.322882905694464928,0.172035284314888404],"hpluv":[69.6158026784446662,78.8843243984218105,63.5804407621292285],"hsluv":[69.6158026784446662,54.9106459007729129,63.5804407621292285]},"#aa9977":{"lch":[63.8853523521207762,29.4269320044373437,64.5162682653354835],"luv":[63.8853523521207762,12.6610788645847681,26.563911782313685],"rgb":[0.66666666666666663,0.6,0.466666666666666674],"xyz":[0.312973469578735342,0.326608510902545723,0.221089086221286313],"hpluv":[64.5162682653354835,58.4497984351079,63.8853523521207762],"hsluv":[64.5162682653354835,39.6604297676390303,63.8853523521207762]},"#aa9988":{"lch":[64.2470245358341288,18.7498828458428441,52.4386898809200943],"luv":[64.2470245358341288,11.4301164327749429,14.8630597477787205],"rgb":[0.66666666666666663,0.6,0.533333333333333326],"xyz":[0.324113886680679142,0.331064677743323321,0.279761949624858508],"hpluv":[52.4386898809200943,37.0326564248891472,64.2470245358341288],"hsluv":[52.4386898809200943,22.8076315183033955,64.2470245358341288]},"#aa9999":{"lch":[64.6668097656484,10.3324715423982241,12.1770506300641514],"luv":[64.6668097656484,10.0999956892392,2.17946214737001709],"rgb":[0.66666666666666663,0.6,0.6],"xyz":[0.337170850789751841,0.336287463386952479,0.348528627265976387],"hpluv":[12.1770506300641514,20.2750581327120152,64.6668097656484],"hsluv":[12.1770506300641514,9.39861318597140283,64.6668097656484]},"#aa99aa":{"lch":[65.1455571833188,14.2173372068657535,307.715012949255367],"luv":[65.1455571833188,8.69723339065650514,-11.2468132643064216],"rgb":[0.66666666666666663,0.6,0.66666666666666663],"xyz":[0.352228543755004397,0.342310540573053601,0.427832476882975],"hpluv":[307.715012949255367,27.6931773999722353,65.1455571833188],"hsluv":[307.715012949255367,11.6506794595111955,65.1455571833188]},"#aa99bb":{"lch":[65.6836488991384186,26.2061362707181722,286.054514249721478],"luv":[65.6836488991384186,7.24735484809431529,-25.1840708771488],"rgb":[0.66666666666666663,0.6,0.733333333333333282],"xyz":[0.369366135862341072,0.34916557741598836,0.51809046198161679],"hpluv":[286.054514249721478,50.6273330900370553,65.6836488991384186],"hsluv":[286.054514249721478,27.5721610485895,65.6836488991384186]},"#aa99cc":{"lch":[66.2810360009151651,39.8419200501833544,278.33213307587846],"luv":[66.2810360009151651,5.77353773601307907,-39.4213756139487757],"rgb":[0.66666666666666663,0.6,0.8],"xyz":[0.388658511306062771,0.356882527593477161,0.619696972651887],"hpluv":[278.33213307587846,76.2764194246967,66.2810360009151651],"hsluv":[278.33213307587846,44.416066179202609,66.2810360009151651]},"#aa99dd":{"lch":[66.937275739096421,53.9476968390211695,274.567192844176702],"luv":[66.937275739096421,4.29575598209881182,-53.7763932853180151],"rgb":[0.66666666666666663,0.6,0.866666666666666696],"xyz":[0.41017683685669637,0.365489857813730668,0.733026820551892944],"hpluv":[274.567192844176702,102.269045280662851,66.937275739096421],"hsluv":[274.567192844176702,62.1125641321495365,66.937275739096421]},"#aa99ee":{"lch":[67.6515703211096309,68.1578213039093299,272.380002942583644],"luv":[67.6515703211096309,2.83038594926376286,-68.0990273078393358],"rgb":[0.66666666666666663,0.6,0.933333333333333348],"xyz":[0.433989017122871079,0.375014729920200685,0.858437636620416167],"hpluv":[272.380002942583644,127.843056183363871,67.6515703211096309],"hsluv":[272.380002942583644,80.63443597048024,67.6515703211096309]},"#aa99ff":{"lch":[68.4228071241374778,82.2834014236355387,270.968064044661787],"luv":[68.4228071241374778,1.39018638405132466,-82.2716569157370543],"rgb":[0.66666666666666663,0.6,1],"xyz":[0.4601600655327025,0.385483149284133408,0.996271824912198],"hpluv":[270.968064044661787,152.598644218259693,68.4228071241374778],"hsluv":[270.968064044661787,99.9999999999981668,68.4228071241374778]},"#770000":{"lch":[23.4140868272264697,78.7423116347599432,12.177050630061796],"luv":[23.4140868272264697,76.9706458719381317,16.6093743302492847],"rgb":[0.466666666666666674,0,0],"xyz":[0.0760757904266185919,0.0392265794387260461,0.00356605267624767169],"hpluv":[12.177050630061796,426.746789183125429,23.4140868272264697],"hsluv":[12.177050630061796,100.000000000002359,23.4140868272264697]},"#770011":{"lch":[23.5491569362977273,75.7570426868466456,9.89164947332394462],"luv":[23.5491569362977273,74.6308667748156864,13.0139633123970793],"rgb":[0.466666666666666674,0,0.0666666666666666657],"xyz":[0.0770874559262557102,0.0396312456385809,0.00889415764100330228],"hpluv":[9.89164947332394462,408.213135586655085,23.5491569362977273],"hsluv":[9.89164947332394462,99.9999999999965183,23.5491569362977273]},"#770022":{"lch":[23.7971287372198219,70.9964864167640854,5.53723409440817704],"luv":[23.7971287372198219,70.6651956613751224,6.85063542055327357],"rgb":[0.466666666666666674,0,0.133333333333333331],"xyz":[0.0789628140647327392,0.0403813888939717203,0.0187710438369825],"hpluv":[5.53723409440817704,378.574731225432288,23.7971287372198219],"hsluv":[5.53723409440817704,99.9999999999967741,23.7971287372198219]},"#770033":{"lch":[24.198804347572846,65.0463245726941182,358.140059561726389],"luv":[24.198804347572846,65.0120550988218895,-2.11116845467566527],"rgb":[0.466666666666666674,0,0.2],"xyz":[0.0820505647971904728,0.0416164891869548331,0.0350331976945936416],"hpluv":[358.140059561726389,341.089366306392606,24.198804347572846],"hsluv":[358.140059561726389,99.9999999999971578,24.198804347572846]},"#770044":{"lch":[24.764944554878376,59.7650645123016702,347.391874641304071],"luv":[24.764944554878376,58.3238787679626398,-13.0456161839744915],"rgb":[0.466666666666666674,0,0.266666666666666663],"xyz":[0.0865085600414093464,0.0433996872846424062,0.0585119726474802801],"hpluv":[347.391874641304071,306.231145677972847,24.764944554878376],"hsluv":[347.391874641304071,99.9999999999975557,24.764944554878376]},"#770055":{"lch":[25.4983947844981387,57.0853266397623571,333.997796644431901],"luv":[25.4983947844981387,51.3069893372134587,-25.0265331742018731],"rgb":[0.466666666666666674,0,0.333333333333333315],"xyz":[0.0924709740807713454,0.0457846529003872391,0.0899140199214541885],"hpluv":[333.997796644431901,284.086748448009075,25.4983947844981387],"hsluv":[333.997796644431901,99.999999999998,25.4983947844981387]},"#770066":{"lch":[26.3955149445472088,58.0812929265372375,320.022905340944305],"luv":[26.3955149445472088,44.5077732621065394,-37.3161453966930949],"rgb":[0.466666666666666674,0,0.4],"xyz":[0.100055969854279517,0.0488186512097905506,0.129861664328598164],"hpluv":[320.022905340944305,279.219318659546161,26.3955149445472088],"hsluv":[320.022905340944305,99.9999999999984,26.3955149445472088]},"#770077":{"lch":[27.4476614837194361,62.5213221502200156,307.715012949243601],"luv":[27.4476614837194361,38.2464397320582776,-49.4583215569799322],"rgb":[0.466666666666666674,0,0.466666666666666674],"xyz":[0.109369982874481436,0.052544256417871367,0.178915466234996073],"hpluv":[307.715012949243601,289.04278373048345,27.4476614837194361],"hsluv":[307.715012949243601,99.9999999999988631,27.4476614837194361]},"#770088":{"lch":[28.6427236217895711,69.3985842918787341,298.067280282401043],"luv":[28.6427236217895711,32.6525926425722872,-61.2370124633397808],"rgb":[0.466666666666666674,0,0.533333333333333326],"xyz":[0.120510399976425264,0.0570004232586489579,0.237588329638568241],"hpluv":[298.067280282401043,307.450798390810235,28.6427236217895711],"hsluv":[298.067280282401043,99.9999999999991473,28.6427236217895711]},"#770099":{"lch":[29.9665727349335924,77.70857748467688,290.909274437861086],"luv":[29.9665727349335924,27.7333531267432782,-72.5912125469701],"rgb":[0.466666666666666674,0,0.6],"xyz":[0.133567364085497964,0.0622232089022781223,0.30635500727968612],"hpluv":[290.909274437861086,329.057057444315717,29.9665727349335924],"hsluv":[290.909274437861086,99.9999999999993605,29.9665727349335924]},"#7700aa":{"lch":[31.4042918618800115,86.7647813143177,285.668616902051383],"luv":[31.4042918618800115,23.4328336498598695,-83.5405864455078415],"rgb":[0.466666666666666674,0,0.66666666666666663],"xyz":[0.14862505705075052,0.0682462860883792238,0.385658856896684721],"hpluv":[285.668616902051383,350.585377409449279,31.4042918618800115],"hsluv":[285.668616902051383,99.9999999999996447,31.4042918618800115]},"#7700bb":{"lch":[32.9411141237069387,96.170393631615,281.802895608829544],"luv":[32.9411141237069387,19.6712233173334745,-94.1370680681067853],"rgb":[0.466666666666666674,0,0.733333333333333282],"xyz":[0.165762649158087166,0.0751013229313139824,0.475916841995326467],"hpluv":[281.802895608829544,370.460950364720645,32.9411141237069387],"hsluv":[281.802895608829544,99.9999999999998295,32.9411141237069387]},"#7700cc":{"lch":[34.5630635499026226,105.713400517707811,278.906152205018032],"luv":[34.5630635499026226,16.3661753747823724,-104.438840249301762],"rgb":[0.466666666666666674,0,0.8],"xyz":[0.185055024601808893,0.082818273108802784,0.577523352665596623],"hpluv":[278.906152205018032,388.112061604616713,34.5630635499026226],"hsluv":[278.906152205018032,99.9999999999998721,34.5630635499026226]},"#7700dd":{"lch":[36.2573361534597964,115.285120662302717,276.696107756350386],"luv":[36.2573361534597964,13.4426218553338188,-114.498711624961956],"rgb":[0.466666666666666674,0,0.866666666666666696],"xyz":[0.206573350152442436,0.091425603329056318,0.690853200565602621],"hpluv":[276.696107756350386,403.475057258468723,36.2573361534597964],"hsluv":[276.696107756350386,100.000000000000156,36.2573361534597964]},"#7700ee":{"lch":[38.012479203832,124.831519574090535,274.979891409884715],"luv":[38.012479203832,10.8361388436516783,-124.360308676593633],"rgb":[0.466666666666666674,0,0.933333333333333348],"xyz":[0.230385530418617201,0.100950475435526349,0.816264016634125844],"hpluv":[274.979891409884715,416.713325299391272,38.012479203832],"hsluv":[274.979891409884715,100.000000000000156,38.012479203832]},"#7700ff":{"lch":[39.8184284160989037,134.326708962856742,273.625091115001112],"luv":[39.8184284160989037,8.49315165227522861,-134.057939398617776],"rgb":[0.466666666666666674,0,1],"xyz":[0.256556578828448567,0.111418894799459045,0.954098204925907689],"hpluv":[273.625091115001112,428.072753406140123,39.8184284160989037],"hsluv":[273.625091115001112,100.000000000000313,39.8184284160989037]},"#771100":{"lch":[24.7134353555624457,74.5310598854495794,14.479461840222152],"luv":[24.7134353555624457,72.1637543524892351,18.6352205622059],"rgb":[0.466666666666666674,0.0666666666666666657,0],"xyz":[0.078080190687547,0.0432353799605829231,0.00423418609655712257],"hpluv":[14.479461840222152,382.686818993669249,24.7134353555624457],"hsluv":[14.479461840222152,100.000000000002174,24.7134353555624457]},"#771111":{"lch":[24.8400617115613187,71.7342088143168723,12.1770506300618244],"luv":[24.8400617115613187,70.1202221387804912,15.1311321924069837],"rgb":[0.466666666666666674,0.0666666666666666657,0.0666666666666666657],"xyz":[0.0790918561871841175,0.043640046160437776,0.00956229106131275403],"hpluv":[12.1770506300618244,366.448517223619376,24.8400617115613187],"hsluv":[12.1770506300618244,85.8702458957174173,24.8400617115613187]},"#771122":{"lch":[25.0727380413203562,67.2476760425649616,7.76714475492354417],"luv":[25.0727380413203562,66.6307123231625,9.0883501491595],"rgb":[0.466666666666666674,0.0666666666666666657,0.133333333333333331],"xyz":[0.0809672143256611465,0.0443901894158286,0.0194391772572919501],"hpluv":[7.76714475492354417,340.341449223453765,25.0727380413203562],"hsluv":[7.76714475492354417,86.6206298981217,25.0727380413203562]},"#771133":{"lch":[25.4501908259833556,61.6001849310061189,0.209311103178295294],"luv":[25.4501908259833556,61.599773884646936,0.225035318388215971],"rgb":[0.466666666666666674,0.0666666666666666657,0.2],"xyz":[0.0840549650581188801,0.0456252897088117101,0.0357013311149031],"hpluv":[0.209311103178295294,307.135699817562568,25.4501908259833556],"hsluv":[0.209311103178295294,87.6964449022470802,25.4501908259833556]},"#771144":{"lch":[25.9833113937366775,56.5829308746863688,349.098656617234155],"luv":[25.9833113937366775,55.5618510799655,-10.7008771106518541],"rgb":[0.466666666666666674,0.0666666666666666657,0.266666666666666663],"xyz":[0.0885129603023377537,0.0474084878064992832,0.0591801060677897353],"hpluv":[349.098656617234155,276.331419289390624,25.9833113937366775],"hsluv":[349.098656617234155,88.9762099121112442,25.9833113937366775]},"#771155":{"lch":[26.6758393728738312,54.157242934368746,335.112354986374442],"luv":[26.6758393728738312,49.127918835603694,-22.7915456504066185],"rgb":[0.466666666666666674,0.0666666666666666657,0.333333333333333315],"xyz":[0.0944753743416997527,0.0497934534222441161,0.0905821533417636438],"hpluv":[335.112354986374442,257.618934567198892,26.6758393728738312],"hsluv":[335.112354986374442,90.3225181656420375,26.6758393728738312]},"#771166":{"lch":[27.5255776115618076,55.4731266930874796,320.490705765847224],"luv":[27.5255776115618076,42.7987039146097388,-35.2921907557026557],"rgb":[0.466666666666666674,0.0666666666666666657,0.4],"xyz":[0.102060370115207924,0.0528274517316474276,0.130529797748907606],"hpluv":[320.490705765847224,255.732268141411282,27.5255776115618076],"hsluv":[320.490705765847224,91.6238582413064364,27.5255776115618076]},"#771177":{"lch":[28.525624322061,60.3055315504910538,307.715012949243658],"luv":[28.525624322061,36.8909645322892956,-47.7054909990940672],"rgb":[0.466666666666666674,0.0666666666666666657,0.466666666666666674],"xyz":[0.111374383135409843,0.056553056939728244,0.179583599655305515],"hpluv":[307.715012949243658,268.263334170626,28.525624322061],"hsluv":[307.715012949243658,92.8109433172232201,28.525624322061]},"#771188":{"lch":[29.665668786552871,67.5901402176946,297.828537901307072],"luv":[29.665668786552871,31.5529142063876336,-59.77324367751811],"rgb":[0.466666666666666674,0.0666666666666666657,0.533333333333333326],"xyz":[0.122514800237353672,0.0610092237805058418,0.238256463058877682],"hpluv":[297.828537901307072,289.113605882780575,29.665668786552871],"hsluv":[297.828537901307072,93.8529472884676892,29.665668786552871]},"#771199":{"lch":[30.9332504381216253,76.2730393291315494,290.583951381139741],"luv":[30.9332504381216253,26.816032696200331,-71.4036197887723461],"rgb":[0.466666666666666674,0.0666666666666666657,0.6],"xyz":[0.135571764346426371,0.066232009424135,0.307023140699995589],"hpluv":[290.583951381139741,312.885056330098905,30.9332504381216253],"hsluv":[290.583951381139741,94.745562802664864,30.9332504381216253]},"#7711aa":{"lch":[32.3148680584756391,85.6471240548678452,285.332056603477554],"luv":[32.3148680584756391,22.6461849228904,-82.5989114172104166],"rgb":[0.466666666666666674,0.0666666666666666657,0.66666666666666663],"xyz":[0.150629457311678927,0.0722550866102361078,0.38632699031699419],"hpluv":[285.332056603477554,336.317699636744408,32.3148680584756391],"hsluv":[285.332056603477554,95.4992611083078771,32.3148680584756391]},"#7711bb":{"lch":[33.796865882550442,95.3131880713117,281.486339493443666],"luv":[33.796865882550442,18.9801244444786903,-93.4042755787407],"rgb":[0.466666666666666674,0.0666666666666666657,0.733333333333333282],"xyz":[0.167767049419015574,0.0791101234531708664,0.476584975415635936],"hpluv":[281.486339493443666,357.862255189103962,33.796865882550442],"hsluv":[281.486339493443666,96.130904738193,33.796865882550442]},"#7711cc":{"lch":[35.36607449089243,105.064609202725904,278.619980375929231],"luv":[35.36607449089243,15.7470979978009513,-103.877817707002151],"rgb":[0.466666666666666674,0.0666666666666666657,0.8],"xyz":[0.1870594248627373,0.086827073630659668,0.578191486085906092],"hpluv":[278.619980375929231,376.971848031202455,35.36607449089243],"hsluv":[278.619980375929231,96.6587778670915441,35.36607449089243]},"#7711dd":{"lch":[37.0102245888209,114.800572621107989,276.441726024966442],"luv":[37.0102245888209,12.8797770828984923,-114.075776641796878],"rgb":[0.466666666666666674,0.0666666666666666657,0.866666666666666696],"xyz":[0.208577750413370844,0.0954344038509132,0.69152133398591209],"hpluv":[276.441726024966442,393.605954910771402,37.0102245888209],"hsluv":[276.441726024966442,97.1000737310191084,37.0102245888209]},"#7711ee":{"lch":[38.7181742300654648,124.475046910670883,274.755182332196796],"luv":[38.7181742300654648,10.3187754184265525,-124.046604859938796],"rgb":[0.466666666666666674,0.0666666666666666657,0.933333333333333348],"xyz":[0.232389930679545609,0.104959275957383219,0.816932150054435313],"hpluv":[274.755182332196796,407.949828918098,38.7181742300654648],"hsluv":[274.755182332196796,97.4698666617264706,38.7181742300654648]},"#7711ff":{"lch":[40.4799968781786,134.069342311184641,273.42679883886251],"luv":[40.4799968781786,8.01376323316973682,-133.829623576382744],"rgb":[0.466666666666666674,0.0666666666666666657,1],"xyz":[0.258560979089377,0.115427695321315929,0.954766338346217158],"hpluv":[273.42679883886251,420.269946860795244,40.4799968781786],"hsluv":[273.42679883886251,99.99999999999946,40.4799968781786]},"#772200":{"lch":[26.9238486490213944,67.8779226750429814,18.9619118830866213],"luv":[26.9238486490213944,64.1945131058521241,22.0562207502031953],"rgb":[0.466666666666666674,0.133333333333333331,0],"xyz":[0.0817958144223149414,0.0506666274301188907,0.00547272734147973266],"hpluv":[18.9619118830866213,319.912145739235086,26.9238486490213944],"hsluv":[18.9619118830866213,100.000000000002203,26.9238486490213944]},"#772211":{"lch":[27.0378210495853537,65.3114997865878451,16.6506371445360628],"luv":[27.0378210495853537,62.5729698674152957,18.7140440938083152],"rgb":[0.466666666666666674,0.133333333333333331,0.0666666666666666657],"xyz":[0.0828074799219520596,0.0510712936299737436,0.0108008323062353633],"hpluv":[16.6506371445360628,306.518925183772069,27.0378210495853537],"hsluv":[16.6506371445360628,87.77659617077137,27.0378210495853537]},"#772222":{"lch":[27.2475131582451553,61.1491638550902934,12.1770506300618262],"luv":[27.2475131582451553,59.7733358183195094,12.8983939049434628],"rgb":[0.466666666666666674,0.133333333333333331,0.133333333333333331],"xyz":[0.0846828380604290887,0.0518214368853645649,0.0206777185022145593],"hpluv":[12.1770506300618262,284.775733052529233,27.2475131582451553],"hsluv":[12.1770506300618262,66.7317810633447,27.2475131582451553]},"#772233":{"lch":[27.5884028886125066,55.830319472153235,4.36926883706767555],"luv":[27.5884028886125066,55.668063043001986,4.25339034219168255],"rgb":[0.466666666666666674,0.133333333333333331,0.2],"xyz":[0.0877705887928868222,0.0530565371783476777,0.0369398723598257],"hpluv":[4.36926883706767555,256.792821962959806,27.5884028886125066],"hsluv":[4.36926883706767555,69.0869865520346,27.5884028886125066]},"#772244":{"lch":[28.0713586292933357,51.0577981227000137,352.597218961633928],"luv":[28.0713586292933357,50.6322267647614197,-6.57847717790113862],"rgb":[0.466666666666666674,0.133333333333333331,0.266666666666666663],"xyz":[0.0922285840371057,0.0548397352760352508,0.0604186473127123411],"hpluv":[352.597218961633928,230.801153887638264,28.0713586292933357],"hsluv":[352.597218961633928,71.9536276136468871,28.0713586292933357]},"#772255":{"lch":[28.7011983995690869,48.8793621784160877,337.425357822166575],"luv":[28.7011983995690869,45.134235573623549,-18.7641367015226166],"rgb":[0.466666666666666674,0.133333333333333331,0.333333333333333315],"xyz":[0.0981909980764677,0.0572247008917800837,0.0918206945866862495],"hpluv":[337.425357822166575,216.105005327694982,28.7011983995690869],"hsluv":[337.425357822166575,75.0482997779786416,28.7011983995690869]},"#772266":{"lch":[29.4776386596593341,50.6214045611569148,321.457127980188602],"luv":[29.4776386596593341,39.5931335065919541,-31.5421999688275427],"rgb":[0.466666666666666674,0.133333333333333331,0.4],"xyz":[0.105775993849975866,0.0602586992011833952,0.131768338993830225],"hpluv":[321.457127980188602,217.911839443782668,29.4776386596593341],"hsluv":[321.457127980188602,78.1196257410634871,29.4776386596593341]},"#772277":{"lch":[30.3962065887853328,56.0773495547330114,307.715012949243828],"luv":[30.3962065887853328,34.3044404103525125,-44.3607315225559375],"rgb":[0.466666666666666674,0.133333333333333331,0.466666666666666674],"xyz":[0.115090006870177786,0.0639843044092642116,0.180822140900228134],"hpluv":[307.715012949243828,234.103236488433623,30.3962065887853328],"hsluv":[307.715012949243828,80.9925899090149,30.3962065887853328]},"#772288":{"lch":[31.4492100235983827,64.0564791390884,297.353574907339521],"luv":[31.4492100235983827,29.432687880373738,-56.8941948166328118],"rgb":[0.466666666666666674,0.133333333333333331,0.533333333333333326],"xyz":[0.126230423972121614,0.0684404712500418094,0.239495004303800302],"hpluv":[297.353574907339521,258.459589193709576,31.4492100235983827],"hsluv":[297.353574907339521,83.5725358287189692,31.4492100235983827]},"#772299":{"lch":[32.6267183371791276,73.3979299617999885,289.947447059718741],"luv":[32.6267183371791276,25.040297814612174,-68.9944896932561136],"rgb":[0.466666666666666674,0.133333333333333331,0.6],"xyz":[0.139287388081194341,0.073663256893670967,0.308261681944918209],"hpluv":[289.947447059718741,285.462946683821,32.6267183371791276],"hsluv":[289.947447059718741,85.8272099061853169,32.6267183371791276]},"#7722aa":{"lch":[33.91747454857272,83.3484305918169213,284.681710760769079],"luv":[33.91747454857272,21.1245907707188039,-80.6269963900962],"rgb":[0.466666666666666674,0.133333333333333331,0.66666666666666663],"xyz":[0.154345081046446869,0.0796863340797720754,0.38756553156191681],"hpluv":[284.681710760769079,311.826661765562392,33.91747454857272],"hsluv":[284.681710760769079,87.7639475735253,33.91747454857272]},"#7722bb":{"lch":[35.3096729107126137,93.4985765466947,280.880145280973409],"luv":[35.3096729107126137,17.6483381470917493,-91.8178630599952186],"rgb":[0.466666666666666674,0.133333333333333331,0.733333333333333282],"xyz":[0.171482673153783516,0.086541370922706834,0.477823516660558556],"hpluv":[280.880145280973409,336.008784107710085,35.3096729107126137],"hsluv":[280.880145280973409,89.410850129911168,35.3096729107126137]},"#7722cc":{"lch":[36.7915673195940158,103.646851370476796,278.075561058441508],"luv":[36.7915673195940158,14.5601992392030191,-102.619054746808203],"rgb":[0.466666666666666674,0.133333333333333331,0.8],"xyz":[0.19077504859750527,0.0942583211001956356,0.579430027330828712],"hpluv":[278.075561058441508,357.476214898523438,36.7915673195940158],"hsluv":[278.075561058441508,90.8041771911133395,36.7915673195940158]},"#7722dd":{"lch":[38.351906528896663,113.703099806952181,275.960131804992216],"luv":[38.351906528896663,11.8065226659589069,-113.088465053903391],"rgb":[0.466666666666666674,0.133333333333333331,0.866666666666666696],"xyz":[0.212293374148138814,0.10286565132044917,0.69275987523083471],"hpluv":[275.960131804992216,376.205095027198126,38.351906528896663],"hsluv":[275.960131804992216,91.9810564333708101,38.351906528896663]},"#7722ee":{"lch":[39.9802139341708269,123.633267676123751,274.331320845995606],"luv":[39.9802139341708269,9.33725773346982812,-123.280170726255989],"rgb":[0.466666666666666674,0.133333333333333331,0.933333333333333348],"xyz":[0.236105554414313523,0.112390523426919187,0.818170691299357933],"hpluv":[274.331320845995606,392.400507860275241,39.9802139341708269],"hsluv":[274.331320845995606,92.975835565241681,39.9802139341708269]},"#7722ff":{"lch":[41.6669409214524222,133.430100966175758,273.053819065229],"luv":[41.6669409214524222,7.10835060884393233,-133.240621416539511],"rgb":[0.466666666666666674,0.133333333333333331,1],"xyz":[0.262276602824144944,0.122858942790851897,0.956004879591139778],"hpluv":[273.053819065229,406.351179140502,41.6669409214524222],"hsluv":[273.053819065229,99.9999999999994,41.6669409214524222]},"#eeaa00":{"lch":[74.1441199778221716,94.3993067628715323,52.9277228913731435],"luv":[74.1441199778221716,56.9059790518510553,75.3189130661151438],"rgb":[0.933333333333333348,0.66666666666666663,0],"xyz":[0.496332043879122442,0.469286695915611562,0.0644413600602487119],"hpluv":[52.9277228913731435,161.559096825574699,74.1441199778221716],"hsluv":[52.9277228913731435,100.00000000000226,74.1441199778221716]},"#eeaa11":{"lch":[74.170022976797469,93.4032488378738748,52.6298301838218165],"luv":[74.170022976797469,56.6922374254564474,74.2304325001913412],"rgb":[0.933333333333333348,0.66666666666666663,0.0666666666666666657],"xyz":[0.497343709378759546,0.469691362115466415,0.0697694650250043485],"hpluv":[52.6298301838218165,159.798572537124,74.170022976797469],"hsluv":[52.6298301838218165,98.6103970010943698,74.170022976797469]},"#eeaa22":{"lch":[74.2180009061856794,91.5777923210439866,52.06484069365154],"luv":[74.2180009061856794,56.2992155036066038,72.2280442769616],"rgb":[0.933333333333333348,0.66666666666666663,0.133333333333333331],"xyz":[0.499219067517236603,0.470441505370857216,0.0796463512209835411],"hpluv":[52.06484069365154,156.574215350823607,74.2180009061856794],"hsluv":[52.06484069365154,96.0561964998804427,74.2180009061856794]},"#eeaa33":{"lch":[74.296884894391,88.6315089581908353,51.0969321655322659],"luv":[74.296884894391,55.6610065739707096,68.9738843866158646],"rgb":[0.933333333333333348,0.66666666666666663,0.2],"xyz":[0.502306818249694365,0.471676605663840343,0.0959085050785946913],"hpluv":[51.0969321655322659,151.375944062314744,74.296884894391],"hsluv":[51.0969321655322659,91.9112466174575786,74.296884894391]},"#eeaa44":{"lch":[74.4105324975616,84.5080331915566,49.6113532778883268],"luv":[74.4105324975616,54.7585847399730952,64.3669563610119582],"rgb":[0.933333333333333348,0.66666666666666663,0.266666666666666663],"xyz":[0.506764813493913224,0.473459803761527909,0.11938728003148133],"hpluv":[49.6113532778883268,144.112916810009352,74.4105324975616],"hsluv":[49.6113532778883268,86.056132752536,74.4105324975616]},"#eeaa55":{"lch":[74.5620870475656545,79.2349762990306203,47.4460085751506284],"luv":[74.5620870475656545,53.5853993814341081,58.3676832008958897],"rgb":[0.933333333333333348,0.66666666666666663,0.333333333333333315],"xyz":[0.512727227533275154,0.475844769377272769,0.150789327305455245],"hpluv":[47.4460085751506284,134.846041865267,74.5620870475656545],"hsluv":[47.4460085751506284,78.4547380743125302,74.5620870475656545]},"#eeaa66":{"lch":[74.7541548019056705,72.9335579755352512,44.3584242628533616],"luv":[74.7541548019056705,52.1460491859645643,50.9911113162453518],"rgb":[0.933333333333333348,0.66666666666666663,0.4],"xyz":[0.520312223306783395,0.478878767686676088,0.190736971712599179],"hpluv":[44.3584242628533616,123.803063546095515,74.7541548019056705],"hsluv":[44.3584242628533616,69.1456590086766,74.7541548019056705]},"#eeaa77":{"lch":[74.988898345165353,65.8409092602829702,39.9757578623994689],"luv":[74.988898345165353,50.4549646902964213,42.3003767160737851],"rgb":[0.933333333333333348,0.66666666666666663,0.466666666666666674],"xyz":[0.529626236326985245,0.482604372894756883,0.239790773618997088],"hpluv":[39.9757578623994689,111.41359114675457,74.988898345165353],"hsluv":[39.9757578623994689,69.3768546233612398,74.988898345165353]},"#eeaa88":{"lch":[75.268091919562039,58.355059996267,33.7246537035848917],"luv":[75.268091919562039,48.5347963512250544,32.3988668060016],"rgb":[0.933333333333333348,0.66666666666666663,0.533333333333333326],"xyz":[0.540766653428929156,0.487060539735534481,0.298463637022569284],"hpluv":[33.7246537035848917,98.3800275430836706,75.268091919562039],"hsluv":[33.7246537035848917,69.7313730072723388,75.268091919562039]},"#eeaa99":{"lch":[75.5931575717450102,51.1191249468368198,24.7740386445795764],"luv":[75.5931575717450102,46.4145012045046172,21.4209946843594],"rgb":[0.933333333333333348,0.66666666666666663,0.6],"xyz":[0.5538236175380018,0.492283325379163639,0.367230314663687163],"hpluv":[24.7740386445795764,85.8104641434512274,75.5931575717450102],"hsluv":[24.7740386445795764,70.1099573125584925,75.5931575717450102]},"#eeaaaa":{"lch":[75.9651912478537,45.142946910964838,12.1770506300622827],"luv":[75.9651912478537,44.1272513869876164,9.52215001119964199],"rgb":[0.933333333333333348,0.66666666666666663,0.66666666666666663],"xyz":[0.568881310503254412,0.498306402565264761,0.446534164280685764],"hpluv":[12.1770506300622827,75.4075094474617771,75.9651912478537],"hsluv":[12.1770506300622827,70.5013292017584661,75.9651912478537]},"#eeaabb":{"lch":[76.3849837125259512,41.8257198613105743,355.706426922992932],"luv":[76.3849837125259512,41.7083375548448743,-3.13136077895000353],"rgb":[0.933333333333333348,0.66666666666666663,0.733333333333333282],"xyz":[0.586018902610591,0.505161439408199464,0.53679214937932751],"hpluv":[355.706426922992932,71.0120800923082243,76.3849837125259512],"hsluv":[355.706426922992932,70.8933377227291857,76.3849837125259512]},"#eeaacc":{"lch":[76.8530390510081,42.4751513806234229,337.329003704434115],"luv":[76.8530390510081,39.1932374848878169,-16.3715796507258275],"rgb":[0.933333333333333348,0.66666666666666663,0.8],"xyz":[0.605311278054312729,0.512878389585688321,0.638398660049597666],"hpluv":[337.329003704434115,73.8860979443606283,76.8530390510081],"hsluv":[337.329003704434115,71.273377003825658,76.8530390510081]},"#eeaadd":{"lch":[77.3695923472492666,47.3596417233686893,320.637369166639587],"luv":[77.3695923472492666,36.6159833837478814,-30.0367345929437413],"rgb":[0.933333333333333348,0.66666666666666663,0.866666666666666696],"xyz":[0.626829603604946328,0.521485719805941828,0.751728507949603664],"hpluv":[320.637369166639587,84.6581146126829,77.3695923472492666],"hsluv":[320.637369166639587,71.6287050870027144,77.3695923472492666]},"#eeaaee":{"lch":[77.9346274334411078,55.5926087174301244,307.715012949246329],"luv":[77.9346274334411078,34.00790779424905,-43.9772708506012506],"rgb":[0.933333333333333348,0.66666666666666663,0.933333333333333348],"xyz":[0.650641783871121,0.531010591912411845,0.877139324018126887],"hpluv":[307.715012949246329,102.440850498764817,77.9346274334411078],"hsluv":[307.715012949246329,71.9466349992656,77.9346274334411078]},"#eeaaff":{"lch":[78.5478951631237123,66.0054362136172,298.40296943037481],"luv":[78.5478951631237123,31.3967924706888546,-58.0599606639755166],"rgb":[0.933333333333333348,0.66666666666666663,1],"xyz":[0.676812832280952459,0.541479011276344568,1.01497351230990884],"hpluv":[298.40296943037481,125.797711632464541,78.5478951631237123],"hsluv":[298.40296943037481,99.9999999999967457,78.5478951631237123]},"#773300":{"lch":[30.1331354048611715,59.6402239078303253,26.8671398719653283],"luv":[30.1331354048611715,53.2024709950710601,26.952799257122777],"rgb":[0.466666666666666674,0.2,0],"xyz":[0.0879135365113257461,0.0629020716081407,0.0075119680378166135],"hpluv":[26.8671398719653283,251.150628123644026,30.1331354048611715],"hsluv":[26.8671398719653283,100.000000000002174,30.1331354048611715]},"#773311":{"lch":[30.23185303241101,57.2493346092074376,24.6191658238461528],"luv":[30.23185303241101,52.0451874365790204,23.8492091669378929],"rgb":[0.466666666666666674,0.2,0.0666666666666666657],"xyz":[0.0889252020109628644,0.0633067378079955473,0.012840073002572245],"hpluv":[24.6191658238461528,240.295148301589592,30.23185303241101],"hsluv":[24.6191658238461528,89.9983576544591131,30.23185303241101]},"#773322":{"lch":[30.4137421865898716,53.2944669038914185,20.1857997859538507],"luv":[30.4137421865898716,50.0210446853216055,18.3900867632275506],"rgb":[0.466666666666666674,0.2,0.133333333333333331],"xyz":[0.0908005601494399,0.0640568810633863617,0.022716959198551441],"hpluv":[20.1857997859538507,222.35740076876786,30.4137421865898716],"hsluv":[20.1857997859538507,72.5478159849102,30.4137421865898716]},"#773333":{"lch":[30.7101510688592612,48.0738359215612618,12.1770506300619186],"luv":[30.7101510688592612,46.9921967440780932,10.1403720532853221],"rgb":[0.466666666666666674,0.2,0.2],"xyz":[0.093888310881897627,0.0652919813563694745,0.0389791130561625843],"hpluv":[12.1770506300619186,198.639745699191,30.7101510688592612],"hsluv":[12.1770506300619186,46.5474493854848177,30.7101510688592612]},"#773344":{"lch":[31.1315732769052218,43.177963340605487,359.450637080068248],"luv":[31.1315732769052218,43.1759786068728815,-0.413992248148033204],"rgb":[0.466666666666666674,0.2,0.266666666666666663],"xyz":[0.0983463061261165,0.0670751794540570545,0.0624578880090492228],"hpluv":[359.450637080068248,175.995032884643848,31.1315732769052218],"hsluv":[359.450637080068248,50.753084379908266,31.1315732769052218]},"#773355":{"lch":[31.6836931484193158,40.8566925980369149,342.103665666318761],"luv":[31.6836931484193158,38.8798033655970627,-12.5550874271345432],"rgb":[0.466666666666666674,0.2,0.333333333333333315],"xyz":[0.1043087201654785,0.0694601450698018874,0.0938599352830231382],"hpluv":[342.103665666318761,163.631433468067485,31.6836931484193158],"hsluv":[342.103665666318761,55.4419897041632623,31.6836931484193158]},"#773366":{"lch":[32.368092831934419,42.8604868736005429,323.403106692152903],"luv":[32.368092831934419,34.4105334223914952,-25.55262265656037],"rgb":[0.466666666666666674,0.2,0.4],"xyz":[0.111893715938986671,0.0724941433792052,0.1338075796901671],"hpluv":[323.403106692152903,168.027093700417197,32.368092831934419],"hsluv":[323.403106692152903,60.2559031079253913,32.368092831934419]},"#773377":{"lch":[33.18286532501061,49.0630735877418189,307.715012949244226],"luv":[33.18286532501061,30.0135669321659,-38.8119954380674201],"rgb":[0.466666666666666674,0.2,0.466666666666666674],"xyz":[0.12120772895918859,0.0762197485872860153,0.182861381596565],"hpluv":[307.715012949244226,187.620458725202155,33.18286532501061],"hsluv":[307.715012949244226,64.9109644958811458,33.18286532501061]},"#773388":{"lch":[34.1232577260479,58.0074356166469371,296.464975996700218],"luv":[34.1232577260479,25.8510525803809479,-51.9286594021626868],"rgb":[0.466666666666666674,0.2,0.533333333333333326],"xyz":[0.132348146061132432,0.0806759154280636132,0.241534245000137177],"hpluv":[296.464975996700218,215.711106662248483,34.1232577260479],"hsluv":[296.464975996700218,69.2226633917654226,34.1232577260479]},"#773399":{"lch":[35.1823459678372572,68.3160830057283,288.793689920994325],"luv":[35.1823459678372572,22.0088074868374761,-64.6737936899706369],"rgb":[0.466666666666666674,0.2,0.6],"xyz":[0.145405110170205132,0.0858987010716927707,0.310300922641255084],"hpluv":[288.793689920994325,246.398176299420243,35.1823459678372572],"hsluv":[288.793689920994325,73.0971646513407,35.1823459678372572]},"#7733aa":{"lch":[36.3517007299652,79.1457370086552316,283.529620316849901],"luv":[36.3517007299652,18.5159885211015585,-76.9493720294691741],"rgb":[0.466666666666666674,0.2,0.66666666666666663],"xyz":[0.160462803135457688,0.0919217782577938791,0.389604772258253684],"hpluv":[283.529620316849901,276.275338575971432,36.3517007299652],"hsluv":[283.529620316849901,76.5077273075914093,36.3517007299652]},"#7733bb":{"lch":[37.6219984216960484,90.0609255961329183,279.823655256592],"luv":[37.6219984216960484,15.3658639022925581,-88.7404110074345596],"rgb":[0.466666666666666674,0.2,0.733333333333333282],"xyz":[0.177600395242794307,0.0987768151007286377,0.479862757356895431],"hpluv":[279.823655256592,303.762299466947354,37.6219984216960484],"hsluv":[279.823655256592,79.4699002038008615,37.6219984216960484]},"#7733cc":{"lch":[38.9835424310364687,100.85881095677091,277.137789072490136],"luv":[38.9835424310364687,12.5323059717609908,-100.077175492935524],"rgb":[0.466666666666666674,0.2,0.8],"xyz":[0.196892770686516061,0.106493765278217439,0.581469268027165587],"hpluv":[277.137789072490136,328.300745951509327,38.9835424310364687],"hsluv":[277.137789072490136,82.0218198813884,38.9835424310364687]},"#7733dd":{"lch":[40.4266769703902469,111.457640409912926,275.137669231249674],"luv":[40.4266769703902469,9.98093438608736,-111.009848907770674],"rgb":[0.466666666666666674,0.2,0.866666666666666696],"xyz":[0.218411096237149605,0.115101095498470973,0.694799115927171584],"hpluv":[275.137669231249674,349.849394775278881,40.4266769703902469],"hsluv":[275.137669231249674,84.2108753320266459,40.4266769703902469]},"#7733ee":{"lch":[41.9420918590451066,121.83559331992231,273.612094072304103],"luv":[41.9420918590451066,7.67578650940870766,-121.593561100411392],"rgb":[0.466666666666666674,0.2,0.933333333333333348],"xyz":[0.242223276503324342,0.12462596760494099,0.820209931995694808],"hpluv":[273.612094072304103,368.606867281158145,41.9420918590451066],"hsluv":[273.612094072304103,91.3228806729277665,41.9420918590451066]},"#7733ff":{"lch":[43.521028110395612,131.998699032970592,272.424037139620168],"luv":[43.521028110395612,5.58285979872954208,-131.88058319125102],"rgb":[0.466666666666666674,0.2,1],"xyz":[0.268394324913155735,0.135094386968873714,0.958044120287476653],"hpluv":[272.424037139620168,384.866252510120546,43.521028110395612],"hsluv":[272.424037139620168,99.9999999999993605,43.521028110395612]},"#eebb00":{"lch":[78.2979307719844115,92.4506686575273307,61.8965912674010781],"luv":[78.2979307719844115,43.5502151824584587,81.5506277890334275],"rgb":[0.933333333333333348,0.733333333333333282,0],"xyz":[0.530286541787721277,0.537195691732810121,0.0757595260297813378],"hpluv":[61.8965912674010781,173.778692590363192,78.2979307719844115],"hsluv":[61.8965912674010781,100.000000000002373,78.2979307719844115]},"#eebb11":{"lch":[78.3216028454340858,91.4822746680663528,61.6861071172261504],"luv":[78.3216028454340858,43.3901974999079059,80.5375523551748],"rgb":[0.933333333333333348,0.733333333333333282,0.0666666666666666657],"xyz":[0.531298207287358437,0.537600357932665,0.0810876309945369744],"hpluv":[61.6861071172261504,172.182825477748111,78.3216028454340858],"hsluv":[61.6861071172261504,98.7812238781787642,78.3216028454340858]},"#eebb22":{"lch":[78.3654531575016335,89.702527227679937,61.2866058237147371],"luv":[78.3654531575016335,43.0956539167563477,78.672155204492924],"rgb":[0.933333333333333348,0.733333333333333282,0.133333333333333331],"xyz":[0.533173565425835383,0.53835050118805583,0.090964517190516167],"hpluv":[61.2866058237147371,169.241982225815036,78.3654531575016335],"hsluv":[61.2866058237147371,96.5386826089343,78.3654531575016335]},"#eebb33":{"lch":[78.4375634156200192,86.8156112143301897,60.6012126372659665],"luv":[78.4375634156200192,42.6165086308843897,75.6358614853528906],"rgb":[0.933333333333333348,0.733333333333333282,0.2],"xyz":[0.5362613161582932,0.539585601481039,0.107226671048127303],"hpluv":[60.6012126372659665,164.44952499458185,78.4375634156200192],"hsluv":[60.6012126372659665,92.89304460263088,78.4375634156200192]},"#eebb44":{"lch":[78.5414800230656,82.7424491039972878,59.5464137785053],"luv":[78.5414800230656,41.9372005918819397,71.3273025583039839],"rgb":[0.933333333333333348,0.733333333333333282,0.266666666666666663],"xyz":[0.540719311402512059,0.541368799578726523,0.130705446001013942],"hpluv":[59.5464137785053,157.640041580932575,78.5414800230656],"hsluv":[59.5464137785053,87.729612164687,78.5414800230656]},"#eebb55":{"lch":[78.6801087960333,77.4695312482544,58.0014729567720551],"luv":[78.6801087960333,41.0509080282697809,65.6989438414256455],"rgb":[0.933333333333333348,0.733333333333333282,0.333333333333333315],"xyz":[0.546681725441874,0.543753765194471272,0.162107493274987857],"hpluv":[58.0014729567720551,148.738759066450825,78.6801087960333],"hsluv":[58.0014729567720551,81.0022494643358613,78.6801087960333]},"#eebb66":{"lch":[78.8558787138066748,71.0520814803831229,55.7790951769469174],"luv":[78.8558787138066748,39.9586324736418845,58.7512210386423703],"rgb":[0.933333333333333348,0.733333333333333282,0.4],"xyz":[0.55426672121538223,0.546787763503874591,0.202055137682131819],"hpluv":[55.7790951769469174,137.768430134850121,78.8558787138066748],"hsluv":[55.7790951769469174,72.7264864885570574,78.8558787138066748]},"#eebb77":{"lch":[79.0708286262536,63.6259938562226566,52.5733668905169],"luv":[79.0708286262536,38.6683825737350801,50.5274507898760348],"rgb":[0.933333333333333348,0.733333333333333282,0.466666666666666674],"xyz":[0.56358073423558408,0.550513368711955442,0.251108939588529756],"hpluv":[52.5733668905169,124.876553308513152,79.0708286262536],"hsluv":[52.5733668905169,64.3532422469102841,79.0708286262536]},"#eebb88":{"lch":[79.3266586201773833,55.4370708593257149,47.8613800964459557],"luv":[79.3266586201773833,37.1942049853437169,41.1079060640423961],"rgb":[0.933333333333333348,0.733333333333333282,0.533333333333333326],"xyz":[0.574721151337528,0.554969535552733,0.309781802992101896],"hpluv":[47.8613800964459557,110.403075040931697,79.3266586201773833],"hsluv":[47.8613800964459557,64.6428486235092379,79.3266586201773833]},"#eebb99":{"lch":[79.6247632766216071,46.9114913521919519,40.7190885070752131],"luv":[79.6247632766216071,35.5550187983100727,30.6027557441907163],"rgb":[0.933333333333333348,0.733333333333333282,0.6],"xyz":[0.587778115446600635,0.560192321196362197,0.378548480633219775],"hpluv":[40.7190885070752131,95.0436922052712845,79.6247632766216071],"hsluv":[40.7190885070752131,64.94797236425741,79.6247632766216071]},"#eebbaa":{"lch":[79.9662551563314,38.821829319770238,29.5464132636418633],"luv":[79.9662551563314,33.7733033676501,19.1441482278540249],"rgb":[0.933333333333333348,0.733333333333333282,0.66666666666666663],"xyz":[0.602835808411853247,0.566215398382463264,0.457852330250218431],"hpluv":[29.5464132636418633,80.2381481795300573,79.9662551563314],"hsluv":[29.5464132636418633,65.2570717669902081,79.9662551563314]},"#eebbbb":{"lch":[80.3519829843595,32.6073830473385868,12.1770506300627979],"luv":[80.3519829843595,31.8737319395561,6.87798236703069765],"rgb":[0.933333333333333348,0.733333333333333282,0.733333333333333282],"xyz":[0.61997340051918981,0.573070435225398,0.548110315348860122],"hpluv":[12.1770506300627979,68.9527679352530498,80.3519829843595],"hsluv":[12.1770506300627979,65.5572779496269646,80.3519829843595]},"#eebbcc":{"lch":[80.7825470949933,30.4869713003172755,348.56539147946927],"luv":[80.7825470949933,29.8818538307637169,-6.04402437976891349],"rgb":[0.933333333333333348,0.733333333333333282,0.8],"xyz":[0.639265775962911564,0.58078738540288688,0.649716826019130278],"hpluv":[348.56539147946927,66.1649916626687542,80.7825470949933],"hsluv":[348.56539147946927,65.8346704867411,80.7825470949933]},"#eebbdd":{"lch":[81.2583136554081165,33.9595526191752555,325.014354592586812],"luv":[81.2583136554081165,27.8229160969035512,-19.4714291709468021],"rgb":[0.933333333333333348,0.733333333333333282,0.866666666666666696],"xyz":[0.660784101513545163,0.589394715623140386,0.763046673919136276],"hpluv":[325.014354592586812,75.8902298772919721,81.2583136554081165],"hsluv":[325.014354592586812,66.0744631525984119,81.2583136554081165]},"#eebbee":{"lch":[81.7794285687783429,42.0458499431423576,307.715012949247921],"luv":[81.7794285687783429,25.7208902583653902,-33.2609275540891716],"rgb":[0.933333333333333348,0.733333333333333282,0.933333333333333348],"xyz":[0.684596281779719873,0.598919587729610403,0.888457489987659499],"hpluv":[307.715012949247921,97.0917602325266245,81.7794285687783429],"hsluv":[307.715012949247921,66.2610602343042103,81.7794285687783429]},"#eebbff":{"lch":[82.3458315671937697,52.842459086223478,296.523687653639684],"luv":[82.3458315671937697,23.5977388768935938,-47.2807804734349446],"rgb":[0.933333333333333348,0.733333333333333282,1],"xyz":[0.710767330189551294,0.609388007093543127,1.02629167827944134],"hpluv":[296.523687653639684,126.563624284615543,82.3458315671937697],"hsluv":[296.523687653639684,99.9999999999958504,82.3458315671937697]},"#774400":{"lch":[34.1007355557283631,52.2824067620925845,38.9690248280103901],"luv":[34.1007355557283631,40.6488429776156863,32.8804139483986475],"rgb":[0.466666666666666674,0.266666666666666663,0],"xyz":[0.0967461069942917862,0.0805672125740730105,0.0104561581988052085],"hpluv":[38.9690248280103901,194.549962435525771,34.1007355557283631],"hsluv":[38.9690248280103901,100.000000000002302,34.1007355557283631]},"#774411":{"lch":[34.1844760931178726,49.9480603042207,37.0032460066389604],"luv":[34.1844760931178726,39.8885915773263164,30.0617529450848728],"rgb":[0.466666666666666674,0.266666666666666663,0.0666666666666666657],"xyz":[0.0977577724939289,0.0809718787739278634,0.0157842631635608383],"hpluv":[37.0032460066389604,185.408237524396696,34.1844760931178726],"hsluv":[37.0032460066389604,92.0774266797174477,34.1844760931178726]},"#774422":{"lch":[34.3389737161705639,45.9687551907429608,33.0232295817012798],"luv":[34.3389737161705639,38.542488289151045,25.0520069109664867],"rgb":[0.466666666666666674,0.266666666666666663,0.133333333333333331],"xyz":[0.0996331306324059335,0.0817220220293186778,0.0256611493595400378],"hpluv":[33.0232295817012798,169.869245826721482,34.3389737161705639],"hsluv":[33.0232295817012798,78.0803941927279794,34.3389737161705639]},"#774433":{"lch":[34.5913049894652787,40.4066166426811861,25.4401077009201266],"luv":[34.5913049894652787,36.4885814660887746,17.357364174931714],"rgb":[0.466666666666666674,0.266666666666666663,0.2],"xyz":[0.102720881364863667,0.0829571223223017906,0.041923303217151181],"hpluv":[25.4401077009201266,148.226163260119392,34.5913049894652787],"hsluv":[25.4401077009201266,56.8050953227402715,34.5913049894652787]},"#774444":{"lch":[34.9512320153617324,34.6101233100924119,12.1770506300620909],"luv":[34.9512320153617324,33.8314114683579277,7.30042694631360689],"rgb":[0.466666666666666674,0.266666666666666663,0.266666666666666663],"xyz":[0.107178876609082541,0.0847403204199893706,0.0654020781700378195],"hpluv":[12.1770506300620909,125.655060642768362,34.9512320153617324],"hsluv":[12.1770506300620909,29.4448754689639038,34.9512320153617324]},"#774455":{"lch":[35.4248138391838907,31.0799263948782318,351.580242092888511],"luv":[35.4248138391838907,30.7449438027498871,-4.55085214842230634],"rgb":[0.466666666666666674,0.266666666666666663,0.333333333333333315],"xyz":[0.11314129064844454,0.0871252860357342,0.0968041254440117349],"hpluv":[351.580242092888511,111.329877567225012,35.4248138391838907],"hsluv":[351.580242092888511,35.0525071981411855,35.4248138391838907]},"#774466":{"lch":[36.0149447056398699,32.55773059028094,327.386935336661793],"luv":[36.0149447056398699,27.4243377055297302,-17.5474078599198116],"rgb":[0.466666666666666674,0.266666666666666663,0.4],"xyz":[0.120726286421952711,0.090159284345137522,0.136751769851155697],"hpluv":[327.386935336661793,114.712488009680612,36.0149447056398699],"hsluv":[327.386935336661793,41.0162201785438469,36.0149447056398699]},"#774477":{"lch":[36.7217587051522898,39.3078830273429531,307.715012949244965],"luv":[36.7217587051522898,24.0459818745983789,-31.0950224919964064],"rgb":[0.466666666666666674,0.266666666666666663,0.466666666666666674],"xyz":[0.130040299442154617,0.0938848895532183314,0.185805571757553606],"hpluv":[307.715012949244965,135.82994003022975,36.7217587051522898],"hsluv":[307.715012949244965,46.9930223744603381,36.7217587051522898]},"#774488":{"lch":[37.5430301686231331,49.3077922843884906,294.880307130505798],"luv":[37.5430301686231331,20.7449732069104158,-44.731470651041306],"rgb":[0.466666666666666674,0.266666666666666663,0.533333333333333326],"xyz":[0.141180716544098472,0.0983410563939959292,0.244478435161125773],"hpluv":[294.880307130505798,166.657768282509579,37.5430301686231331],"hsluv":[294.880307130505798,52.7229750286883814,37.5430301686231331]},"#774499":{"lch":[38.4745988052595678,60.7540316024919775,286.849160899925266],"luv":[38.4745988052595678,17.609743748149274,-58.1459309073396042],"rgb":[0.466666666666666674,0.266666666666666663,0.6],"xyz":[0.154237680653171172,0.103563842037625087,0.313245112802243653],"hpluv":[286.849160899925266,200.373520820200838,38.4745988052595678],"hsluv":[286.849160899925266,58.0391908614757739,38.4745988052595678]},"#7744aa":{"lch":[39.5108096650206306,72.6607854160185695,281.662296555210446],"luv":[39.5108096650206306,14.6878600390207232,-71.1607792589909423],"rgb":[0.466666666666666674,0.266666666666666663,0.66666666666666663],"xyz":[0.169295373618423728,0.109586919223726181,0.392548962419242253],"hpluv":[281.662296555210446,233.358425064810547,39.5108096650206306],"hsluv":[281.662296555210446,62.855979622580108,39.5108096650206306]},"#7744bb":{"lch":[40.6449442050895,84.5532389367896684,278.156646558388104],"luv":[40.6449442050895,11.9964108827533504,-83.6978873128468],"rgb":[0.466666666666666674,0.266666666666666663,0.733333333333333282],"xyz":[0.186432965725760347,0.11644195606666094,0.482806947517884],"hpluv":[278.156646558388104,263.975148792079324,40.6449442050895],"hsluv":[278.156646558388104,67.1480450168623832,40.6449442050895]},"#7744cc":{"lch":[41.8696179576200223,96.2178725735773099,275.685728840067554],"luv":[41.8696179576200223,9.53248740063005151,-95.7445073439828747],"rgb":[0.466666666666666674,0.266666666666666663,0.8],"xyz":[0.205725341169482101,0.124158906244149742,0.584413458188154156],"hpluv":[275.685728840067554,291.605746800226,41.8696179576200223],"hsluv":[275.685728840067554,71.7563947172966721,41.8696179576200223]},"#7744dd":{"lch":[43.1771261833787037,107.572507589609089,273.881356516641858],"luv":[43.1771261833787037,7.28165300546471084,-107.325774717094461],"rgb":[0.466666666666666674,0.266666666666666663,0.866666666666666696],"xyz":[0.227243666720115645,0.132766236464403276,0.697743306088160153],"hpluv":[273.881356516641858,316.145413845169799,43.1771261833787037],"hsluv":[273.881356516641858,81.1040313116107683,43.1771261833787037]},"#7744ee":{"lch":[44.5597272061305958,118.600491111934247,272.524492751992966],"luv":[44.5597272061305958,5.22393127379498168,-118.485387428318177],"rgb":[0.466666666666666674,0.266666666666666663,0.933333333333333348],"xyz":[0.251055846986290354,0.14229110857087332,0.823154122156683377],"hpluv":[272.524492751992966,337.740615485066769,44.5597272061305958],"hsluv":[272.524492751992966,90.4775463334620866,44.5597272061305958]},"#7744ff":{"lch":[46.0098610845945188,129.316457315512423,271.478956563127554],"luv":[46.0098610845945188,3.33763127257498882,-129.273378350389976],"rgb":[0.466666666666666674,0.266666666666666663,1],"xyz":[0.277226895396121775,0.152759527934806016,0.960988310448465222],"hpluv":[271.478956563127554,356.649979093308843,46.0098610845945188],"hsluv":[271.478956563127554,99.9999999999992752,46.0098610845945188]},"#eecc00":{"lch":[82.5742071813858161,93.0890420253441278,70.6743105766144737],"luv":[82.5742071813858161,30.8066573410433797,87.8437226480516529],"rgb":[0.933333333333333348,0.8,0],"xyz":[0.568510285097338142,0.613643178352045071,0.088500773799653279],"hpluv":[70.6743105766144737,226.330948640265689,82.5742071813858161],"hsluv":[70.6743105766144737,100.000000000002331,82.5742071813858161]},"#eecc11":{"lch":[82.5958706312260773,92.1609271203023,70.5494354113464226],"luv":[82.5958706312260773,30.6889817522442812,86.9012248859824297],"rgb":[0.933333333333333348,0.8,0.0666666666666666657],"xyz":[0.569521950596975302,0.6140478445519,0.0938288787644089156],"hpluv":[70.5494354113464226,224.395635781555484,82.5958706312260773],"hsluv":[70.5494354113464226,98.9293851282895389,82.5958706312260773]},"#eecc22":{"lch":[82.636003730849751,90.4517890224530277,70.3125751850760849],"luv":[82.636003730849751,30.4721781878481224,85.1643851257694848],"rgb":[0.933333333333333348,0.8,0.133333333333333331],"xyz":[0.571397308735452247,0.61479798780729078,0.103705764960388108],"hpluv":[70.3125751850760849,220.820363432361461,82.636003730849751],"hsluv":[70.3125751850760849,96.9576791715233668,82.636003730849751]},"#eecc33":{"lch":[82.7020112487531,87.6695564091762236,69.9066450473675332],"luv":[82.7020112487531,30.1189443150749909,82.3334701948554084],"rgb":[0.933333333333333348,0.8,0.2],"xyz":[0.574485059467910064,0.616033088100273907,0.119967918817999258],"hpluv":[69.9066450473675332,214.968262161852493,82.7020112487531],"hsluv":[69.9066450473675332,93.7473974454290726,82.7020112487531]},"#eecc44":{"lch":[82.7971553193909102,83.7217279628800242,69.2828434677537786],"luv":[82.7971553193909102,29.6169744667019792,78.3081257375581],"rgb":[0.933333333333333348,0.8,0.266666666666666663],"xyz":[0.578943054712128924,0.617816286197961473,0.143446693770885897],"hpluv":[69.2828434677537786,206.594355258371763,82.7971553193909102],"hsluv":[69.2828434677537786,89.1900904304584685,82.7971553193909102]},"#eecc55":{"lch":[82.9241214704336471,78.5673404382155098,68.3706518767947387],"luv":[82.9241214704336471,28.9599810639926183,73.0352413585910085],"rgb":[0.933333333333333348,0.8,0.333333333333333315],"xyz":[0.584905468751490853,0.620201251813706222,0.174848741044859812],"hpluv":[68.3706518767947387,195.532369916851508,82.9241214704336471],"hsluv":[68.3706518767947387,83.2339277722755497,82.9241214704336471]},"#eecc66":{"lch":[83.0851700146488241,72.2150018940459688,67.0599726095305186],"luv":[83.0851700146488241,28.1470538355007811,66.503758231685552],"rgb":[0.933333333333333348,0.8,0.4],"xyz":[0.592490464524999094,0.623235250123109541,0.214796385452003746],"hpluv":[67.0599726095305186,181.688085793908328,83.0851700146488241],"hsluv":[67.0599726095305186,75.8779818086204898,83.0851700146488241]},"#eecc77":{"lch":[83.2822165713090925,64.7250307453925586,65.1677162202921778],"luv":[83.2822165713090925,27.1821511319325673,58.740618526133936],"rgb":[0.933333333333333348,0.8,0.466666666666666674],"xyz":[0.601804477545200944,0.626960855331190392,0.263850187358401655],"hpluv":[65.1677162202921778,165.044758034407693,83.2822165713090925],"hsluv":[65.1677162202921778,67.1675472191497533,83.2822165713090925]},"#eecc88":{"lch":[83.5168798492942699,56.2182636624862511,62.3679934299132839],"luv":[83.5168798492942699,26.0735255024375405,49.8062690541919793],"rgb":[0.933333333333333348,0.8,0.533333333333333326],"xyz":[0.612944894647144856,0.631417022171967934,0.322523050761973851],"hpluv":[62.3679934299132839,145.689263900370548,83.5168798492942699],"hsluv":[62.3679934299132839,57.1887031148042198,83.5168798492942699]},"#eecc99":{"lch":[83.79051243806407,46.9027423702446598,58.0311593919332083],"luv":[83.79051243806407,24.8330316313984234,39.7892923013655633],"rgb":[0.933333333333333348,0.8,0.6],"xyz":[0.6260018587562175,0.636639807815597147,0.39128972840309173],"hpluv":[58.0311593919332083,123.89218615802821,83.79051243806407],"hsluv":[58.0311593919332083,56.9799526918745158,83.79051243806407]},"#eeccaa":{"lch":[84.1042222244633,37.1556922719042646,50.8162292091241454],"luv":[84.1042222244633,23.475329457535171,28.8002495660129298],"rgb":[0.933333333333333348,0.8,0.66666666666666663],"xyz":[0.641059551721470111,0.642662885001698214,0.470593578020090331],"hpluv":[50.8162292091241454,100.353156070069275,84.1042222244633],"hsluv":[50.8162292091241454,57.1375361174420533,84.1042222244633]},"#eeccbb":{"lch":[84.4588885299527,27.7950211383377486,37.6158086991229084],"luv":[84.4588885299527,22.0170273242058485,16.9650731765535063],"rgb":[0.933333333333333348,0.8,0.733333333333333282],"xyz":[0.658197143828806674,0.649517921844633,0.560851563118732077],"hpluv":[37.6158086991229084,77.0182985337263517,84.4588885299527],"hsluv":[37.6158086991229084,57.2612530554736736,84.4588885299527]},"#eecccc":{"lch":[84.8551753311588897,20.9471233587290264,12.1770506300631585],"luv":[84.8551753311588897,20.4758227261490333,4.41844550641173317],"rgb":[0.933333333333333348,0.8,0.8],"xyz":[0.677489519272528429,0.65723487202212183,0.662458073789002233],"hpluv":[12.1770506300631585,59.764130158742411,84.8551753311588897],"hsluv":[12.1770506300631585,57.3329985994000637,84.8551753311588897]},"#eeccdd":{"lch":[85.2935429882433596,20.7797326136980232,335.241604291037675],"luv":[85.2935429882433596,18.8696973425293919,-8.70240252448279],"rgb":[0.933333333333333348,0.8,0.866666666666666696],"xyz":[0.699007844823162,0.665842202242375336,0.775787921689008231],"hpluv":[335.241604291037675,61.2821093808529582,85.2935429882433596],"hsluv":[335.241604291037675,57.3323512744098664,85.2935429882433596]},"#eeccee":{"lch":[85.7742593547863805,28.14328338963319,307.715012949251047],"luv":[85.7742593547863805,17.2162128855465397,-22.2631177921859056],"rgb":[0.933333333333333348,0.8,0.933333333333333348],"xyz":[0.722820025089336737,0.675367074348845353,0.901198737757531454],"hpluv":[307.715012949251047,86.153290074940827,85.7742593547863805],"hsluv":[307.715012949251047,57.2362127773837557,85.7742593547863805]},"#eeccff":{"lch":[86.2974107975625344,39.333162863939684,293.258584701896098],"luv":[86.2974107975625344,15.5319389668875889,-36.1366375415599919],"rgb":[0.933333333333333348,0.8,1],"xyz":[0.748991073499168158,0.685835493712778077,1.03903292604931341],"hpluv":[293.258584701896098,125.558261528980708,86.2974107975625344],"hsluv":[293.258584701896098,99.9999999999940314,86.2974107975625344]},"#775500":{"lch":[38.5848153490983421,48.2339285723334328,54.8056311564330656],"luv":[38.5848153490983421,27.7997213245256276,39.4168410682499868],"rgb":[0.466666666666666674,0.333333333333333315,0],"xyz":[0.108559363708637752,0.104193726002765275,0.0143939104369204193],"hpluv":[54.8056311564330656,158.626424871442595,38.5848153490983421],"hsluv":[54.8056311564330656,100.000000000002302,38.5848153490983421]},"#775511":{"lch":[38.6553893217116595,45.9150245993572952,53.4685955296553956],"luv":[38.6553893217116595,27.3315290852913257,36.8941323494598521],"rgb":[0.466666666666666674,0.333333333333333315,0.0666666666666666657],"xyz":[0.10957102920827487,0.104598392202620127,0.0197220154016760491],"hpluv":[53.4685955296553956,150.724584795248319,38.6553893217116595],"hsluv":[53.4685955296553956,93.8009130268131344,38.6553893217116595]},"#775522":{"lch":[38.7857346943923531,41.8305053308362176,50.7011784026830412],"luv":[38.7857346943923531,26.4939762066725,32.3706719268134577],"rgb":[0.466666666666666674,0.333333333333333315,0.133333333333333331],"xyz":[0.111446387346751899,0.105348535458010942,0.0295989015976552486],"hpluv":[50.7011784026830412,136.854920013655288,38.7857346943923531],"hsluv":[50.7011784026830412,82.7342982429400138,38.7857346943923531]},"#775533":{"lch":[38.9990050188249739,35.7224202133018096,45.1472123185964946],"luv":[38.9990050188249739,25.1945818654867857,25.3243825298663161],"rgb":[0.466666666666666674,0.333333333333333315,0.2],"xyz":[0.114534138079209633,0.106583635750994055,0.0458610554552663918],"hpluv":[45.1472123185964946,116.232257903435652,38.9990050188249739],"hsluv":[45.1472123185964946,65.6272728324870656,38.9990050188249739]},"#775544":{"lch":[39.3040305977305735,28.372964966311546,34.1730058033032336],"luv":[39.3040305977305735,23.4742392428959334,15.9369141601135258],"rgb":[0.466666666666666674,0.333333333333333315,0.266666666666666663],"xyz":[0.118992133323428506,0.108366833848681635,0.0693398304081530303],"hpluv":[34.1730058033032336,91.6024225041024,39.3040305977305735],"hsluv":[34.1730058033032336,43.1049791856067799,39.3040305977305735]},"#775555":{"lch":[39.7068052905653701,21.9117916496410494,12.1770506300624941],"luv":[39.7068052905653701,21.4187864245998618,4.62192615633957704],"rgb":[0.466666666666666674,0.333333333333333315,0.333333333333333315],"xyz":[0.124954547362790505,0.110751799464426468,0.100741877682126946],"hpluv":[12.1770506300624941,70.0248633547080601,39.7068052905653701],"hsluv":[12.1770506300624941,16.4089959502104463,39.7068052905653701]},"#775566":{"lch":[40.21091767922141,20.7753835118276839,337.09176723456028],"luv":[40.21091767922141,19.1368182791551824,-8.08694912894311],"rgb":[0.466666666666666674,0.333333333333333315,0.4],"xyz":[0.132539543136298676,0.113785797773829786,0.140689522089270908],"hpluv":[337.09176723456028,65.5608222190156482,40.21091767922141],"hsluv":[337.09176723456028,22.8015335286909036,40.21091767922141]},"#775577":{"lch":[40.8178321801082404,27.3616881241227183,307.715012949246557],"luv":[40.8178321801082404,16.7380842217685313,-21.6448264854847388],"rgb":[0.466666666666666674,0.333333333333333315,0.466666666666666674],"xyz":[0.141853556156500582,0.117511402981910595,0.189743323995668817],"hpluv":[307.715012949246557,85.0613515767839,40.8178321801082404],"hsluv":[307.715012949246557,29.4286369924042717,40.8178321801082404]},"#775588":{"lch":[41.5271394874135922,38.3484586217177892,291.922773984013077],"luv":[41.5271394874135922,14.317648223710199,-35.5754020076188269],"rgb":[0.466666666666666674,0.333333333333333315,0.533333333333333326],"xyz":[0.152993973258444438,0.121967569822688193,0.248416187399240984],"hpluv":[291.922773984013077,117.180466459805771,41.5271394874135922],"hsluv":[291.922773984013077,36.0000576829853429,41.5271394874135922]},"#775599":{"lch":[42.336815252734,50.9328741768069335,283.566916489070877],"luv":[42.336815252734,11.9478768110398388,-49.5116744982298442],"rgb":[0.466666666666666674,0.333333333333333315,0.6],"xyz":[0.166050937367517137,0.127190355466317351,0.317182865040358863],"hpluv":[283.566916489070877,152.657914615048412,42.336815252734],"hsluv":[283.566916489070877,42.2975255710275704,42.336815252734]},"#7755aa":{"lch":[43.2434937800222059,63.9392804809027098,278.705184193400783],"luv":[43.2434937800222059,9.67722671121172517,-63.202712533524668],"rgb":[0.466666666666666674,0.333333333333333315,0.66666666666666663],"xyz":[0.181108630332769693,0.133213432652418445,0.396486714657357464],"hpluv":[278.705184193400783,187.623095354238075,43.2434937800222059],"hsluv":[278.705184193400783,48.1780536314011272,43.2434937800222059]},"#7755bb":{"lch":[44.2427493107278096,76.8690732738289171,275.624120681329657],"luv":[44.2427493107278096,7.53331271169703509,-76.4990432983646116],"rgb":[0.466666666666666674,0.333333333333333315,0.733333333333333282],"xyz":[0.198246222440106312,0.140068469495353204,0.486744699755999211],"hpluv":[275.624120681329657,220.469676556121556,44.2427493107278096],"hsluv":[275.624120681329657,58.1137757976744496,44.2427493107278096]},"#7755cc":{"lch":[45.3293721892173949,89.4999308488430785,273.541003165926895],"luv":[45.3293721892173949,5.52776894932058127,-89.3290624175056536],"rgb":[0.466666666666666674,0.333333333333333315,0.8],"xyz":[0.217538597883828067,0.147785419672842,0.588351210426269366],"hpluv":[273.541003165926895,250.543028147628775,45.3293721892173949],"hsluv":[273.541003165926895,68.560007412736141,45.3293721892173949]},"#7755dd":{"lch":[46.4976270234735622,101.740884988783861,272.062259876532949],"luv":[46.4976270234735622,3.66119191329505167,-101.674988822595736],"rgb":[0.466666666666666674,0.333333333333333315,0.866666666666666696],"xyz":[0.23905692343446161,0.15639274989309554,0.701681058326275364],"hpluv":[272.062259876532949,277.654072578046794,46.4976270234735622],"hsluv":[272.062259876532949,78.9623412233913911,46.4976270234735622]},"#7755ee":{"lch":[47.7414825998049253,113.569026574645434,270.972372145675877],"luv":[47.7414825998049253,1.92729827623402139,-113.552672000560818],"rgb":[0.466666666666666674,0.333333333333333315,0.933333333333333348],"xyz":[0.26286910370063632,0.165917621999565584,0.827091874394798587],"hpluv":[270.972372145675877,301.858443342198598,47.7414825998049253],"hsluv":[270.972372145675877,89.4067229175139175,47.7414825998049253]},"#7755ff":{"lch":[49.0548071408334749,124.996939079083958,270.144864217432826],"luv":[49.0548071408334749,0.31603661949764611,-124.996539552082652],"rgb":[0.466666666666666674,0.333333333333333315,1],"xyz":[0.289040152110467741,0.17638604136349828,0.964926062686580432],"hpluv":[270.144864217432826,323.338286172745597,49.0548071408334749],"hsluv":[270.144864217432826,99.9999999999992184,49.0548071408334749]},"#eedd00":{"lch":[86.9434330779808562,96.0018853881048528,78.7633058197047831],"luv":[86.9434330779808562,18.7071720605167293,94.1615829920517],"rgb":[0.933333333333333348,0.866666666666666696,0],"xyz":[0.611144275644513346,0.69891115944639659,0.102712103982044597],"hpluv":[78.7633058197047831,323.365375109368927,86.9434330779808562],"hsluv":[78.7633058197047831,100.000000000002331,86.9434330779808562]},"#eedd11":{"lch":[86.9632971622836,95.1251800329902153,78.7103442402005555],"luv":[86.9632971622836,18.6225708681111755,93.2845095960255293],"rgb":[0.933333333333333348,0.866666666666666696,0.0666666666666666657],"xyz":[0.612155941144150506,0.699315825646251499,0.108040208946800234],"hpluv":[78.7103442402005555,320.953864246165836,86.9632971622836],"hsluv":[78.7103442402005555,99.0572185708442134,86.9632971622836]},"#eedd22":{"lch":[87.0000996195567,93.508678235103929,78.6100630695382421],"luv":[87.0000996195567,18.466577094457584,91.6671066178629559],"rgb":[0.933333333333333348,0.866666666666666696,0.133333333333333331],"xyz":[0.614031299282627452,0.700065968901642299,0.117917095142779427],"hpluv":[78.6100630695382421,316.490280961531141,87.0000996195567],"hsluv":[78.6100630695382421,97.3195837272491104,87.0000996195567]},"#eedd33":{"lch":[87.0606371109171704,90.8714304533391157,78.438725785200063],"luv":[87.0606371109171704,18.2120693177914781,89.0277339024194561],"rgb":[0.933333333333333348,0.866666666666666696,0.2],"xyz":[0.617119050015085269,0.701301069194625426,0.134179249000390577],"hpluv":[78.438725785200063,309.159510866930361,87.0606371109171704],"hsluv":[78.438725785200063,94.4866487647953335,87.0606371109171704]},"#eedd44":{"lch":[87.1479139339873399,87.1163282896156375,78.1766823729436737],"luv":[87.1479139339873399,17.8496481580416315,85.2680755927926839],"rgb":[0.933333333333333348,0.866666666666666696,0.266666666666666663],"xyz":[0.621577045259304128,0.703084267292313,0.157658023953277215],"hpluv":[78.1766823729436737,298.614243514229941,87.1479139339873399],"hsluv":[78.1766823729436737,90.4569971269957449,87.1479139339873399]},"#eedd55":{"lch":[87.2644132886328,82.1887294441124823,77.7961103956051119],"luv":[87.2644132886328,17.3739699699556027,80.3313912186301],"rgb":[0.933333333333333348,0.866666666666666696,0.333333333333333315],"xyz":[0.627539459298666058,0.705469232908057742,0.189060071227251103],"hpluv":[77.7961103956051119,284.577035202400168,87.2644132886328],"hsluv":[77.7961103956051119,85.1762064326895114,87.2644132886328]},"#eedd66":{"lch":[87.4122373516825775,76.0722975624531,77.2543738936701],"luv":[87.4122373516825775,16.7832968217641607,74.1978126646801428],"rgb":[0.933333333333333348,0.866666666666666696,0.4],"xyz":[0.635124455072174299,0.70850323121746106,0.229007715634395093],"hpluv":[77.2543738936701,266.820521177772889,87.4122373516825775],"hsluv":[77.2543738936701,78.6319742502837187,87.4122373516825775]},"#eedd77":{"lch":[87.5931821049200323,68.7867162946957,76.4818073814204666],"luv":[87.5931821049200323,16.0791769624109904,66.8810317415814524],"rgb":[0.933333333333333348,0.866666666666666696,0.466666666666666674],"xyz":[0.644438468092376149,0.712228836425541911,0.278061517540793],"hpluv":[76.4818073814204666,245.153905791490757,87.5931821049200323],"hsluv":[76.4818073814204666,70.850552214552053,87.5931821049200323]},"#eedd88":{"lch":[87.8087818591101694,60.3863988515096,75.3563176494847],"luv":[87.8087818591101694,15.266108392374667,58.4248500280990655],"rgb":[0.933333333333333348,0.866666666666666696,0.533333333333333326],"xyz":[0.65557888519432006,0.716685003266319454,0.336734380944365141],"hpluv":[75.3563176494847,219.413652035392374,87.8087818591101694],"hsluv":[75.3563176494847,61.8928475378351,87.8087818591101694]},"#eedd99":{"lch":[88.0603378936253165,50.9615259485641658,73.6438422487017164],"luv":[88.0603378936253165,14.3511385044238935,48.8990996914362483],"rgb":[0.933333333333333348,0.866666666666666696,0.6],"xyz":[0.668635849303392704,0.721907788909948667,0.405501058585483076],"hpluv":[73.6438422487017164,189.463858183723431,88.0603378936253165],"hsluv":[73.6438422487017164,51.8496821371243328,88.0603378936253165]},"#eeddaa":{"lch":[88.3489381850503719,40.6474355343677374,70.8361013393810595],"luv":[88.3489381850503719,13.3433963411670824,38.3948927541556],"rgb":[0.933333333333333348,0.866666666666666696,0.66666666666666663],"xyz":[0.683693542268645316,0.727930866096049733,0.484804908202481677],"hpluv":[70.8361013393810595,155.230940371192503,88.3489381850503719],"hsluv":[70.8361013393810595,42.897511243529749,88.3489381850503719]},"#eeddbb":{"lch":[88.6754719765582422,29.6681200622416164,65.6052069824857256],"luv":[88.6754719765582422,12.2535763784239329,27.0193858917206811],"rgb":[0.933333333333333348,0.866666666666666696,0.733333333333333282],"xyz":[0.700831134375981879,0.734785902938984492,0.575062893301123368],"hpluv":[65.6052069824857256,116.881954111652547,88.6754719765582422],"hsluv":[65.6052069824857256,42.5880034653653823,88.6754719765582422]},"#eeddcc":{"lch":[89.0406413623298,18.5684245799280596,53.3136761054906927],"luv":[89.0406413623298,11.093403559257359,14.8903589228712931],"rgb":[0.933333333333333348,0.866666666666666696,0.8],"xyz":[0.720123509819703633,0.742502853116473349,0.676669403971393524],"hpluv":[53.3136761054906927,75.8171941810365837,89.0406413623298],"hsluv":[53.3136761054906927,42.1389745374101,89.0406413623298]},"#eedddd":{"lch":[89.4449712115231677,10.1024117660870978,12.1770506300652031],"luv":[89.4449712115231677,9.87511215198720294,2.13093488339032255],"rgb":[0.933333333333333348,0.866666666666666696,0.866666666666666696],"xyz":[0.741641835370337232,0.751110183336726855,0.789999251871399522],"hpluv":[12.1770506300652031,42.9711785560074802,89.4449712115231677],"hsluv":[12.1770506300652031,41.5103310668104939,89.4449712115231677]},"#eeddee":{"lch":[89.8888182614484919,14.0763196099440542,307.715012949260654],"luv":[89.8888182614484919,8.61096808409750203,-11.1352594229299271],"rgb":[0.933333333333333348,0.866666666666666696,0.933333333333333348],"xyz":[0.765454015636511942,0.760635055443196872,0.915410067939922745],"hpluv":[307.715012949260654,62.7286135322124423,89.8888182614484919],"hsluv":[307.715012949260654,40.6526002298302203,89.8888182614484919]},"#eeddff":{"lch":[90.3723799019863776,25.8444533047225526,286.436741223308786],"luv":[90.3723799019863776,7.31285770395748802,-24.7882609075678033],"rgb":[0.933333333333333348,0.866666666666666696,1],"xyz":[0.791625064046343363,0.771103474807129596,1.05324425623170459],"hpluv":[286.436741223308786,121.429851146909542,90.3723799019863776],"hsluv":[286.436741223308786,99.9999999999912461,90.3723799019863776]},"#776600":{"lch":[43.3967364031710616,48.7618731822316747,71.5665709091534836],"luv":[43.3967364031710616,15.4186312136361749,46.2599836547520695],"rgb":[0.466666666666666674,0.4,0],"xyz":[0.123587421414484214,0.134249841414458615,0.0194032630055357667],"hpluv":[71.5665709091534836,142.581321953300886,43.3967364031710616],"hsluv":[71.5665709091534836,100.000000000002203,43.3967364031710616]},"#776611":{"lch":[43.4563559440565683,46.5521225716425278,71.0105555334865812],"luv":[43.4563559440565683,15.1477793781447385,44.0186880294754204],"rgb":[0.466666666666666674,0.4,0.0666666666666666657],"xyz":[0.124599086914121332,0.134654507614313468,0.0247313679702914],"hpluv":[71.0105555334865812,135.933189968578517,43.4563559440565683],"hsluv":[71.0105555334865812,95.1446041192036,43.4563559440565683]},"#776622":{"lch":[43.5665595032511135,42.5748985848782695,69.8598868578742582],"luv":[43.5665595032511135,14.6592646006394602,39.9715892964128727],"rgb":[0.466666666666666674,0.4,0.133333333333333331],"xyz":[0.126474445052598361,0.135404650869704296,0.0346082541662705925],"hpluv":[69.8598868578742582,124.005139157578384,43.5665595032511135],"hsluv":[69.8598868578742582,86.4059851293991699,43.5665595032511135]},"#776633":{"lch":[43.7471247164395862,36.3538810550032,67.535659471968259],"luv":[43.7471247164395862,13.8911218179866047,33.5952586297408544],"rgb":[0.466666666666666674,0.4,0.2],"xyz":[0.129562195785056095,0.136639751162687395,0.0508704080238817358],"hpluv":[67.535659471968259,105.448545621014873,43.7471247164395862],"hsluv":[67.535659471968259,72.7162107178341,43.7471247164395862]},"#776644":{"lch":[44.0059094002531381,28.0798421405657628,62.7556004259007807],"luv":[44.0059094002531381,12.8545871201011757,24.9647175952547435],"rgb":[0.466666666666666674,0.4,0.266666666666666663],"xyz":[0.134020191029274982,0.138422949260375,0.0743491829767683743],"hpluv":[62.7556004259007807,80.969785387169,44.0059094002531381],"hsluv":[62.7556004259007807,54.3487361937933,44.0059094002531381]},"#776655":{"lch":[44.348573895236818,18.4503377813959695,51.0995937541716287],"luv":[44.348573895236818,11.5862323365157813,14.3587668165439446],"rgb":[0.466666666666666674,0.4,0.333333333333333315],"xyz":[0.139982605068636967,0.140807914876119822,0.10575123025074229],"hpluv":[51.0995937541716287,52.7914984191523473,44.348573895236818],"hsluv":[51.0995937541716287,32.0544530960382303,44.348573895236818]},"#776666":{"lch":[44.7789425039584543,10.3722772339139464,12.177050630063178],"luv":[44.7789425039584543,10.1389057710203723,2.18785849257654696],"rgb":[0.466666666666666674,0.4,0.4],"xyz":[0.147567600842145152,0.143841913185523113,0.145698874657886251],"hpluv":[12.177050630063178,29.3927086392471182,44.7789425039584543],"hsluv":[12.177050630063178,6.88762268030489189,44.7789425039584543]},"#776677":{"lch":[45.2992151274866899,14.0123007519981453,307.715012949251729],"luv":[45.2992151274866899,8.57180555029232849,-11.0846164558105222],"rgb":[0.466666666666666674,0.4,0.466666666666666674],"xyz":[0.156881613862347058,0.147567518393603936,0.194752676564284161],"hpluv":[307.715012949251729,39.2516664249610088,45.2992151274866899],"hsluv":[307.715012949251729,13.5798811229143528,45.2992151274866899]},"#776688":{"lch":[45.9101336093725934,25.9566305949561666,285.511882327844],"luv":[45.9101336093725934,6.94179491604529719,-25.0111606125461954],"rgb":[0.466666666666666674,0.4,0.533333333333333326],"xyz":[0.168022030964290886,0.152023685234381534,0.253425539967856328],"hpluv":[285.511882327844,71.7429261821633304,45.9101336093725934],"hsluv":[285.511882327844,20.4210179876919788,45.9101336093725934]},"#776699":{"lch":[46.6111419677041781,39.5636276789354753,277.694853057332239],"luv":[46.6111419677041781,5.29745753469698322,-39.2073663842078446],"rgb":[0.466666666666666674,0.4,0.6],"xyz":[0.181078995073363613,0.157246470878010691,0.322192217608974207],"hpluv":[277.694853057332239,107.707436484347127,46.6111419677041781],"hsluv":[277.694853057332239,30.3115853005661187,46.6111419677041781]},"#7766aa":{"lch":[47.4005539940279945,53.5010996637438936,273.94010537559177],"luv":[47.4005539940279945,3.67625443841083355,-53.3746458398921959],"rgb":[0.466666666666666674,0.4,0.66666666666666663],"xyz":[0.196136688038616142,0.163269548064111786,0.401496067225972808],"hpluv":[273.94010537559177,143.224929654224553,47.4005539940279945],"hsluv":[273.94010537559177,41.7476492103462178,47.4005539940279945]},"#7766bb":{"lch":[48.2757296522395052,67.3356727079262356,271.790784098674919],"luv":[48.2757296522395052,2.10423911354751,-67.3027859511178],"rgb":[0.466666666666666674,0.4,0.733333333333333282],"xyz":[0.213274280145952788,0.170124584907046544,0.491754052324614555],"hpluv":[271.790784098674919,176.992833999799871,48.2757296522395052],"hsluv":[271.790784098674919,53.26174830093764,48.2757296522395052]},"#7766cc":{"lch":[49.2332558923506838,80.8618894300095263,270.423298283194697],"luv":[49.2332558923506838,0.597398061184884921,-80.8596826468393886],"rgb":[0.466666666666666674,0.4,0.8],"xyz":[0.232566655589674542,0.177841535084535346,0.59336056299488471],"hpluv":[270.423298283194697,208.412927467485218,49.2332558923506838],"hsluv":[270.423298283194697,64.812294986267446,49.2332558923506838]},"#7766dd":{"lch":[50.2691251722936698,93.9789905273776327,269.490145829531343],"luv":[50.2691251722936698,-0.836273601566472236,-93.9752696564806769],"rgb":[0.466666666666666674,0.4,0.866666666666666696],"xyz":[0.254084981140308086,0.18644886530478888,0.706690410894890708],"hpluv":[269.490145829531343,237.229544488008315,50.2691251722936698],"hsluv":[269.490145829531343,76.411365903071939,50.2691251722936698]},"#7766ee":{"lch":[51.378904811117593,106.647241299318011,268.82087794331261],"luv":[51.378904811117593,-2.19459861633770803,-106.624658562961542],"rgb":[0.466666666666666674,0.4,0.933333333333333348],"xyz":[0.277897161406482796,0.195973737411258925,0.832101226963413931],"hpluv":[268.82087794331261,263.392927722023558,51.378904811117593],"hsluv":[268.82087794331261,88.1124589032604177,51.378904811117593]},"#7766ff":{"lch":[52.5578914047646748,118.864223743766644,268.322642340607558],"luv":[52.5578914047646748,-3.47930230784918848,-118.81329109850806],"rgb":[0.466666666666666674,0.4,1],"xyz":[0.304068209816314217,0.206442156775191621,0.969935415255195776],"hpluv":[268.322642340607558,286.980608281330717,52.5578914047646748],"hsluv":[268.322642340607558,99.9999999999990621,52.5578914047646748]},"#eeee00":{"lch":[91.3819857871042416,100.73955854358779,85.8743202181747591],"luv":[91.3819857871042416,7.24765584469138,100.478505862268193],"rgb":[0.933333333333333348,0.933333333333333348,0],"xyz":[0.658323051985028163,0.793268712127427555,0.118438362762215782],"hpluv":[85.8743202181747591,533.074105620447313,91.3819857871042416],"hsluv":[85.8743202181747591,100.000000000002302,91.3819857871042416]},"#eeee11":{"lch":[91.4002420948697,99.9206079899190485,85.8743202181747449],"luv":[91.4002420948697,7.18873686735402107,99.6616775060856526],"rgb":[0.933333333333333348,0.933333333333333348,0.0666666666666666657],"xyz":[0.659334717484665322,0.793673378327282464,0.123766467726971419],"hpluv":[85.8743202181747449,529.940172906192515,91.4002420948697],"hsluv":[85.8743202181747449,99.1672499526241182,91.4002420948697]},"#eeee22":{"lch":[91.4340680155716,98.4094794247264559,85.8743202181747],"luv":[91.4340680155716,7.08001949817026599,98.1544648222952105],"rgb":[0.933333333333333348,0.933333333333333348,0.133333333333333331],"xyz":[0.661210075623142268,0.794423521582673264,0.133643353922950597],"hpluv":[85.8743202181747,524.128135432551403,91.4340680155716],"hsluv":[85.8743202181747,97.631382664670781,91.4340680155716]},"#eeee33":{"lch":[91.4897155548310224,95.9410009888260475,85.874320218174617],"luv":[91.4897155548310224,6.90242608380469225,95.6923831080380864],"rgb":[0.933333333333333348,0.933333333333333348,0.2],"xyz":[0.664297826355600085,0.795658621875656391,0.149905507780561748],"hpluv":[85.874320218174617,514.550466890897383,91.4897155548310224],"hsluv":[85.874320218174617,95.1245282264191,91.4897155548310224]},"#eeee44":{"lch":[91.569956182858661,92.4193611961338917,85.8743202181745],"luv":[91.569956182858661,6.64906351605686385,92.1798691594911],"rgb":[0.933333333333333348,0.933333333333333348,0.266666666666666663],"xyz":[0.668755821599819,0.797441819973344,0.173384282733448386],"hpluv":[85.8743202181745,500.701064757674544,91.569956182858661],"hsluv":[85.8743202181745,91.5525623856835438,91.569956182858661]},"#eeee55":{"lch":[91.6770884747666912,87.7855710128071536,85.8743202181743612],"luv":[91.6770884747666912,6.31568785915728625,87.5580868047623682],"rgb":[0.933333333333333348,0.933333333333333348,0.333333333333333315],"xyz":[0.674718235639180874,0.799826785589088707,0.204786330007422301],"hpluv":[85.8743202181743612,482.129233036801622,91.6770884747666912],"hsluv":[85.8743202181743612,86.8606098102410584,91.6770884747666912]},"#eeee66":{"lch":[91.8130678710263197,82.0131153940214261,85.8743202181741481],"luv":[91.8130678710263197,5.90039150181238092,81.8005897091115912],"rgb":[0.933333333333333348,0.933333333333333348,0.4],"xyz":[0.682303231412689115,0.802860783898492,0.244733974414566263],"hpluv":[85.8743202181741481,458.402522986492727,91.8130678710263197],"hsluv":[85.8743202181741481,81.0287908474737435,91.8130678710263197]},"#eeee77":{"lch":[91.9795762822891163,75.1051560234190703,85.8743202181738923],"luv":[91.9795762822891163,5.40340190972927914,74.9105313631138],"rgb":[0.933333333333333348,0.933333333333333348,0.466666666666666674],"xyz":[0.691617244432891,0.806586389106572876,0.2937877763209642],"hpluv":[85.8743202181738923,429.072804464814112,91.9795762822891163],"hsluv":[85.8743202181738923,74.0694118243717838,91.9795762822891163]},"#eeee88":{"lch":[92.1780636375363542,67.0918310376028444,85.8743202181734233],"luv":[92.1780636375363542,4.82688735568056,66.9179718045445497],"rgb":[0.933333333333333348,0.933333333333333348,0.533333333333333326],"xyz":[0.702757661534834877,0.811042555947350419,0.35246063972453634],"hpluv":[85.8743202181734233,393.637417052406249,92.1780636375363542],"hsluv":[85.8743202181734233,66.0241185279663085,92.1780636375363542]},"#eeee99":{"lch":[92.4097746137617264,58.0271343519240759,85.8743202181728549],"luv":[92.4097746137617264,4.17473240419888647,57.8767650309654],"rgb":[0.933333333333333348,0.933333333333333348,0.6],"xyz":[0.715814625643907521,0.816265341590979632,0.421227317365654219],"hpluv":[85.8743202181728549,351.489405737917593,92.4097746137617264],"hsluv":[85.8743202181728549,56.9604957584853295,92.4097746137617264]},"#eeeeaa":{"lch":[92.6757669457712,47.9852530272659195,85.8743202181718885],"luv":[92.6757669457712,3.45227440531043239,47.8609058577161903],"rgb":[0.933333333333333348,0.933333333333333348,0.66666666666666663],"xyz":[0.730872318609160132,0.822288418777080699,0.500531166982652875],"hpluv":[85.8743202181718885,301.850049763156903,92.6757669457712],"hsluv":[85.8743202181718885,46.9680087594427178,92.6757669457712]},"#eeeebb":{"lch":[92.9769247593952741,37.0564456712956627,85.8743202181703253],"luv":[92.9769247593952741,2.66600696822725,36.9604189997225347],"rgb":[0.933333333333333348,0.933333333333333348,0.733333333333333282],"xyz":[0.748009910716496695,0.829143455620015457,0.590789152081294566],"hpluv":[85.8743202181703253,243.673832720465015,92.9769247593952741],"hsluv":[85.8743202181703253,36.1533987495139,92.9769247593952741]},"#eeeecc":{"lch":[93.3139689281547788,25.3426537884513579,85.8743202181670711],"luv":[93.3139689281547788,1.82326422217474082,25.2769817940640493],"rgb":[0.933333333333333348,0.933333333333333348,0.8],"xyz":[0.76730228616021845,0.836860405797504314,0.692395662751564722],"hpluv":[85.8743202181670711,175.509740066336235,93.3139689281547788],"hsluv":[85.8743202181670711,24.635760697738192,93.3139689281547788]},"#eeeedd":{"lch":[93.6874656794852143,12.9530841337210045,85.8743202181571377],"luv":[93.6874656794852143,0.931902991100789779,12.919518001474831],"rgb":[0.933333333333333348,0.933333333333333348,0.866666666666666696],"xyz":[0.788820611710852,0.84546773601775782,0.80572551065157072],"hpluv":[85.8743202181571377,95.2907564198152812,93.6874656794852143],"hsluv":[85.8743202181571377,12.5415797244653469,93.6874656794852143]},"#eeeeee":{"lch":[94.0978342288501466,4.90671076366048496e-12,0],"luv":[94.0978342288501466,4.6515081442594671e-12,1.56182025281704723e-12],"rgb":[0.933333333333333348,0.933333333333333348,0.933333333333333348],"xyz":[0.812632791977026758,0.854992608124227838,0.931136326720093943],"hpluv":[0,3.87295813278393312e-11,94.0978342288501466],"hsluv":[0,3.8714510065860851e-11,94.0978342288501466]},"#eeeeff":{"lch":[94.5453539438838391,13.4050739145486393,265.874320218197],"luv":[94.5453539438838391,-0.964421163933715353,-13.3703365130825738],"rgb":[0.933333333333333348,0.933333333333333348,1],"xyz":[0.838803840386858179,0.865461027488160561,1.06897051501187579],"hpluv":[265.874320218197,114.885858328026472,94.5453539438838391],"hsluv":[265.874320218197,99.999999999981938,94.5453539438838391]},"#777700":{"lch":[48.4055282063088868,53.3622847060179737,85.8743202181747],"luv":[48.4055282063088868,3.83912219020021839,53.2240036999738706],"rgb":[0.466666666666666674,0.466666666666666674,0],"xyz":[0.142041159467901856,0.171157317521294372,0.0255545090233414707],"hpluv":[85.8743202181747,139.887458074797621,48.4055282063088868],"hsluv":[85.8743202181747,100.000000000002331,48.4055282063088868]},"#777711":{"lch":[48.4562461221814829,51.3697569370731628,85.874320218174617],"luv":[48.4562461221814829,3.69577080233359201,51.2366392921178502],"rgb":[0.466666666666666674,0.466666666666666674,0.0666666666666666657],"xyz":[0.143052824967539,0.171561983721149225,0.0308826139880971],"hpluv":[85.874320218174617,134.523163178361983,48.4562461221814829],"hsluv":[85.874320218174617,96.1652781669932324,48.4562461221814829]},"#777722":{"lch":[48.5500530694338579,47.7524066126053768,85.8743202181744323],"luv":[48.5500530694338579,3.43552238949120969,47.6286628324468282],"rgb":[0.466666666666666674,0.466666666666666674,0.133333333333333331],"xyz":[0.144928183106016,0.172312126976540053,0.0407595001840763],"hpluv":[85.8743202181744323,124.808706278838557,48.5500530694338579],"hsluv":[85.8743202181744323,89.2207979160694293,48.5500530694338579]},"#777733":{"lch":[48.7039135074563063,42.0024110114446501,85.874320218174],"luv":[48.7039135074563063,3.02184190658892726,41.8935675523809934],"rgb":[0.466666666666666674,0.466666666666666674,0.2],"xyz":[0.148015933838473723,0.173547227269523152,0.0570216540416874432],"hpluv":[85.874320218174,109.433348296247431,48.7039135074563063],"hsluv":[85.874320218174,78.2295638238963704,48.7039135074563063]},"#777744":{"lch":[48.9247697387985312,34.1210359912247227,85.8743202181732528],"luv":[48.9247697387985312,2.45482042510454956,34.0326160292585],"rgb":[0.466666666666666674,0.466666666666666674,0.266666666666666663],"xyz":[0.152473929082692611,0.175330425367210746,0.0805004289945740747],"hpluv":[85.8743202181732528,88.497855114462908,48.9247697387985312],"hsluv":[85.8743202181732528,63.2636094274766378,48.9247697387985312]},"#777755":{"lch":[49.2178287935421537,24.2815247917763841,85.8743202181716327],"luv":[49.2178287935421537,1.74692184102758041,24.2186025669317253],"rgb":[0.466666666666666674,0.466666666666666674,0.333333333333333315],"xyz":[0.158436343122054624,0.177715390982955579,0.11190247626854799],"hpluv":[85.8743202181716327,62.6026663147617,49.2178287935421537],"hsluv":[85.8743202181716327,44.7521651878825324,49.2178287935421537]},"#777766":{"lch":[49.5868745078829676,12.7836483150604128,85.8743202181664742],"luv":[49.5868745078829676,0.919713018071489197,12.750521252385596],"rgb":[0.466666666666666674,0.466666666666666674,0.4],"xyz":[0.166021338895562781,0.18074938929235887,0.151850120675691952],"hpluv":[85.8743202181664742,32.7135296885410085,49.5868745078829676],"hsluv":[85.8743202181664742,23.385605928338574,49.5868745078829676]},"#777777":{"lch":[50.0344387925380687,2.67192546523751356e-12,0],"luv":[50.0344387925380687,2.52749706171116152e-12,8.66570421158112546e-13],"rgb":[0.466666666666666674,0.466666666666666674,0.466666666666666674],"xyz":[0.175335351915764714,0.184474994500439693,0.200903922582089861],"hpluv":[0,6.77633132918180515e-12,50.0344387925380687],"hsluv":[0,1.94020402484744743e-12,50.0344387925380687]},"#777788":{"lch":[50.5619220099523545,13.6772258441596737,265.874320218187563],"luv":[50.5619220099523545,-0.984000994856362388,-13.6417831984777926],"rgb":[0.466666666666666674,0.466666666666666674,0.533333333333333326],"xyz":[0.186475769017708515,0.188931161341217291,0.259576785985662029],"hpluv":[265.874320218187563,34.3252548472133,50.5619220099523545],"hsluv":[265.874320218187563,11.1797639211738336,50.5619220099523545]},"#777799":{"lch":[51.1696982290560669,27.8798810968622455,265.87432021818239],"luv":[51.1696982290560669,-2.00580373888746255,-27.8076342276045096],"rgb":[0.466666666666666674,0.466666666666666674,0.6],"xyz":[0.199532733126781242,0.194153946984846448,0.328343463626779908],"hpluv":[265.87432021818239,69.1380916549642563,51.1696982290560669],"hsluv":[265.87432021818239,22.9846011782403536,51.1696982290560669]},"#7777aa":{"lch":[51.8572203345112,42.2927406525888614,265.874320218180628],"luv":[51.8572203345112,-3.04272952363285398,-42.1831448442758443],"rgb":[0.466666666666666674,0.466666666666666674,0.66666666666666663],"xyz":[0.21459042609203377,0.200177024170947543,0.407647313243778564],"hpluv":[265.874320218180628,103.489412577951782,51.8572203345112],"hsluv":[265.874320218180628,35.2207148819814435,51.8572203345112]},"#7777bb":{"lch":[52.6231302285762439,56.6671214785474,265.874320218179832],"luv":[52.6231302285762439,-4.07688697591046,-56.5202764435038816],"rgb":[0.466666666666666674,0.466666666666666674,0.733333333333333282],"xyz":[0.231728018199370445,0.207032061013882301,0.497905298342420255],"hpluv":[265.874320218179832,136.645017565491173,52.6231302285762439],"hsluv":[265.874320218179832,47.751077300634,52.6231302285762439]},"#7777cc":{"lch":[53.4653742998309696,70.8221320427834513,265.874320218179378],"luv":[53.4653742998309696,-5.09526194727884452,-70.6386062488075],"rgb":[0.466666666666666674,0.466666666666666674,0.8],"xyz":[0.251020393643092143,0.214749011191371103,0.599511809012690411],"hpluv":[265.874320218179378,168.087613695837888,53.4653742998309696],"hsluv":[265.874320218179378,60.4968982098403671,53.4653742998309696]},"#7777dd":{"lch":[54.3813217092404102,84.6378263199215581,265.874320218179037],"luv":[54.3813217092404102,-6.08922498249284594,-84.4184990584042083],"rgb":[0.466666666666666674,0.466666666666666674,0.866666666666666696],"xyz":[0.272538719193725743,0.223356341411624637,0.712841656912696409],"hpluv":[265.874320218179037,197.494074150637061,54.3813217092404102],"hsluv":[265.874320218179037,73.4330970128385445,54.3813217092404102]},"#7777ee":{"lch":[55.3678819060931,98.0443353361264656,265.874320218178809],"luv":[55.3678819060931,-7.05374939408338086,-97.7902669542745713],"rgb":[0.466666666666666674,0.466666666666666674,0.933333333333333348],"xyz":[0.296350899459900452,0.232881213518094682,0.838252472981219632],"hpluv":[265.874320218178809,224.700440227144242,55.3678819060931],"hsluv":[265.874320218178809,86.5809092876847,55.3678819060931]},"#7777ff":{"lch":[56.4216176153771158,111.010032393554411,265.874320218178696],"luv":[56.4216176153771158,-7.98655981550332,-110.722365194803288],"rgb":[0.466666666666666674,0.466666666666666674,1],"xyz":[0.322521947869731873,0.243349632882027378,0.976086661273001477],"hpluv":[265.874320218178696,249.664056525023511,56.4216176153771158],"hsluv":[265.874320218178696,99.99999999999892,56.4216176153771158]},"#eeff00":{"lch":[95.8710857598618702,106.837421111995667,91.929871543819857],"luv":[95.8710857598618702,-3.59788306357601462,106.776822332015158],"rgb":[0.933333333333333348,1,0],"xyz":[0.710175424414702,0.896973456986776663,0.135722486905439893],"hpluv":[91.929871543819857,1221.941869030823,95.8710857598618702],"hsluv":[91.929871543819857,100.000000000002217,95.8710857598618702]},"#eeff11":{"lch":[95.8879066370154192,106.077593073364397,91.9648080695471748],"luv":[95.8879066370154192,-3.63693915095535747,106.015227330089402],"rgb":[0.933333333333333348,1,0.0666666666666666657],"xyz":[0.71118708991433921,0.897378123186631571,0.14105059187019553],"hpluv":[91.9648080695471748,1218.36968740939687,95.8879066370154192],"hsluv":[91.9648080695471748,99.9999999999846096,95.8879066370154192]},"#eeff22":{"lch":[95.9190746883988083,104.674935415410417,92.0306447189025221],"luv":[95.9190746883988083,-3.7090534526558554,104.609201443781629],"rgb":[0.933333333333333348,1,0.133333333333333331],"xyz":[0.713062448052816156,0.898128266442022372,0.150927478066174708],"hpluv":[92.0306447189025221,1211.72771901411761,95.9190746883988083],"hsluv":[92.0306447189025221,99.9999999999843254,95.9190746883988083]},"#eeff33":{"lch":[95.9703546560603,102.38192729680722,92.1421884898051076],"luv":[95.9703546560603,-3.826988551916231,102.31037677397255],"rgb":[0.933333333333333348,1,0.2],"xyz":[0.716150198785274,0.899363366735005498,0.167189631923785859],"hpluv":[92.1421884898051076,1200.73225066318059,95.9703546560603],"hsluv":[92.1421884898051076,99.9999999999843,95.9703546560603]},"#eeff44":{"lch":[96.0443082677326316,99.1069805797193482,92.3105231291127666],"luv":[96.0443082677326316,-3.99552836231266495,99.0264073504377],"rgb":[0.933333333333333348,1,0.266666666666666663],"xyz":[0.720608194029492832,0.901146564832693064,0.190668406876672497],"hpluv":[92.3105231291127666,1184.71704479359755,96.0443082677326316],"hsluv":[92.3105231291127666,99.999999999984,96.0443082677326316]},"#eeff55":{"lch":[96.1430663154878,94.7914212488158086,92.5502587525383831],"luv":[96.1430663154878,-4.21781218752730513,94.6975374691506744],"rgb":[0.933333333333333348,1,0.333333333333333315],"xyz":[0.726570608068854762,0.903531530448437814,0.222070454150646412],"hpluv":[92.5502587525383831,1163.01160371768833,96.1430663154878],"hsluv":[92.5502587525383831,99.9999999999832312,96.1430663154878]},"#eeff66":{"lch":[96.2684490440968261,89.4056432425818315,92.8821944044194083],"luv":[96.2684490440968261,-4.49554545672610839,89.2925479234763912],"rgb":[0.933333333333333348,1,0.4],"xyz":[0.734155603842363,0.906565528757841133,0.262018098557790347],"hpluv":[92.8821944044194083,1134.86447310352946,96.2684490440968261],"hsluv":[92.8821944044194083,99.9999999999826912,96.2684490440968261]},"#eeff77":{"lch":[96.4220309754045104,82.947030730659,93.3376121292550494],"luv":[96.4220309754045104,-4.82912482473711879,82.8063370791148827],"rgb":[0.933333333333333348,1,0.466666666666666674],"xyz":[0.743469616862564853,0.910291133965922,0.311071900464188311],"hpluv":[93.3376121292550494,1099.34916045901696,96.4220309754045104],"hsluv":[93.3376121292550494,99.9999999999824354,96.4220309754045104]},"#eeff88":{"lch":[96.6051797330544559,75.4384320618763553,93.966065888554354],"luv":[96.6051797330544559,-5.21774760700183382,75.2577713054536446],"rgb":[0.933333333333333348,1,0.533333333333333326],"xyz":[0.754610033964508764,0.914747300806699526,0.369744763867760451],"hpluv":[93.966065888554354,1055.22684316018899,96.6051797330544559],"hsluv":[93.966065888554354,99.9999999999810711,96.6051797330544559]},"#eeff99":{"lch":[96.8190810543072,66.9270103141668926,94.8508818247366],"luv":[96.8190810543072,-5.65953211211599072,66.6872881879637589],"rgb":[0.933333333333333348,1,0.6],"xyz":[0.767666998073581408,0.919970086450328739,0.43851144150887833],"hpluv":[94.8508818247366,1000.72847038880911,96.8190810543072],"hsluv":[94.8508818247366,99.9999999999804,96.8190810543072]},"#eeffaa":{"lch":[97.0647558759300182,57.4841926777339438,96.1432585072641785],"luv":[97.0647558759300182,-6.15165762861061438,57.1540857352402938],"rgb":[0.933333333333333348,1,0.66666666666666663],"xyz":[0.782724691038834,0.925993163636429806,0.517815291125877],"hpluv":[96.1432585072641785,933.191048721381,97.0647558759300182],"hsluv":[96.1432585072641785,99.9999999999786127,97.0647558759300182]},"#eeffbb":{"lch":[97.3430726615411857,47.2094061136043166,98.1473956779809242],"luv":[97.3430726615411857,-6.69052372550339935,46.7329104366258861],"rgb":[0.933333333333333348,1,0.733333333333333282],"xyz":[0.799862283146170583,0.932848200479364564,0.608073276224518677],"hpluv":[98.1473956779809242,848.432918810296883,97.3430726615411857],"hsluv":[98.1473956779809242,99.9999999999760689,97.3430726615411857]},"#eeffcc":{"lch":[97.6547568121604,36.2474903433398126,101.573139749476653],"luv":[97.6547568121604,-7.27192346215819718,35.5105573787715443],"rgb":[0.933333333333333348,1,0.8],"xyz":[0.819154658589892337,0.940565150656853421,0.709679786894788833],"hpluv":[101.573139749476653,739.717147432346792,97.6547568121604],"hsluv":[101.573139749476653,99.999999999972971,97.6547568121604]},"#eeffdd":{"lch":[98.0003982932414743,24.8675243497069864,108.50155795297276],"luv":[98.0003982932414743,-7.89122250686935445,23.5822470225029335],"rgb":[0.933333333333333348,1,0.866666666666666696],"xyz":[0.840672984140525936,0.949172480877106928,0.823009634794794831],"hpluv":[108.50155795297276,596.728870831386416,98.0003982932414743],"hsluv":[108.50155795297276,99.9999999999688072,98.0003982932414743]},"#eeffee":{"lch":[98.3804582036479,13.96608756186059,127.715012949221688],"luv":[98.3804582036479,-8.54353535492541205,11.0480588984987129],"rgb":[0.933333333333333348,1,0.933333333333333348],"xyz":[0.864485164406700646,0.958697352983577,0.948420450863318],"hpluv":[127.715012949221688,414.943064796341446,98.3804582036479],"hsluv":[127.715012949221688,99.9999999999608491,98.3804582036479]},"#eeffff":{"lch":[98.7952747621608438,9.43620053547767768,192.177050630058204],"luv":[98.7952747621608438,-9.22389036737693679,-1.99040876112424892],"rgb":[0.933333333333333348,1,1],"xyz":[0.890656212816532067,0.969165772347509669,1.0862546391551],"hpluv":[192.177050630058204,378.040319927501173,98.7952747621608438],"hsluv":[192.177050630058204,99.999999999948713,98.7952747621608438]},"#778800":{"lch":[53.5249548615687303,60.5938372915660253,96.5029793655947259],"luv":[53.5249548615687303,-6.86254771619202231,60.2039745910497572],"rgb":[0.466666666666666674,0.533333333333333326,0],"xyz":[0.164113529192872309,0.215302056971235917,0.0329119655983314136],"hpluv":[96.5029793655947259,143.651932639250902,53.5249548615687303],"hsluv":[96.5029793655947259,100.000000000002373,53.5249548615687303]},"#778811":{"lch":[53.5684856288310272,58.8481082257442409,96.7583563096261088],"luv":[53.5684856288310272,-6.9253766303469888,58.4391906196240143],"rgb":[0.466666666666666674,0.533333333333333326,0.0666666666666666657],"xyz":[0.165125194692509442,0.21570672317109077,0.0382400705630870433],"hpluv":[96.7583563096261088,139.399900460742,53.5684856288310272],"hsluv":[96.7583563096261088,96.9357421545617,53.5684856288310272]},"#778822":{"lch":[53.6490362820541407,55.6690512282284615,97.2652817371477],"luv":[53.6490362820541407,-7.04010577997538,55.2220986133077147],"rgb":[0.466666666666666674,0.533333333333333326,0.133333333333333331],"xyz":[0.167000552830986443,0.216456866426481598,0.0481169567590662428],"hpluv":[97.2652817371477,131.671329649176641,53.6490362820541407],"hsluv":[97.2652817371477,91.3605066517003337,53.6490362820541407]},"#778833":{"lch":[53.7812573057213,50.5917713326567053,98.2096275165039856],"luv":[53.7812573057213,-7.22426441450666346,50.0733195448945381],"rgb":[0.466666666666666674,0.533333333333333326,0.2],"xyz":[0.170088303563444176,0.217691966719464697,0.064379110616677393],"hpluv":[98.2096275165039856,119.368094402160139,53.7812573057213],"hsluv":[98.2096275165039856,82.4672262716137539,53.7812573057213]},"#778844":{"lch":[53.9712743947247162,43.5928841845235198,99.8805739619221811],"luv":[53.9712743947247162,-7.48032491712259429,42.9462954241638357],"rgb":[0.466666666666666674,0.533333333333333326,0.266666666666666663],"xyz":[0.174546298807663064,0.219475164817152291,0.0878578855695640315],"hpluv":[99.8805739619221811,102.492540276722124,53.9712743947247162],"hsluv":[99.8805739619221811,70.2195807792145672,53.9712743947247162]},"#778855":{"lch":[54.2238135722873,34.8221097745323078,102.954066597198249],"luv":[54.2238135722873,-7.80606678579386326,33.9358903004666175],"rgb":[0.466666666666666674,0.533333333333333326,0.333333333333333315],"xyz":[0.180508712847025077,0.221860130432897124,0.119259932843537933],"hpluv":[102.954066597198249,81.4900057495692636,54.2238135722873],"hsluv":[102.954066597198249,54.8454134878709638,54.2238135722873]},"#778866":{"lch":[54.542475349788262,24.6519214642532667,109.417534351990682],"luv":[54.542475349788262,-8.19552569001744224,23.2497438812554442],"rgb":[0.466666666666666674,0.533333333333333326,0.4],"xyz":[0.188093708620533234,0.224894128742300414,0.159207577250681909],"hpluv":[109.417534351990682,57.3528835536874197,54.542475349788262],"hsluv":[109.417534351990682,36.7830408334215164,54.542475349788262]},"#778877":{"lch":[54.9298804020046703,14.1239929232838151,127.715012949231166],"luv":[54.9298804020046703,-8.6401314869560828,11.1729720300858784],"rgb":[0.466666666666666674,0.533333333333333326,0.466666666666666674],"xyz":[0.197407721640735168,0.228619733950381238,0.208261379157079818],"hpluv":[127.715012949231166,32.6278280107521041,54.9298804020046703],"hsluv":[127.715012949231166,16.6133799052879709,54.9298804020046703]},"#778888":{"lch":[55.3877640712208574,9.3400800844087577,192.177050630059369],"luv":[55.3877640712208574,-9.12993258220805437,-1.97013375878514596],"rgb":[0.466666666666666674,0.533333333333333326,0.533333333333333326],"xyz":[0.208548138742678968,0.233075900791158835,0.266934242560651958],"hpluv":[192.177050630059369,21.3981433643613,55.3877640712208574],"hsluv":[192.177050630059369,21.3143847536295468,55.3877640712208574]},"#778899":{"lch":[55.9170512374386703,18.5603965019494623,238.655736169794807],"luv":[55.9170512374386703,-9.65472976501325597,-15.851640655596027],"rgb":[0.466666666666666674,0.533333333333333326,0.6],"xyz":[0.221605102851751695,0.238298686434788,0.335700920201769892],"hpluv":[238.655736169794807,42.1194135101242679,55.9170512374386703],"hsluv":[238.655736169794807,26.1912729818073053,55.9170512374386703]},"#7788aa":{"lch":[56.5179258756863732,31.8473117719276075,251.310804784322386],"luv":[56.5179258756863732,-10.2049729927717898,-30.1680260095876527],"rgb":[0.466666666666666674,0.533333333333333326,0.66666666666666663],"xyz":[0.236662795817004223,0.244321763620889087,0.415004769818768493],"hpluv":[251.310804784322386,71.5032678590983721,56.5179258756863732],"hsluv":[251.310804784322386,31.1149405392867244,56.5179258756863732]},"#7788bb":{"lch":[57.1899017055338845,45.9393215269311881,256.438388794294667],"luv":[57.1899017055338845,-10.7723499078102041,-44.6584565319768387],"rgb":[0.466666666666666674,0.533333333333333326,0.733333333333333282],"xyz":[0.253800387924340898,0.251176800463823846,0.505262754917410239],"hpluv":[256.438388794294667,101.930593576715296,57.1899017055338845],"hsluv":[256.438388794294667,41.4357647235180622,57.1899017055338845]},"#7788cc":{"lch":[57.9318961804226547,60.1932243037694406,259.131204763586595],"luv":[57.9318961804226547,-11.3500713849249486,-59.1134513595764233],"rgb":[0.466666666666666674,0.533333333333333326,0.8],"xyz":[0.273092763368062652,0.258893750641312648,0.606869265587680395],"hpluv":[259.131204763586595,131.8466774878151,57.9318961804226547],"hsluv":[259.131204763586595,55.5026255722761661,57.9318961804226547]},"#7788dd":{"lch":[58.7423077351926679,74.3397271130694861,260.762999043897821],"luv":[58.7423077351926679,-11.9329115646152975,-73.3757497327060264],"rgb":[0.466666666666666674,0.533333333333333326,0.866666666666666696],"xyz":[0.29461108891869614,0.267501080861566209,0.720199113487686393],"hpluv":[260.762999043897821,160.586593274196787,58.7423077351926679],"hsluv":[260.762999043897821,69.9489143241080598,58.7423077351926679]},"#7788ee":{"lch":[59.6190949291064101,88.2283098571320465,261.84384456781811],"luv":[59.6190949291064101,-12.5170812067924775,-87.3358880318318285],"rgb":[0.466666666666666674,0.533333333333333326,0.933333333333333348],"xyz":[0.318423269184870905,0.277025952968036226,0.845609929556209616],"hpluv":[261.84384456781811,187.785436290663455,59.6190949291064101],"hsluv":[261.84384456781811,84.7689484415743237,59.6190949291064101]},"#7788ff":{"lch":[60.55985551741054,101.77153783075579,262.604380260147],"luv":[60.55985551741054,-13.1000102630052879,-100.924901008354297],"rgb":[0.466666666666666674,0.533333333333333326,1],"xyz":[0.344594317594702271,0.28749437233196895,0.983444117847991461],"hpluv":[262.604380260147,213.245970352856943,60.55985551741054],"hsluv":[262.604380260147,99.9999999999987921,60.55985551741054]},"#779900":{"lch":[58.6994568897504223,69.1976359459353603,103.993850276975294],"luv":[58.6994568897504223,-16.7332165977800322,67.1439668384135899],"rgb":[0.466666666666666674,0.6,0],"xyz":[0.189983129645339782,0.267041257876171612,0.0415351657491536685],"hpluv":[103.993850276975294,149.587912305351722,58.6994568897504223],"hsluv":[103.993850276975294,100.000000000002444,58.6994568897504223]},"#779911":{"lch":[58.7371702745588493,67.6759907780605232,104.326162498332039],"luv":[58.7371702745588493,-16.7458460058928829,65.5714600214076],"rgb":[0.466666666666666674,0.6,0.0666666666666666657],"xyz":[0.190994795144976914,0.267445924076026464,0.0468632707139093],"hpluv":[104.326162498332039,146.20456366036808,58.7371702745588493],"hsluv":[104.326162498332039,97.5197891999702,58.7371702745588493]},"#779922":{"lch":[58.8069803361006223,64.8997387816913,104.97431376012679],"luv":[58.8069803361006223,-16.7691829588827659,62.6958578920751464],"rgb":[0.466666666666666674,0.6,0.133333333333333331],"xyz":[0.192870153283453916,0.268196067331417265,0.0567401569098885],"hpluv":[104.97431376012679,140.04041716275114,58.8069803361006223],"hsluv":[104.97431376012679,92.9911396041894704,58.8069803361006223]},"#779933":{"lch":[58.9216385591388132,60.4528100001228097,106.14237332279157],"luv":[58.9216385591388132,-16.8074000849803582,58.0693855598141369],"rgb":[0.466666666666666674,0.6,0.2],"xyz":[0.195957904015911677,0.269431167624400392,0.0730023107674996341],"hpluv":[106.14237332279157,130.191012221085145,58.9216385591388132],"hsluv":[106.14237332279157,85.724115661044948,58.9216385591388132]},"#779944":{"lch":[59.0865618982540752,54.3006768161790845,108.091337704968765],"luv":[59.0865618982540752,-16.8621369683366211,51.6161974534756354],"rgb":[0.466666666666666674,0.6,0.266666666666666663],"xyz":[0.200415899260130537,0.271214365722087958,0.0964810857203862726],"hpluv":[108.091337704968765,116.615384645059635,59.0865618982540752],"hsluv":[108.091337704968765,75.6282332091309399,59.0865618982540752]},"#779955":{"lch":[59.3060149965037056,46.5647823410072945,111.326222899357617],"luv":[59.3060149965037056,-16.9345685221747893,43.3762532203180413],"rgb":[0.466666666666666674,0.6,0.333333333333333315],"xyz":[0.206378313299492522,0.273599331337832818,0.127883132994360188],"hpluv":[111.326222899357617,99.6318422422000367,59.3060149965037056],"hsluv":[111.326222899357617,62.8087826319283806,59.3060149965037056]},"#779966":{"lch":[59.5833535636433282,37.5662597340720836,116.949978591108717],"luv":[59.5833535636433282,-17.0254963867212936,33.4866591823296957],"rgb":[0.466666666666666674,0.6,0.4],"xyz":[0.213963309073000707,0.276633329647236137,0.16783077740150415],"hpluv":[116.949978591108717,80.0041177209304522,59.5833535636433282],"hsluv":[116.949978591108717,47.5357009492008,59.5833535636433282]},"#779977":{"lch":[59.921152065724,28.0111989307655129,127.71501294923614],"luv":[59.921152065724,-17.1354122862910181,22.1586306282167591],"rgb":[0.466666666666666674,0.6,0.466666666666666674],"xyz":[0.223277322093202613,0.280358934855316932,0.216884579307902059],"hpluv":[127.71501294923614,59.3185968765002301,59.921152065724],"hsluv":[127.71501294923614,30.2037385091367128,59.921152065724]},"#779988":{"lch":[60.3212826107906608,19.7788738743410271,150.794869664161695],"luv":[60.3212826107906608,-17.2645515875173317,9.65086059473676272],"rgb":[0.466666666666666674,0.6,0.533333333333333326],"xyz":[0.234417739195146468,0.28481510169609453,0.275557442711474199],"hpluv":[150.794869664161695,41.6073752981458043,60.3212826107906608],"hsluv":[150.794869664161695,33.5278156565034706,60.3212826107906608]},"#779999":{"lch":[60.7849725890424537,17.8137422376051369,192.177050630060307],"luv":[60.7849725890424537,-17.4129412378011317,-3.75751113860251662],"rgb":[0.466666666666666674,0.6,0.6],"xyz":[0.247474703304219168,0.290037887339723688,0.344324120352592133],"hpluv":[192.177050630060307,37.1876097830212373,60.7849725890424537],"hsluv":[192.177050630060307,37.0420465685486562,60.7849725890424537]},"#7799aa":{"lch":[61.3128540464897895,25.0117677757311512,225.340924984985747],"luv":[61.3128540464897895,-17.5804418295499474,-17.7909131959243076],"rgb":[0.466666666666666674,0.6,0.66666666666666663],"xyz":[0.262532396269471724,0.29606096452582481,0.423627969969590734],"hpluv":[225.340924984985747,51.7645188682129742,61.3128540464897895],"hsluv":[225.340924984985747,40.6599304384258815,61.3128540464897895]},"#7799bb":{"lch":[61.9050111975332129,36.7727368637825478,241.108601392342877],"luv":[61.9050111975332129,-17.766782778670386,-32.1958942436537],"rgb":[0.466666666666666674,0.6,0.733333333333333282],"xyz":[0.279669988376808343,0.302916001368759569,0.513885955068232425],"hpluv":[241.108601392342877,75.37710856774234,61.9050111975332129],"hsluv":[241.108601392342877,44.3026829048042927,61.9050111975332129]},"#7799cc":{"lch":[62.5610290710097274,50.0883036089361084,248.973595844380469],"luv":[62.5610290710097274,-17.971590279241223,-46.7531827927901],"rgb":[0.466666666666666674,0.6,0.8],"xyz":[0.298962363820530097,0.31063295154624837,0.615492465738502581],"hpluv":[248.973595844380469,101.594866952252644,62.5610290710097274],"hsluv":[248.973595844380469,49.5852758814030068,62.5610290710097274]},"#7799dd":{"lch":[63.2800443412030518,63.9273589508424962,253.464421950176984],"luv":[63.2800443412030518,-18.1944086519195096,-61.2835272829234228],"rgb":[0.466666666666666674,0.6,0.866666666666666696],"xyz":[0.320480689371163641,0.319240281766501877,0.728822313638508579],"hpluv":[253.464421950176984,128.191525099113591,63.2800443412030518],"hsluv":[253.464421950176984,65.7895471985927429,63.2800443412030518]},"#7799ee":{"lch":[64.0607982423263138,77.8622331281598292,256.304567564122067],"luv":[64.0607982423263138,-18.434716379612933,-75.6484539148497106],"rgb":[0.466666666666666674,0.6,0.933333333333333348],"xyz":[0.344292869637338406,0.328765153872971894,0.854233129707031802],"hpluv":[256.304567564122067,154.231767587931557,64.0607982423263138],"hsluv":[256.304567564122067,82.5871459557978085,64.0607982423263138]},"#7799ff":{"lch":[64.9016907971027,91.67329289213788,258.23504341307023],"luv":[64.9016907971027,-18.6919383586334327,-89.7474460365571929],"rgb":[0.466666666666666674,0.6,1],"xyz":[0.370463918047169771,0.339233573236904618,0.992067317998813758],"hpluv":[258.23504341307023,179.236372955016122,64.9016907971027],"hsluv":[258.23504341307023,99.9999999999984368,64.9016907971027]},"#660000":{"lch":[19.330201679573328,65.0080772249371819,12.1770506300617765],"luv":[19.330201679573328,63.5454254137925432,13.7123671721378795],"rgb":[0.4,0,0],"xyz":[0.0547936733227042463,0.0282529878070199789,0.00256845343700170745],"hpluv":[12.1770506300617765,426.746789183125202,19.330201679573328],"hsluv":[12.1770506300617765,100.000000000002217,19.330201679573328]},"#660011":{"lch":[19.4980803058243595,61.695772445130423,8.9911342856641614],"luv":[19.4980803058243595,60.9376877881905799,9.641916024853316],"rgb":[0.4,0,0.0666666666666666657],"xyz":[0.0558053388223413716,0.0286576540068748317,0.0078965584017573389],"hpluv":[8.9911342856641614,401.51602003210553,19.4980803058243595],"hsluv":[8.9911342856641614,99.9999999999966178,19.4980803058243595]},"#660022":{"lch":[19.8051492014688648,56.728751528179842,2.87530221933591967],"luv":[19.8051492014688648,56.6573341637173584,2.84565201787440492],"rgb":[0.4,0,0.133333333333333331],"xyz":[0.0576806969608183867,0.029407797262265653,0.0177734445977365332],"hpluv":[2.87530221933591967,363.466537566247382,19.8051492014688648],"hsluv":[2.87530221933591967,99.9999999999968594,19.8051492014688648]},"#660033":{"lch":[20.2995520444984123,51.2727836305606957,352.516911450402631],"luv":[20.2995520444984123,50.836110988726972,-6.67743669143524787],"rgb":[0.4,0,0.2],"xyz":[0.0607684476932761272,0.0306428975552487659,0.0340355984553476765],"hpluv":[352.516911450402631,320.508659944055125,20.2995520444984123],"hsluv":[352.516911450402631,99.9999999999973852,20.2995520444984123]},"#660044":{"lch":[20.9904438433464762,47.7800185043531087,338.095292373375855],"luv":[20.9904438433464762,44.3305689635839855,-17.8250055719836844],"rgb":[0.4,0,0.266666666666666663],"xyz":[0.0652264429374950078,0.0324260956529363389,0.057514373408234315],"hpluv":[338.095292373375855,288.844444062118953,20.9904438433464762],"hsluv":[338.095292373375855,99.999999999997911,20.9904438433464762]},"#660055":{"lch":[21.8759682447435324,48.0792454528985687,322.009867044845],"luv":[21.8759682447435324,37.8920594608334085,-29.5940141436867741],"rgb":[0.4,0,0.333333333333333315],"xyz":[0.071188856976857,0.0348110612686811718,0.0889164206822082304],"hpluv":[322.009867044845,278.887908627948889,21.8759682447435324],"hsluv":[322.009867044845,99.9999999999984,21.8759682447435324]},"#660066":{"lch":[22.9458380566939866,52.2668983658326383,307.715012949243601],"luv":[22.9458380566939866,31.9734565677830815,-41.3464235441515271],"rgb":[0.4,0,0.4],"xyz":[0.0787738527503651781,0.0378450595780844834,0.128864065089352192],"hpluv":[307.715012949243601,289.042783730483393,22.9458380566939866],"hsluv":[307.715012949243601,99.9999999999988,22.9458380566939866]},"#660077":{"lch":[24.1840444716539054,59.1802438936044553,296.875135467660698],"luv":[24.1840444716539054,26.7522904844618061,-52.7884099129864097],"rgb":[0.4,0,0.466666666666666674],"xyz":[0.0880878657705671,0.0415706647861653,0.177917866995750101],"hpluv":[296.875135467660698,310.518260327731298,24.1840444716539054],"hsluv":[296.875135467660698,99.9999999999992326,24.1840444716539054]},"#660088":{"lch":[25.5714349826340381,67.6035320092512819,289.201479741547303],"luv":[25.5714349826340381,22.2341957091879898,-63.8426039670327725],"rgb":[0.4,0,0.533333333333333326],"xyz":[0.0992282828725109256,0.0460268316269428907,0.236590730399322269],"hpluv":[289.201479741547303,335.469941782198191,25.5714349826340381],"hsluv":[289.201479741547303,99.9999999999995168,25.5714349826340381]},"#660099":{"lch":[27.0878540213863559,76.7583277742970296,283.827270614430063],"luv":[27.0878540213863559,18.3449067131383,-74.5339203342523291],"rgb":[0.4,0,0.6],"xyz":[0.112285246981583625,0.0512496172705720551,0.305357408040440148],"hpluv":[283.827270614430063,359.575614235331898,27.0878540213863559],"hsluv":[283.827270614430063,99.9999999999996732,27.0878540213863559]},"#6600aa":{"lch":[28.7136916664512327,86.2331190336617226,280.0081392435834],"luv":[28.7136916664512327,14.9862877024472088,-84.9209161465722246],"rgb":[0.4,0,0.66666666666666663],"xyz":[0.127342939946836181,0.0572726944566731566,0.384661257657438749],"hpluv":[280.0081392435834,381.087223541781498,28.7136916664512327],"hsluv":[280.0081392435834,99.9999999999998863,28.7136916664512327]},"#6600bb":{"lch":[30.4308478844127208,95.8259209373334784,277.232006261077231],"luv":[30.4308478844127208,12.063278317584528,-95.06358103774852],"rgb":[0.4,0,0.733333333333333282],"xyz":[0.144480532054172828,0.0641277312996079152,0.474919242756080495],"hpluv":[277.232006261077231,399.584170303460496,30.4308478844127208],"hsluv":[277.232006261077231,100.000000000000071,30.4308478844127208]},"#6600cc":{"lch":[32.2232190058254631,105.440117399912424,275.16595430901134],"luv":[32.2232190058254631,9.49391256045434,-105.011827817640437],"rgb":[0.4,0,0.8],"xyz":[0.163772907497894554,0.0718446814770967168,0.576525753426350707],"hpluv":[275.16595430901134,415.218107165999243,32.2232190058254631],"hsluv":[275.16595430901134,100.000000000000284,32.2232190058254631]},"#6600dd":{"lch":[34.0768449366564425,115.029794578821409,273.594219506454294],"luv":[34.0768449366564425,7.21119822634443164,-114.803537667557165],"rgb":[0.4,0,0.866666666666666696],"xyz":[0.185291233048528098,0.0804520116973502508,0.689855601326356704],"hpluv":[273.594219506454294,428.341637585051217,34.0768449366564425],"hsluv":[273.594219506454294,100.000000000000313,34.0768449366564425]},"#6600ee":{"lch":[35.9798440153965657,124.573148355199,272.374748889870204],"luv":[35.9798440153965657,5.16172842086039729,-124.466163477612255],"rgb":[0.4,0,0.933333333333333348],"xyz":[0.209103413314702835,0.0899768838038202817,0.815266417394879928],"hpluv":[272.374748889870204,439.343788723350144,35.9798440153965657],"hsluv":[272.374748889870204,100.000000000000313,35.9798440153965657]},"#6600ff":{"lch":[37.9222328155672699,134.059876636217865,271.411957283269032],"luv":[37.9222328155672699,3.30334385288953181,-134.01917192367489],"rgb":[0.4,0,1],"xyz":[0.235274461724534228,0.100445303167752992,0.953100605686661773],"hpluv":[271.411957283269032,448.58447779597617,37.9222328155672699],"hsluv":[271.411957283269032,100.00000000000054,37.9222328155672699]},"#661100":{"lch":[20.9278595225824304,60.6482483509225645,15.3961031612090817],"luv":[20.9278595225824304,58.4717927536604165,16.1015365791022269],"rgb":[0.4,0.0666666666666666657,0],"xyz":[0.0567980735836326536,0.0322617883288768559,0.00323658685731115833],"hpluv":[15.3961031612090817,367.733145903292666,20.9278595225824304],"hsluv":[15.3961031612090817,100.00000000000216,20.9278595225824304]},"#661111":{"lch":[21.0816163302651134,57.5811303886473453,12.1770506300618102],"luv":[21.0816163302651134,56.2855814623301782,12.1457768908291825],"rgb":[0.4,0.0666666666666666657,0.0666666666666666657],"xyz":[0.0578097390832697788,0.0326664545287317087,0.00856469182206678892],"hpluv":[12.1770506300618102,346.589664487627374,21.0816163302651134],"hsluv":[12.1770506300618102,81.2167011616125762,21.0816163302651134]},"#661122":{"lch":[21.363314856368774,52.932385078801687,5.93410154371749865],"luv":[21.363314856368774,52.6487447994206548,5.4723908098767966],"rgb":[0.4,0.0666666666666666657,0.133333333333333331],"xyz":[0.059685097221746794,0.0334165977841225301,0.018441578018045985],"hpluv":[5.93410154371749865,314.406957937895,21.363314856368774],"hsluv":[5.93410154371749865,82.5199513610387356,21.363314856368774]},"#661133":{"lch":[21.8180817632255923,47.7742586248590229,355.183549580278111],"luv":[21.8180817632255923,47.6055578330604661,-4.01131531521171425],"rgb":[0.4,0.0666666666666666657,0.2],"xyz":[0.0627728479542045414,0.0346516980771056429,0.0347037318756571317],"hpluv":[355.183549580278111,277.854041301729922,21.8180817632255923],"hsluv":[355.183549580278111,84.3121175303292603,21.8180817632255923]},"#661144":{"lch":[22.4559756968324393,44.5402485804784689,339.935360677682411],"luv":[22.4559756968324393,41.8369301419790247,-15.2808710453946635],"rgb":[0.4,0.0666666666666666657,0.266666666666666663],"xyz":[0.0672308431984234151,0.036434896174793216,0.0581825068285437702],"hpluv":[339.935360677682411,251.686564911624259,22.4559756968324393],"hsluv":[339.935360677682411,86.3348863624116518,22.4559756968324393]},"#661155":{"lch":[23.2773926977910151,45.1903944783221903,322.792583995755933],"luv":[23.2773926977910151,35.9919645110905364,-27.3267313035930464],"rgb":[0.4,0.0666666666666666657,0.333333333333333315],"xyz":[0.073193257237785414,0.0388198617905380489,0.0895845541025176717],"hpluv":[322.792583995755933,246.349182588766354,23.2773926977910151],"hsluv":[322.792583995755933,88.344826800164725,23.2773926977910151]},"#661166":{"lch":[24.275087751098269,49.8658315110702119,307.715012949243715],"luv":[24.275087751098269,30.5046415204515107,-39.4470277460696508],"rgb":[0.4,0.0666666666666666657,0.4],"xyz":[0.0807782530112935854,0.0418538600999413604,0.129532198509661634],"hpluv":[307.715012949243715,260.664316843383688,24.275087751098269],"hsluv":[307.715012949243715,90.1819147598703239,24.275087751098269]},"#661177":{"lch":[25.4363091503391701,57.3032374709331265,296.512546946797],"luv":[25.4363091503391701,25.5798087859014238,-51.2770358652572114],"rgb":[0.4,0.0666666666666666657,0.466666666666666674],"xyz":[0.0900922660314955,0.0455794653080221768,0.178586000416059543],"hpluv":[296.512546946797,285.867241464858182,25.4363091503391701],"hsluv":[296.512546946797,91.7740463972148461,25.4363091503391701]},"#661188":{"lch":[26.7449145171680129,66.1973281861227179,288.734792076243366],"luv":[26.7449145171680129,21.2617948521868456,-62.6898902427238127],"rgb":[0.4,0.0666666666666666657,0.533333333333333326],"xyz":[0.101232683133439333,0.0500356321487997746,0.23725886381963171],"hpluv":[288.734792076243366,314.078764213635395,26.7449145171680129],"hsluv":[288.734792076243366,93.110372692245349,26.7449145171680129]},"#661199":{"lch":[28.1832309630650286,75.7381406209258614,283.36677781159608],"luv":[28.1832309630650286,17.5094321789343716,-73.6864012521064637],"rgb":[0.4,0.0666666666666666657,0.6],"xyz":[0.114289647242512032,0.0552584177924289321,0.306025541460749617],"hpluv":[283.36677781159608,341.006914961476241,28.1832309630650286],"hsluv":[283.36677781159608,94.2123428080992,28.1832309630650286]},"#6611aa":{"lch":[29.733500038717203,85.5146667147819102,279.591039159426828],"luv":[29.733500038717203,14.2479867443400359,-84.3193518539685],"rgb":[0.4,0.0666666666666666657,0.66666666666666663],"xyz":[0.129347340207764588,0.0612814949785300336,0.385329391077748218],"hpluv":[279.591039159426828,364.950446526832081,29.733500038717203],"hsluv":[279.591039159426828,95.1136535912152254,29.733500038717203]},"#6611bb":{"lch":[31.378866229854367,95.3367425151459287,276.866082014695],"luv":[31.378866229854367,11.3974241300945351,-94.6530147253534153],"rgb":[0.4,0.0666666666666666657,0.733333333333333282],"xyz":[0.146484932315101235,0.0681365318214647853,0.475587376176389964],"hpluv":[276.866082014695,385.533736621086632,31.378866229854367],"hsluv":[276.866082014695,95.8493220980777636,31.378866229854367]},"#6611cc":{"lch":[33.1039576367877899,105.121866511028642,274.848446148865946],"luv":[33.1039576367877899,8.88494143701037409,-104.745714157780327],"rgb":[0.4,0.0666666666666666657,0.8],"xyz":[0.165777307758822962,0.0758534819989535869,0.577193886846660176],"hpluv":[274.848446148865946,402.951217622234481,33.1039576367877899],"hsluv":[274.848446148865946,96.4508528344463372,33.1039576367877899]},"#6611dd":{"lch":[34.8951509835915559,114.837148656435488,273.319244536407894],"luv":[34.8951509835915559,6.64899595047804048,-114.644500803094743],"rgb":[0.4,0.0666666666666666657,0.866666666666666696],"xyz":[0.187295633309456505,0.0844608122192071209,0.690523734746666173],"hpluv":[273.319244536407894,417.596303228590671,34.8951509835915559],"hsluv":[273.319244536407894,96.944722371929771,34.8951509835915559]},"#6611ee":{"lch":[36.7406193088150914,124.471664845310258,272.136065946829319],"luv":[36.7406193088150914,4.63940101804097527,-124.385173182164465],"rgb":[0.4,0.0666666666666666657,0.933333333333333348],"xyz":[0.211107813575631242,0.0939856843256771657,0.815934550815189397],"hpluv":[272.136065946829319,429.895948632666091,36.7406193088150914],"hsluv":[272.136065946829319,97.3524117238680446,36.7406193088150914]},"#6611ff":{"lch":[38.6302462525687815,134.023748920536207,271.203906716280642],"luv":[38.6302462525687815,2.81591803113255,-133.994163605572282],"rgb":[0.4,0.0666666666666666657,1],"xyz":[0.237278861985462636,0.104454103689609862,0.953768739106971242],"hpluv":[271.203906716280642,440.244168299440901,38.6302462525687815],"hsluv":[271.203906716280642,99.999999999999531,38.6302462525687815]},"#662200":{"lch":[23.5697003211059126,54.0433218319152,21.7646438431993481],"luv":[23.5697003211059126,50.1908335966774928,20.038983444740694],"rgb":[0.4,0.133333333333333331,0],"xyz":[0.0605136973184005889,0.0396930357984128235,0.00447512810223376842],"hpluv":[21.7646438431993481,290.955989204018863,23.5697003211059126],"hsluv":[21.7646438431993481,100.000000000002302,23.5697003211059126]},"#662211":{"lch":[23.7037155268300239,51.2256671637292627,18.5481266113504795],"luv":[23.7037155268300239,48.5648418325832196,16.2949413667354186],"rgb":[0.4,0.133333333333333331,0.0666666666666666657],"xyz":[0.0615253628180377071,0.0400977019982676763,0.0098032330669894],"hpluv":[18.5481266113504795,274.227196288753476,23.7037155268300239],"hsluv":[18.5481266113504795,84.4421944630679775,23.7037155268300239]},"#662222":{"lch":[23.9497782760704823,46.8639841586094761,12.177050630061828],"luv":[23.9497782760704823,45.8095660888384515,9.88517404858116],"rgb":[0.4,0.133333333333333331,0.133333333333333331],"xyz":[0.0634007209565147362,0.0408478452536585,0.0196801192629685942],"hpluv":[12.177050630061828,248.300181449835577,23.9497782760704823],"hsluv":[12.177050630061828,58.184428739378582,23.9497782760704823]},"#662233":{"lch":[24.3484354577474491,41.8866591548313139,0.79920805816821483],"luv":[24.3484354577474491,41.8825842907357284,0.584250188216085209],"rgb":[0.4,0.133333333333333331,0.2],"xyz":[0.0664884716889724697,0.0420829455466416105,0.0359422731205797374],"hpluv":[0.79920805816821483,218.295100847162672,24.3484354577474491],"hsluv":[0.79920805816821483,61.8388407102714908,24.3484354577474491]},"#662244":{"lch":[24.9104705449366364,38.7518995195090881,343.921953822216381],"luv":[24.9104705449366364,37.2361321960480467,-10.7322027305005232],"rgb":[0.4,0.133333333333333331,0.266666666666666663],"xyz":[0.0709464669331913433,0.0438661436443291836,0.059421048073466376],"hpluv":[343.921953822216381,197.40147375767063,24.9104705449366364],"hsluv":[343.921953822216381,66.1143919991375,24.9104705449366364]},"#662255":{"lch":[25.6388481254070371,39.7515606661792376,324.488651014584605],"luv":[25.6388481254070371,32.3577893991285421,-23.0902585650003651],"rgb":[0.4,0.133333333333333331,0.333333333333333315],"xyz":[0.0769088809725533423,0.0462511092600740165,0.0908230953474402913],"hpluv":[324.488651014584605,196.74105716675524,25.6388481254070371],"hsluv":[324.488651014584605,70.5303777194930746,25.6388481254070371]},"#662266":{"lch":[26.530115175026431,45.1550068711170525,307.715012949244],"luv":[26.530115175026431,27.6228683191850166,-35.7204674010796381],"rgb":[0.4,0.133333333333333331,0.4],"xyz":[0.0844938767460615137,0.049285107569477328,0.130770739754584253],"hpluv":[307.715012949244,215.976303505553034,26.530115175026431],"hsluv":[307.715012949244,74.7212231760600076,26.530115175026431]},"#662277":{"lch":[27.5758503181253047,53.47184404785515,295.772994892671647],"luv":[27.5758503181253047,23.2499163509258366,-48.1526686233805137],"rgb":[0.4,0.133333333333333331,0.466666666666666674],"xyz":[0.0938078897662634331,0.0530107127775581444,0.179824541660982162],"hpluv":[295.772994892671647,246.056915236342576,27.5758503181253047],"hsluv":[295.772994892671647,78.4792949436714622,27.5758503181253047]},"#662288":{"lch":[28.7641691288539221,63.1969785740596492,287.807032602413699],"luv":[28.7641691288539221,19.3264050913403267,-60.169329123196718],"rgb":[0.4,0.133333333333333331,0.533333333333333326],"xyz":[0.104948306868207261,0.0574668796183357422,0.23849740506455433],"hpluv":[287.807032602413699,278.794247273594806,28.7641691288539221],"hsluv":[287.807032602413699,81.7283139306751565,28.7641691288539221]},"#662299":{"lch":[30.081149723697223,73.446586603294,282.467625610713],"luv":[30.081149723697223,15.8562317990126083,-71.7145800853016766],"rgb":[0.4,0.133333333333333331,0.6],"xyz":[0.118005270977279975,0.0626896652619649,0.307264082705672237],"hpluv":[282.467625610713,309.825038390781458,30.081149723697223],"hsluv":[282.467625610713,84.475317587044259,30.081149723697223]},"#6622aa":{"lch":[31.512047889249807,83.7990879252892569,278.786617054458873],"luv":[31.512047889249807,12.8007301136733549,-82.8156292354725565],"rgb":[0.4,0.133333333333333331,0.66666666666666663],"xyz":[0.133062963942532531,0.068712742448066,0.386567932322670837],"hpluv":[278.786617054458873,337.444217562648532,31.512047889249807],"hsluv":[278.786617054458873,86.7692530837111349,31.512047889249807]},"#6622bb":{"lch":[33.0422299311305281,94.07636648958254,276.16643073789237],"luv":[33.0422299311305281,10.1053888262289746,-93.5320471739658643],"rgb":[0.4,0.133333333333333331,0.733333333333333282],"xyz":[0.150200556049869149,0.0755677792910007529,0.476825917421312584],"hpluv":[276.16643073789237,361.285484259324733,33.0422299311305281],"hsluv":[276.16643073789237,88.6739591516067662,33.0422299311305281]},"#6622cc":{"lch":[34.6578144612334853,104.214655833315277,274.245119058655746],"luv":[34.6578144612334853,7.71433729467952212,-103.928742369761551],"rgb":[0.4,0.133333333333333331,0.8],"xyz":[0.169492931493590904,0.0832847294684895545,0.578432428091582684],"hpluv":[274.245119058655746,381.563613242959605,34.6578144612334853],"hsluv":[274.245119058655746,90.2534916489383079,34.6578144612334853]},"#6622dd":{"lch":[36.346058304563158,114.200305800004017,272.799119030217753],"luv":[36.346058304563158,5.5769048208672336,-114.064052082299],"rgb":[0.4,0.133333333333333331,0.866666666666666696],"xyz":[0.191011257044224447,0.0918920596887430885,0.691762275991588682],"hpluv":[272.799119030217753,398.702789727268566,36.346058304563158],"hsluv":[272.799119030217753,91.5654894217155118,36.346058304563158]},"#6622ee":{"lch":[38.0955422395423,124.039689220569301,271.686141036519132],"luv":[38.0955422395423,3.64980151132168062,-123.985980864222597],"rgb":[0.4,0.133333333333333331,0.933333333333333348],"xyz":[0.214823437310399185,0.101416931795213133,0.817173092060111905],"hpluv":[271.686141036519132,413.167199445381073,38.0955422395423],"hsluv":[271.686141036519132,92.6590152569973498,38.0955422395423]},"#6622ff":{"lch":[39.8962147757429264,133.745689778340022,270.812765394378914],"luv":[39.8962147757429264,1.89717678294479941,-133.732233416399],"rgb":[0.4,0.133333333333333331,1],"xyz":[0.240994485720230578,0.111885351159145829,0.95500728035189375],"hpluv":[270.812765394378914,425.390148773484384,39.8962147757429264],"hsluv":[270.812765394378914,99.99999999999946,39.8962147757429264]},"#ddaa00":{"lch":[72.3107430320736881,86.5721801417344494,59.9465914104400071],"luv":[72.3107430320736881,43.355958426121056,74.9333253195491267],"rgb":[0.866666666666666696,0.66666666666666663,0],"xyz":[0.441922241377765923,0.441231641500849037,0.0618909005679976823],"hpluv":[59.9465914104400071,151.919966798177825,72.3107430320736881],"hsluv":[59.9465914104400071,100.000000000002402,72.3107430320736881]},"#ddaa11":{"lch":[72.3377322217577188,85.4954146103564625,59.6744594052448178],"luv":[72.3377322217577188,43.1676990261245663,73.7971251485224],"rgb":[0.866666666666666696,0.66666666666666663,0.0666666666666666657],"xyz":[0.442933906877403,0.44163630770070389,0.067219005532753312],"hpluv":[59.6744594052448178,149.974443711406025,72.3377322217577188],"hsluv":[59.6744594052448178,98.5180859943944398,72.3377322217577188]},"#ddaa22":{"lch":[72.3877194091470386,83.5208789068112623,59.1557200492863586],"luv":[72.3877194091470386,42.8217010650181038,71.708013019916109],"rgb":[0.866666666666666696,0.66666666666666663,0.133333333333333331],"xyz":[0.444809265015880084,0.44238645095609469,0.0770958917287325],"hpluv":[59.1557200492863586,146.409577733002152,72.3877194091470386],"hsluv":[59.1557200492863586,95.7957425728033911,72.3877194091470386]},"#ddaa33":{"lch":[72.4698996386445771,80.3304907566891,58.2589820164620633],"luv":[72.4698996386445771,42.2603136650720543,68.3158373595774435],"rgb":[0.866666666666666696,0.66666666666666663,0.2],"xyz":[0.44789701574833779,0.443621551249077817,0.0933580455863436548],"hpluv":[58.2589820164620633,140.657238526484292,72.4698996386445771],"hsluv":[58.2589820164620633,91.3821490755410082,72.4698996386445771]},"#ddaa44":{"lch":[72.5882801580772679,75.8571050863154,56.8623293870095949],"luv":[72.5882801580772679,41.467485474955744,63.5196665644635701],"rgb":[0.866666666666666696,0.66666666666666663,0.266666666666666663],"xyz":[0.452355010992556705,0.445404749346765383,0.116836820539230293],"hpluv":[56.8623293870095949,132.607804442486071,72.5882801580772679],"hsluv":[56.8623293870095949,85.1564308385751332,72.5882801580772679]},"#ddaa55":{"lch":[72.7461171317656579,70.1198989219024469,54.780917696258733],"luv":[72.7461171317656579,40.4384565855633085,57.2846528644045065],"rgb":[0.866666666666666696,0.66666666666666663,0.333333333333333315],"xyz":[0.45831742503191869,0.447789714962510244,0.148238867813204195],"hpluv":[54.780917696258733,122.3124851735341,72.7461171317656579],"hsluv":[54.780917696258733,77.0893717991816345,72.7461171317656579]},"#ddaa66":{"lch":[72.9460991959627307,63.2340905833455835,51.7145858463931702],"luv":[72.9460991959627307,39.17852917707404,49.6345954292357661],"rgb":[0.866666666666666696,0.66666666666666663,0.4],"xyz":[0.465902420805426876,0.450823713271913562,0.188186512220348157],"hpluv":[51.7145858463931702,109.998947735143361,72.9460991959627307],"hsluv":[51.7145858463931702,67.2337497701281421,72.9460991959627307]},"#ddaa77":{"lch":[73.1904440644495651,55.4382228560327377,47.150998877343909],"luv":[73.1904440644495651,37.7017926183457632,40.6444508733775294],"rgb":[0.866666666666666696,0.66666666666666663,0.466666666666666674],"xyz":[0.475216433825628781,0.454549318479994358,0.237240314126746066],"hpluv":[47.150998877343909,96.1156803308001173,73.1904440644495651],"hsluv":[47.150998877343909,55.7140089565642214,73.1904440644495651]},"#ddaa88":{"lch":[73.4809558021361511,47.1613293807763228,40.1850915920125189],"luv":[73.4809558021361511,36.0295555463961819,30.4312687229965526],"rgb":[0.866666666666666696,0.66666666666666663,0.533333333333333326],"xyz":[0.486356850927572582,0.459005485320771955,0.295913177530318261],"hpluv":[40.1850915920125189,81.4424009312931645,73.4809558021361511],"hsluv":[40.1850915920125189,45.325944585658668,73.4809558021361511]},"#ddaa99":{"lch":[73.8190624606049539,39.1833139250455389,29.2463480703396321],"luv":[73.8190624606049539,34.1885051927702435,19.1436204212419021],"rgb":[0.866666666666666696,0.66666666666666663,0.6],"xyz":[0.499413815036645281,0.464228270964401113,0.36467985517143614],"hpluv":[29.2463480703396321,67.3553294964948,73.8190624606049539],"hsluv":[29.2463480703396321,46.1073405736803323,73.8190624606049539]},"#ddaaaa":{"lch":[74.2058435914849923,32.9500913661112946,12.1770506300625296],"luv":[74.2058435914849923,32.2087294789219527,6.95027095793437244],"rgb":[0.866666666666666696,0.66666666666666663,0.66666666666666663],"xyz":[0.514471508001897893,0.470251348150502235,0.443983704788434741],"hpluv":[12.1770506300625296,56.3453191386000114,74.2058435914849923],"hsluv":[12.1770506300625296,46.9171896008106,74.2058435914849923]},"#ddaabb":{"lch":[74.6420527030620633,30.7078714289026884,348.787813428378513],"luv":[74.6420527030620633,30.1217754775259223,-5.97093039446416807],"rgb":[0.866666666666666696,0.66666666666666663,0.733333333333333282],"xyz":[0.531609100109234456,0.477106384993437,0.534241689887076543],"hpluv":[348.787813428378513,52.2042025244198,74.6420527030620633],"hsluv":[348.787813428378513,47.7320050944543937,74.6420527030620633]},"#ddaacc":{"lch":[75.1281375044867445,34.0548346014018435,325.184688201169763],"luv":[75.1281375044867445,27.9589055182432595,-19.4430286208394669],"rgb":[0.866666666666666696,0.66666666666666663,0.8],"xyz":[0.55090147555295621,0.484823335170925795,0.635848200557346699],"hpluv":[325.184688201169763,57.5195499622066393,75.1281375044867445],"hsluv":[325.184688201169763,48.5278754329488109,75.1281375044867445]},"#ddaadd":{"lch":[75.6642595524878772,42.092894356631966,307.715012949247466],"luv":[75.6642595524878772,25.749668941594777,-33.2981426616688125],"rgb":[0.866666666666666696,0.66666666666666663,0.866666666666666696],"xyz":[0.572419801103589809,0.493430665391179302,0.749178048457352697],"hpluv":[307.715012949247466,70.5922995729826255,75.6642595524878772],"hsluv":[307.715012949247466,49.2811497501269855,75.6642595524878772]},"#ddaaee":{"lch":[76.2503141773092636,52.9001531738191915,296.399494755977059],"luv":[76.2503141773092636,23.5208512504545659,-47.3834967290038875],"rgb":[0.866666666666666696,0.66666666666666663,0.933333333333333348],"xyz":[0.596231981369764519,0.502955537497649319,0.87458886452587592],"hpluv":[296.399494755977059,89.1958388421213,76.2503141773092636],"hsluv":[296.399494755977059,73.8038640729286,76.2503141773092636]},"#ddaaff":{"lch":[76.8859510948180542,65.1444004641461447,289.080822119258073],"luv":[76.8859510948180542,21.295808093697417,-61.565261872824486],"rgb":[0.866666666666666696,0.66666666666666663,1],"xyz":[0.62240302977959594,0.513423956861582,1.01242305281765765],"hpluv":[289.080822119258073,113.514774922986319,76.8859510948180542],"hsluv":[289.080822119258073,99.9999999999968736,76.8859510948180542]},"#663300":{"lch":[27.2772702365161024,46.6784293424923,33.1138040531735385],"luv":[27.2772702365161024,39.0972512948193938,25.5006020923387098],"rgb":[0.4,0.2,0],"xyz":[0.0666314194074114075,0.0519284799764346272,0.00651436879857064926],"hpluv":[33.1138040531735385,217.147410386557254,27.2772702365161024],"hsluv":[33.1138040531735385,100.000000000002288,27.2772702365161024]},"#663311":{"lch":[27.3893959478715772,43.971204952951652,30.1269617465812196],"luv":[27.3893959478715772,38.0313691656755353,22.0699303215615963],"rgb":[0.4,0.2,0.0666666666666666657],"xyz":[0.0676430849070485257,0.0523331461762894801,0.0118424737633262799],"hpluv":[30.1269617465812196,203.716046393577358,27.3893959478715772],"hsluv":[30.1269617465812196,87.8713966090680572,27.3893959478715772]},"#663322":{"lch":[27.5957277293980781,39.608651287835805,23.9834802389854467],"luv":[27.5957277293980781,36.1889469500517436,16.0998563809655693],"rgb":[0.4,0.2,0.133333333333333331],"xyz":[0.0695184430455255548,0.0530832894316803,0.0217193599593054759],"hpluv":[23.9834802389854467,182.132533879714401,27.5957277293980781],"hsluv":[23.9834802389854467,66.9779468056010501,27.5957277293980781]},"#663333":{"lch":[27.9312558147072,34.2527069144242517,12.1770506300619683],"luv":[27.9312558147072,33.482036777055967,7.2250359324586606],"rgb":[0.4,0.2,0.2],"xyz":[0.0726061937779832883,0.0543183897246634143,0.0379815138169166192],"hpluv":[12.1770506300619683,155.612242967619039,27.9312558147072],"hsluv":[12.1770506300619683,36.4647718300342518,27.9312558147072]},"#663344":{"lch":[28.4068233476218452,30.4023991370198274,352.642674566889241],"luv":[28.4068233476218452,30.1520905841737843,-3.89323858637544307],"rgb":[0.4,0.2,0.266666666666666663],"xyz":[0.0770641890222021619,0.0561015878223509873,0.0614602887698032577],"hpluv":[352.642674566889241,135.807736934047625,28.4068233476218452],"hsluv":[352.642674566889241,42.3197568133242044,28.4068233476218452]},"#663355":{"lch":[29.027378781744666,31.164203729876963,328.257954430910445],"luv":[29.027378781744666,26.5028264215118483,-16.3953586660521324],"rgb":[0.4,0.2,0.333333333333333315],"xyz":[0.0830266030615641609,0.0584865534380958202,0.0928623360437771661],"hpluv":[328.257954430910445,136.234637721643935,29.027378781744666],"hsluv":[328.257954430910445,48.648881209958347,29.027378781744666]},"#663366":{"lch":[29.7928910898429251,37.2833882928919067,307.715012949244567],"luv":[29.7928910898429251,22.8075289246907325,-29.4935190668720466],"rgb":[0.4,0.2,0.4],"xyz":[0.0906115988350723323,0.0615205517474991317,0.132809980450921128],"hpluv":[307.715012949244567,158.796911496206434,29.7928910898429251],"hsluv":[307.715012949244567,54.9388950129523792,29.7928910898429251]},"#663377":{"lch":[30.6992208566667273,46.7654342463890345,294.320996437271049],"luv":[30.6992208566667273,19.2602655771695837,-42.6151148086008646],"rgb":[0.4,0.2,0.466666666666666674],"xyz":[0.0999256118552742517,0.0652461569555799481,0.181863782357319037],"hpluv":[294.320996437271049,193.302265796468333,30.6992208566667273],"hsluv":[294.320996437271049,60.8304716126584424,30.6992208566667273]},"#663388":{"lch":[31.7390466224972485,57.6768981875091811,286.074834637191429],"luv":[31.7390466224972485,15.9703082974272554,-55.4217812544619122],"rgb":[0.4,0.2,0.533333333333333326],"xyz":[0.11106602895721808,0.0697023237963575459,0.240536645760891205],"hpluv":[286.074834637191429,230.593651019326217,31.7390466224972485],"hsluv":[286.074834637191429,66.1275975958513,31.7390466224972485]},"#663399":{"lch":[32.9028065942714818,68.9918273860838696,280.844497617061506],"luv":[32.9028065942714818,12.9804074562249703,-67.7597319087197292],"rgb":[0.4,0.2,0.6],"xyz":[0.124122993066290793,0.0749251094399867,0.309303323402009112],"hpluv":[280.844497617061506,266.074975063872387,32.9028065942714818],"hsluv":[280.844497617061506,70.7618769362906761,32.9028065942714818]},"#6633aa":{"lch":[34.1795810026756612,80.2563017922262,277.366876751775067],"luv":[34.1795810026756612,10.2906460265496023,-79.5938225097975],"rgb":[0.4,0.2,0.66666666666666663],"xyz":[0.139180686031543321,0.0809481866260878,0.388607173019007712],"hpluv":[277.366876751775067,297.955725741163178,34.1795810026756612],"hsluv":[277.366876751775067,74.7463951454814293,34.1795810026756612]},"#6633bb":{"lch":[35.5578512622049701,91.2933310256451875,274.950579703742051],"luv":[35.5578512622049701,7.87828999249439477,-90.9527615663878208],"rgb":[0.4,0.2,0.733333333333333282],"xyz":[0.15631827813888,0.0878032234690225566,0.478865158117649459],"hpluv":[274.950579703742051,325.793841875348,35.5578512622049701],"hsluv":[274.950579703742051,78.1373397599298158,35.5578512622049701]},"#6633cc":{"lch":[37.0261004663704369,102.052471518039624,273.208108112313198],"luv":[37.0261004663704369,5.71114175070883,-101.892540467119574],"rgb":[0.4,0.2,0.8],"xyz":[0.175610653582601722,0.0955201736465113582,0.58047166878791967],"hpluv":[273.208108112313198,349.747708937339723,37.0261004663704369],"hsluv":[273.208108112313198,81.008127051099,37.0261004663704369]},"#6633dd":{"lch":[38.5732487885037258,112.538160698021628,271.912259810227567],"luv":[38.5732487885037258,3.75528971541350476,-112.475488051606391],"rgb":[0.4,0.2,0.866666666666666696],"xyz":[0.197128979133235266,0.104127503866764892,0.693801516687925668],"hpluv":[271.912259810227567,370.214070757058153,38.5732487885037258],"hsluv":[271.912259810227567,83.8924044294761,38.5732487885037258]},"#6633ee":{"lch":[40.1889386764538372,122.775879994578517,270.923585069715159],"luv":[40.1889386764538372,1.97901241536538453,-122.759929204537158],"rgb":[0.4,0.2,0.933333333333333348],"xyz":[0.22094115939941,0.113652375973234937,0.819212332756448891],"hpluv":[270.923585069715159,387.655406037674595,40.1889386764538372],"hsluv":[270.923585069715159,91.8481370725274502,40.1889386764538372]},"#6633ff":{"lch":[41.8636962738951581,132.796565847050772,270.152898062524457],"luv":[41.8636962738951581,0.354377123439640451,-132.796093005873018],"rgb":[0.4,0.2,1],"xyz":[0.247112207809241397,0.124120795337167633,0.957046521048230736],"hpluv":[270.152898062524457,402.521052726566381,41.8636962738951581],"hsluv":[270.152898062524457,99.9999999999993747,41.8636962738951581]},"#ddbb00":{"lch":[76.6269242453545871,86.8164471599593,69.4373142874166263],"luv":[76.6269242453545871,30.4927107526369845,81.2852390562642],"rgb":[0.866666666666666696,0.733333333333333282,0],"xyz":[0.475876739286364758,0.509140637318047595,0.0732090665375303],"hpluv":[69.4373142874166263,149.25100710879434,76.6269242453545871],"hsluv":[69.4373142874166263,100.000000000002373,76.6269242453545871]},"#ddbb11":{"lch":[76.6514577805917412,85.7837129406502754,69.2755127455160391],"luv":[76.6514577805917412,30.3566774947925779,80.2328956062352461],"rgb":[0.866666666666666696,0.733333333333333282,0.0666666666666666657],"xyz":[0.476888404786001863,0.509545303517902504,0.0785371715022859379],"hpluv":[69.2755127455160391,147.663405788509436,76.6514577805917412],"hsluv":[69.2755127455160391,98.710789014839,76.6514577805917412]},"#ddbb22":{"lch":[76.6969020797125722,83.8847347199512257,68.9672438614109353],"luv":[76.6969020797125722,30.1063672837106679,78.2959473281657523],"rgb":[0.866666666666666696,0.733333333333333282,0.133333333333333331],"xyz":[0.478763762924478919,0.510295446773293304,0.0884140576982651305],"hpluv":[68.9672438614109353,144.735860207932831,76.6969020797125722],"hsluv":[68.9672438614109353,96.3396664069398554,76.6969020797125722]},"#ddbb33":{"lch":[76.7716285455552452,80.8014056767331823,68.4347482297151828],"luv":[76.7716285455552452,29.6994133556607949,75.1452726767666093],"rgb":[0.866666666666666696,0.733333333333333282,0.2],"xyz":[0.481851513656936625,0.511530547066276431,0.104676211555876281],"hpluv":[68.4347482297151828,139.9591753538609,76.7716285455552452],"hsluv":[68.4347482297151828,92.4878111801133542,76.7716285455552452]},"#ddbb44":{"lch":[76.8793043130786771,76.4437058057830683,67.6060651816737277],"luv":[76.8793043130786771,29.122950030038453,70.6788082728408398],"rgb":[0.866666666666666696,0.733333333333333282,0.266666666666666663],"xyz":[0.486309508901155541,0.513313745163964,0.128154986508762919],"hpluv":[67.6060651816737277,133.157612926581692,76.8793043130786771],"hsluv":[67.6060651816737277,87.0382611213693167,76.8793043130786771]},"#ddbb55":{"lch":[77.0229278214451654,70.786451757311653,66.3713649049339551],"luv":[77.0229278214451654,28.3717024864450664,64.851894732620238],"rgb":[0.866666666666666696,0.733333333333333282,0.333333333333333315],"xyz":[0.492271922940517526,0.515698710779708747,0.159557033782736835],"hpluv":[66.3713649049339551,124.235507886155276,77.0229278214451654],"hsluv":[66.3713649049339551,79.9485715087726,77.0229278214451654]},"#ddbb66":{"lch":[77.2049977781888259,63.8693414267369732,64.5489675558404912],"luv":[77.2049977781888259,27.4471820183984,57.6710063509733359],"rgb":[0.866666666666666696,0.733333333333333282,0.4],"xyz":[0.499856918714025711,0.518732709089112065,0.199504678189880769],"hpluv":[64.5489675558404912,113.177180957201557,77.2049977781888259],"hsluv":[64.5489675558404912,71.2432689272834665,77.2049977781888259]},"#ddbb77":{"lch":[77.4276024714994264,55.80459657383539,61.8158033937064815],"luv":[77.4276024714994264,26.3569386858829375,49.1880552764299495],"rgb":[0.866666666666666696,0.733333333333333282,0.466666666666666674],"xyz":[0.509170931734227561,0.522458314297192916,0.248558480096278678],"hpluv":[61.8158033937064815,100.062778032150931,77.4276024714994264],"hsluv":[61.8158033937064815,61.00659046349368,77.4276024714994264]},"#ddbb88":{"lch":[77.6924726660212883,46.8021917196541537,57.5480835848938881],"luv":[77.6924726660212883,25.1136643841879952,39.4936578574539112],"rgb":[0.866666666666666696,0.733333333333333282,0.533333333333333326],"xyz":[0.520311348836171472,0.526914481137970458,0.307231343499850873],"hpluv":[57.5480835848938881,85.1204314231653285,77.6924726660212883],"hsluv":[57.5480835848938881,49.3735690170151145,77.6924726660212883]},"#ddbb99":{"lch":[78.001015952892,37.2494741955694195,50.4191367157405352],"luv":[78.001015952892,23.7341209657771088,28.7091419207933036],"rgb":[0.866666666666666696,0.733333333333333282,0.6],"xyz":[0.533368312945244116,0.532137266781599672,0.375998021140968752],"hpluv":[50.4191367157405352,68.8881727109007471,78.001015952892],"hsluv":[50.4191367157405352,37.2278198354843894,78.001015952892]},"#ddbbaa":{"lch":[78.3543411988951135,27.9779961680489,37.3601297670291643],"luv":[78.3543411988951135,22.2379488027189254,16.9776883770144309],"rgb":[0.866666666666666696,0.733333333333333282,0.66666666666666663],"xyz":[0.548426005910496728,0.538160343967700738,0.455301870757967353],"hpluv":[37.3601297670291643,52.7537881236722086,78.3543411988951135],"hsluv":[37.3601297670291643,37.9002282962103152,78.3543411988951135]},"#ddbbbb":{"lch":[78.7532777240269724,21.1216737069600953,12.1770506300632171],"luv":[78.7532777240269724,20.6464457718990104,4.45526398447083238],"rgb":[0.866666666666666696,0.733333333333333282,0.733333333333333282],"xyz":[0.565563598017833291,0.545015380810635497,0.545559855856609155],"hpluv":[12.1770506300632171,40.7192307977840144,78.7532777240269724],"hsluv":[12.1770506300632171,38.5653299871361952,78.7532777240269724]},"#ddbbcc":{"lch":[79.1983918483363425,20.8793784390591419,335.381067074864461],"luv":[79.1983918483363425,18.9814116783666442,-8.69795692664743747],"rgb":[0.866666666666666696,0.733333333333333282,0.8],"xyz":[0.584855973461555,0.552732330988124354,0.647166366526879311],"hpluv":[335.381067074864461,41.2776027841095186,79.1983918483363425],"hsluv":[335.381067074864461,39.1976988204569,79.1983918483363425]},"#ddbbdd":{"lch":[79.6900023594157858,28.2216267397768341,307.715012949250536],"luv":[79.6900023594157858,17.264138203128045,-22.325092338948604],"rgb":[0.866666666666666696,0.733333333333333282,0.866666666666666696],"xyz":[0.606374299012188644,0.56133966120837786,0.760496214426885309],"hpluv":[307.715012949250536,57.3946451248898555,79.6900023594157858],"hsluv":[307.715012949250536,39.7709084435557401,79.6900023594157858]},"#ddbbee":{"lch":[80.2281958041266,39.4567857635703447,293.154060026294076],"luv":[80.2281958041266,15.5145982189510505,-36.2785774927409221],"rgb":[0.866666666666666696,0.733333333333333282,0.933333333333333348],"xyz":[0.630186479278363354,0.570864533314847877,0.885907030495408532],"hpluv":[293.154060026294076,82.8233888781043674,80.2281958041266],"hsluv":[293.154060026294076,68.7191774169969278,80.2281958041266]},"#ddbbff":{"lch":[80.8128420975971409,52.2658591287574765,285.253756774661895],"luv":[80.8128420975971409,13.7508586713070624,-50.4245368473411],"rgb":[0.866666666666666696,0.733333333333333282,1],"xyz":[0.656357527688194775,0.581332952678780601,1.02374121878719038],"hpluv":[285.253756774661895,113.64059963508393,80.8128420975971409],"hsluv":[285.253756774661895,99.9999999999962768,80.8128420975971409]},"#664400":{"lch":[31.7142168878436834,41.7146560735594463,49.9018869072924431],"luv":[31.7142168878436834,26.8683448374877969,31.9093180282686859],"rgb":[0.4,0.266666666666666663,0],"xyz":[0.0754639898903774337,0.0695936209423669294,0.00945855895955924342],"hpluv":[49.9018869072924431,166.906788900061372,31.7142168878436834],"hsluv":[49.9018869072924431,100.000000000002103,31.7142168878436834]},"#664411":{"lch":[31.8065195391856221,38.988494662362406,47.7128576067384387],"luv":[31.8065195391856221,26.2332728657793552,28.8429906699465946],"rgb":[0.4,0.266666666666666663,0.0666666666666666657],"xyz":[0.0764756553900145519,0.0699982871422217823,0.0147866639243148749],"hpluv":[47.7128576067384387,155.546285842055198,31.8065195391856221],"hsluv":[47.7128576067384387,90.7993319288460157,31.8065195391856221]},"#664422":{"lch":[31.9766874661881033,34.3475437583520318,43.0092135947734064],"luv":[31.9766874661881033,25.116436032279772,23.4290077311931029],"rgb":[0.4,0.266666666666666663,0.133333333333333331],"xyz":[0.078351013528491581,0.0707484303976126,0.0246635501202940727],"hpluv":[43.0092135947734064,136.301783870263904,31.9766874661881033],"hsluv":[43.0092135947734064,74.6688439558526227,31.9766874661881033]},"#664433":{"lch":[32.2542649002247757,27.9288783689085562,32.9719795273007179],"luv":[32.2542649002247757,23.4305644913898661,15.1997004759998031],"rgb":[0.4,0.266666666666666663,0.2],"xyz":[0.0814387642609493145,0.0719835306905957095,0.0409257039779052159],"hpluv":[32.9719795273007179,109.876716511985933,32.2542649002247757],"hsluv":[32.9719795273007179,50.4508902462759465,32.2542649002247757]},"#664444":{"lch":[32.6494757012261942,21.7704999617243,12.1770506300622419],"luv":[32.6494757012261942,21.2806737346177428,4.59212303669972144],"rgb":[0.4,0.266666666666666663,0.266666666666666663],"xyz":[0.0858967595051681881,0.0737667287882832895,0.0644044789307918475],"hpluv":[12.1770506300622419,84.6119136876739,32.6494757012261942],"hsluv":[12.1770506300622419,19.8271939783404392,32.6494757012261942]},"#664455":{"lch":[33.1682230288457163,20.3425996427482829,337.72581918360828],"luv":[33.1682230288457163,18.8246474429619,-7.71064257201243208],"rgb":[0.4,0.266666666666666663,0.333333333333333315],"xyz":[0.0918591735445301871,0.0761516944040281224,0.0958065262047657629],"hpluv":[337.72581918360828,77.8257963773028649,33.1682230288457163],"hsluv":[337.72581918360828,26.9902218950403885,33.1682230288457163]},"#664466":{"lch":[33.8127168447387447,26.5268160416637819,307.715012949245931],"luv":[33.8127168447387447,16.2273642995468066,-20.9843898457416387],"rgb":[0.4,0.266666666666666663,0.4],"xyz":[0.0994441693180383585,0.0791856927134314409,0.135754170611909725],"hpluv":[307.715012949245931,99.5507152142919125,33.8127168447387447],"hsluv":[307.715012949245931,34.4415155187259359,33.8127168447387447]},"#664477":{"lch":[34.5819879544663067,37.1994974310500766,291.489286484323088],"luv":[34.5819879544663067,13.6271894146704895,-34.6136146303646512],"rgb":[0.4,0.266666666666666663,0.466666666666666674],"xyz":[0.108758182338240278,0.0829112979215122503,0.184807972518307634],"hpluv":[291.489286484323088,136.49804898345451,34.5819879544663067],"hsluv":[291.489286484323088,41.7425383187140824,34.5819879544663067]},"#664488":{"lch":[35.4724176022540263,49.4256461635840623,283.003444619748336],"luv":[35.4724176022540263,11.1212465051830698,-48.1582015326441066],"rgb":[0.4,0.266666666666666663,0.533333333333333326],"xyz":[0.119898599440184106,0.0873674647622898481,0.243480835921879801],"hpluv":[283.003444619748336,176.807585609029246,35.4724176022540263],"hsluv":[283.003444619748336,48.5905204317402166,35.4724176022540263]},"#664499":{"lch":[36.4782980897457563,61.9753280698008169,278.131406705371774],"luv":[36.4782980897457563,8.76603164871553453,-61.3522450974139844],"rgb":[0.4,0.266666666666666663,0.6],"xyz":[0.132955563549256806,0.092590250405919,0.312247513562997736],"hpluv":[278.131406705371774,215.5875082467536,36.4782980897457563],"hsluv":[278.131406705371774,54.8155424382278511,36.4782980897457563]},"#6644aa":{"lch":[37.5923984663849922,74.3597011725147468,275.081334091822],"luv":[37.5923984663849922,6.58602388672208239,-74.0674655150911576],"rgb":[0.4,0.266666666666666663,0.66666666666666663],"xyz":[0.148013256514509361,0.0986133275920201,0.391551363179996281],"hpluv":[275.081334091822,251.001852587777108,37.5923984663849922],"hsluv":[275.081334091822,60.3520360208115179,37.5923984663849922]},"#6644bb":{"lch":[38.8064988843830392,86.3901107279874765,273.04172423936518],"luv":[38.8064988843830392,4.58413310153298603,-86.2684006766171905],"rgb":[0.4,0.266666666666666663,0.733333333333333282],"xyz":[0.165150848621846,0.105468364434954859,0.481809348278638083],"hpluv":[273.04172423936518,282.487278503057098,38.8064988843830392],"hsluv":[273.04172423936518,65.2044789549227346,38.8064988843830392]},"#6644cc":{"lch":[40.1118623747323184,98.0126069922284415,271.608181870646],"luv":[40.1118623747323184,2.75066337520804938,-97.9740015535209],"rgb":[0.4,0.266666666666666663,0.8],"xyz":[0.184443224065567735,0.11318531461244366,0.583415858948908239],"hpluv":[271.608181870646,310.061926380003911,40.1118623747323184],"hsluv":[271.608181870646,73.249037078124374,40.1118623747323184]},"#6644dd":{"lch":[41.4996246628331491,109.23540368219534,270.561113733160255],"luv":[41.4996246628331491,1.06975602599714947,-109.230165429047204],"rgb":[0.4,0.266666666666666663,0.866666666666666696],"xyz":[0.205961549616201278,0.121792644832697194,0.696745706848914237],"hpluv":[270.561113733160255,334.009312605211903,41.4996246628331491],"hsluv":[270.561113733160255,82.0982912580276434,41.4996246628331491]},"#6644ee":{"lch":[42.9610953823040305,120.093362966476874,269.772657810053431],"luv":[42.9610953823040305,-0.476513570908160711,-120.092417593346411],"rgb":[0.4,0.266666666666666663,0.933333333333333348],"xyz":[0.229773729882376043,0.131317516939167239,0.82215652291743746],"hpluv":[269.772657810053431,354.717803858999673,42.9610953823040305],"hsluv":[269.772657810053431,90.971694410809846,42.9610953823040305]},"#6644ff":{"lch":[44.4879743720372502,130.630057251556309,269.16406595263021],"luv":[44.4879743720372502,-1.90579898569535566,-130.61615439053088],"rgb":[0.4,0.266666666666666663,1],"xyz":[0.255944778292207409,0.141785936303099935,0.959990711209219305],"hpluv":[269.16406595263021,372.597392941492103,44.4879743720372502],"hsluv":[269.16406595263021,99.9999999999993463,44.4879743720372502]},"#ddcc00":{"lch":[81.0484811072975475,89.5621409057231119,78.2088923998372394],"luv":[81.0484811072975475,18.3014975440108643,87.6723004789036224],"rgb":[0.866666666666666696,0.8,0],"xyz":[0.514100482595981623,0.585588123937282434,0.0859503143074022424],"hpluv":[78.2088923998372394,197.564965691755532,81.0484811072975475],"hsluv":[78.2088923998372394,100.000000000002245,81.0484811072975475]},"#ddcc11":{"lch":[81.070830830397739,88.588371741804238,78.1407504993947413],"luv":[81.070830830397739,18.2056357525625714,86.6974880530521261],"rgb":[0.866666666666666696,0.8,0.0666666666666666657],"xyz":[0.515112148095618783,0.585992790137137343,0.0912784192721578791],"hpluv":[78.1407504993947413,195.686226016320433,81.070830830397739],"hsluv":[78.1407504993947413,98.8754134531589699,81.070830830397739]},"#ddcc22":{"lch":[81.1122340585289265,86.7947856050049751,78.0111959233441894],"luv":[81.1122340585289265,18.0290607078827385,84.9016358983162149],"rgb":[0.866666666666666696,0.8,0.133333333333333331],"xyz":[0.516987506234095728,0.586742933392528143,0.101155305468137072],"hpluv":[78.0111959233441894,192.214732219338657,81.1122340585289265],"hsluv":[78.0111959233441894,96.8049917221618443,81.1122340585289265]},"#ddcc33":{"lch":[81.1803270736657367,83.8738846457710139,77.7882255314295747],"luv":[81.1803270736657367,17.7414783140301893,81.9760237679585089],"rgb":[0.866666666666666696,0.8,0.2],"xyz":[0.520075256966553545,0.58797803368551127,0.117417459325748208],"hpluv":[77.7882255314295747,186.530107062901806,81.1803270736657367],"hsluv":[77.7882255314295747,93.4358723678778631,81.1803270736657367]},"#ddcc44":{"lch":[81.2784695635313312,79.7261575767135469,77.443216014682],"luv":[81.2784695635313312,17.3330313363216426,77.8191893214074213],"rgb":[0.866666666666666696,0.8,0.266666666666666663],"xyz":[0.524533252210772405,0.589761231783198836,0.140896234278634847],"hpluv":[77.443216014682,178.389435414851135,81.2784695635313312],"hsluv":[77.443216014682,88.6570950843060643,81.2784695635313312]},"#ddcc55":{"lch":[81.4094229919429893,74.303525235023784,76.9333685993953509],"luv":[81.4094229919429893,16.7988406729037365,72.37964364652683],"rgb":[0.866666666666666696,0.8,0.333333333333333315],"xyz":[0.530495666250134335,0.592146197398943586,0.172298281552608762],"hpluv":[76.9333685993953509,167.620308244181615,81.4094229919429893],"hsluv":[76.9333685993953509,82.4185745103993668,81.4094229919429893]},"#ddcc66":{"lch":[81.5755062452221154,67.6049359495878406,76.1891492108976252],"luv":[81.5755062452221154,16.1384724175358123,65.6504156329288548],"rgb":[0.866666666666666696,0.8,0.4],"xyz":[0.538080662023642575,0.595180195708346904,0.212245925959752724],"hpluv":[76.1891492108976252,154.10859642349061,81.5755062452221154],"hsluv":[76.1891492108976252,74.724981631947216,81.5755062452221154]},"#ddcc77":{"lch":[81.7786782860545571,59.6741108071854,75.0887439649445554],"luv":[81.7786782860545571,15.3554995822328237,57.6646176889111857],"rgb":[0.866666666666666696,0.8,0.466666666666666674],"xyz":[0.547394675043844425,0.598905800916427755,0.261299727866150633],"hpluv":[75.0887439649445554,137.792143148878608,81.7786782860545571],"hsluv":[75.0887439649445554,65.6305091544174104,81.7786782860545571]},"#ddcc88":{"lch":[82.020587165389415,50.599662209211,73.3985048227604722],"luv":[82.020587165389415,14.4570002873895778,48.4904213054152891],"rgb":[0.866666666666666696,0.8,0.533333333333333326],"xyz":[0.558535092145788337,0.603361967757205298,0.319972591269722773],"hpluv":[73.3985048227604722,118.661765286999071,82.020587165389415],"hsluv":[73.3985048227604722,55.2326761810852389,82.020587165389415]},"#ddcc99":{"lch":[82.3026016456871901,40.5232855707982438,70.6109505258247765],"luv":[82.3026016456871901,13.4529549720920478,38.2250529884698622],"rgb":[0.866666666666666696,0.8,0.6],"xyz":[0.571592056254861,0.608584753400834511,0.388739268910840707],"hpluv":[70.6109505258247765,96.7842051030752231,82.3026016456871901],"hsluv":[70.6109505258247765,43.6647666281718685,82.3026016456871901]},"#ddccaa":{"lch":[82.6258332993788542,29.6818113573176419,65.4008685536862231],"luv":[82.6258332993788542,12.3555588351715961,26.9879619705157374],"rgb":[0.866666666666666696,0.8,0.66666666666666663],"xyz":[0.586649749220113592,0.614607830586935577,0.468043118527839308],"hpluv":[65.4008685536862231,72.4135107626852,82.6258332993788542],"hsluv":[65.4008685536862231,31.0871436920773085,82.6258332993788542]},"#ddccbb":{"lch":[82.9911533066729419,18.6379527757414252,53.1465475992889],"luv":[82.9911533066729419,11.1784915779275345,14.9135713265793797],"rgb":[0.866666666666666696,0.8,0.733333333333333282],"xyz":[0.603787341327450156,0.621462867429870336,0.55830110362648111],"hpluv":[53.1465475992889,46.5946179098545272,82.9911533066729419],"hsluv":[53.1465475992889,24.678645774572626,82.9911533066729419]},"#ddcccc":{"lch":[83.3992063850657,10.164901186858037,12.1770506300648638],"luv":[83.3992063850657,9.93619558955776228,2.14411598208697862],"rgb":[0.866666666666666696,0.8,0.8],"xyz":[0.62307971677117191,0.629179817607359193,0.659907614296751266],"hpluv":[12.1770506300648638,26.1289592314662436,83.3992063850657],"hsluv":[12.1770506300648638,25.0002112827592455,83.3992063850657]},"#ddccdd":{"lch":[83.8504233095379163,14.1290270468723165,307.715012949259346],"luv":[83.8504233095379163,8.64321103323171513,-11.1769543403501022],"rgb":[0.866666666666666696,0.8,0.866666666666666696],"xyz":[0.644598042321805509,0.637787147827612699,0.773237462196757264],"hpluv":[307.715012949259346,37.4791950150616557,83.8504233095379163],"hsluv":[307.715012949259346,25.214872966603707,83.8504233095379163]},"#ddccee":{"lch":[84.3450329093034,25.9620569722210597,286.361909425528779],"luv":[84.3450329093034,7.31360586969829818,-24.9106316943502399],"rgb":[0.866666666666666696,0.8,0.933333333333333348],"xyz":[0.668410222587980218,0.647312019934082716,0.898648278265280487],"hpluv":[286.361909425528779,71.3464154396222199,84.3450329093034],"hsluv":[286.361909425528779,60.879598082714125,84.3450329093034]},"#ddccff":{"lch":[84.8830740665913623,39.380529428060008,278.705583312848262],"luv":[84.8830740665913623,5.96052452183370107,-38.926831947371717],"rgb":[0.866666666666666696,0.8,1],"xyz":[0.694581270997811639,0.65778043929801544,1.03648246655706222],"hpluv":[278.705583312848262,112.590543218900592,84.8830740665913623],"hsluv":[278.705583312848262,99.9999999999947704,84.8830740665913623]},"#665500":{"lch":[36.5970311204425656,41.5054710368830655,69.2006364019199651],"luv":[36.5970311204425656,14.7384507745119784,38.800543743107859],"rgb":[0.4,0.333333333333333315,0],"xyz":[0.0872772466047234,0.0932201343710592,0.0133963111976744542],"hpluv":[69.2006364019199651,143.912599562803223,36.5970311204425656],"hsluv":[69.2006364019199651,100.000000000002359,36.5970311204425656]},"#665511":{"lch":[36.673028710438345,38.8606023214232366,68.2658014049057869],"luv":[36.673028710438345,14.3901304021596417,36.0980686435250391],"rgb":[0.4,0.333333333333333315,0.0666666666666666657],"xyz":[0.0882889121043605174,0.0936248005709140463,0.0187244161624300839],"hpluv":[68.2658014049057869,134.462776824764262,36.673028710438345],"hsluv":[68.2658014049057869,93.0449405246809107,36.673028710438345]},"#665522":{"lch":[36.8133307706753357,34.1687527519613923,66.2355675996872719],"luv":[36.8133307706753357,13.769229594380441,31.2715842419585037],"rgb":[0.4,0.333333333333333315,0.133333333333333331],"xyz":[0.0901642702428375464,0.0943749438263048607,0.0286013023584092835],"hpluv":[66.2355675996872719,117.777773408929676,36.8133307706753357],"hsluv":[66.2355675996872719,80.6853283069105629,36.8133307706753357]},"#665533":{"lch":[37.0427251812615097,27.0303271109949854,61.7081001991288645],"luv":[37.0427251812615097,12.8113945713483854,23.8014023297917383],"rgb":[0.4,0.333333333333333315,0.2],"xyz":[0.09325202097529528,0.0956100441192879735,0.0448634562160204267],"hpluv":[61.7081001991288645,92.5950345984193177,37.0427251812615097],"hsluv":[61.7081001991288645,61.7209513910547045,37.0427251812615097]},"#665544":{"lch":[37.3704580906404473,18.1024774089589755,50.3425610862832542],"luv":[37.3704580906404473,11.5529306171195891,13.9366237840407656],"rgb":[0.4,0.333333333333333315,0.266666666666666663],"xyz":[0.0977100162195141536,0.0973932422169755535,0.0683422311689070583],"hpluv":[50.3425610862832542,61.4679768710498351,37.3704580906404473],"hsluv":[50.3425610862832542,37.0117339514184067,37.3704580906404473]},"#665555":{"lch":[37.8025949068387348,10.2943047784276782,12.1770506300631105],"luv":[37.8025949068387348,10.0626876598879917,2.1714115065313786],"rgb":[0.4,0.333333333333333315,0.333333333333333315],"xyz":[0.103672430258876153,0.0997782078327203864,0.0997442784428809737],"hpluv":[12.1770506300631105,34.5553054430909654,37.8025949068387348],"hsluv":[12.1770506300631105,8.09737912949257321,37.8025949068387348]},"#665566":{"lch":[38.3424918197480693,13.7697499972876347,307.715012949250308],"luv":[38.3424918197480693,8.42342892447929,-10.8927434626015351],"rgb":[0.4,0.333333333333333315,0.4],"xyz":[0.111257426032384324,0.102812206142123705,0.139691922850024935],"hpluv":[307.715012949250308,45.570631638882567,38.3424918197480693],"hsluv":[307.715012949250308,15.7660506346962208,38.3424918197480693]},"#665577":{"lch":[38.9911218270375812,25.5692820710091411,285.225395910208761],"luv":[38.9911218270375812,6.71492531026355,-24.671805035392353],"rgb":[0.4,0.333333333333333315,0.466666666666666674],"xyz":[0.120571439052586243,0.106537811350204514,0.188745724756422845],"hpluv":[285.225395910208761,83.2131821356252885,38.9911218270375812],"hsluv":[285.225395910208761,23.5948697041559434,38.9911218270375812]},"#665588":{"lch":[39.7473800461840554,39.003702064123587,277.369365694294345],"luv":[39.7473800461840554,5.00282395952989312,-38.6815269493963],"rgb":[0.4,0.333333333333333315,0.533333333333333326],"xyz":[0.131711856154530071,0.110993978190982112,0.247418588159995],"hpluv":[277.369365694294345,124.519293959659265,39.7473800461840554],"hsluv":[277.369365694294345,31.2388068533835614,39.7473800461840554]},"#665599":{"lch":[40.6084045881889466,52.6763518020623636,273.629018089310307],"luv":[40.6084045881889466,3.33420095564239061,-52.5707251534733189],"rgb":[0.4,0.333333333333333315,0.6],"xyz":[0.144768820263602771,0.11621676383461127,0.316185265801112947],"hpluv":[273.629018089310307,164.603508765513965,40.6084045881889466],"hsluv":[273.629018089310307,39.2894117268144569,40.6084045881889466]},"#6655aa":{"lch":[41.5699140891343575,66.1399121177165,271.505962745252077],"luv":[41.5699140891343575,1.73822184255944534,-66.1170670838121168],"rgb":[0.4,0.333333333333333315,0.66666666666666663],"xyz":[0.159826513228855327,0.122239841020712364,0.395489115418111492],"hpluv":[271.505962745252077,201.894186201954597,41.5699140891343575],"hsluv":[271.505962745252077,49.6682832978127067,41.5699140891343575]},"#6655bb":{"lch":[42.6265484117568647,79.2031960637105499,270.166039680829499],"luv":[42.6265484117568647,0.229525718995523903,-79.2028634876978],"rgb":[0.4,0.333333333333333315,0.733333333333333282],"xyz":[0.176964105336191974,0.129094877863647123,0.485747100516753294],"hpluv":[270.166039680829499,235.777232293519603,42.6265484117568647],"hsluv":[270.166039680829499,59.8653820834470309,42.6265484117568647]},"#6655cc":{"lch":[43.7721949853351333,91.7929775852419,269.258674658723919],"luv":[43.7721949853351333,-1.18763654850412936,-91.7852943199147688],"rgb":[0.4,0.333333333333333315,0.8],"xyz":[0.1962564807799137,0.136811828041135924,0.58735361118702345],"hpluv":[269.258674658723919,266.103421792879146,43.7721949853351333],"hsluv":[269.258674658723919,69.9112236392489734,43.7721949853351333]},"#6655dd":{"lch":[45.0002850881211458,103.899953671233533,268.61259940679895],"luv":[45.0002850881211458,-2.51566121975990953,-103.869494181457682],"rgb":[0.4,0.333333333333333315,0.866666666666666696],"xyz":[0.217774806330547244,0.145419158261389458,0.700683459087029448],"hpluv":[268.61259940679895,292.98097185143456,45.0002850881211458],"hsluv":[268.61259940679895,79.8793625185682714,45.0002850881211458]},"#6655ee":{"lch":[46.3040490971424106,115.549020689755764,268.134901078425969],"luv":[46.3040490971424106,-3.7607010001107648,-115.487805894602445],"rgb":[0.4,0.333333333333333315,0.933333333333333348],"xyz":[0.241586986596722,0.154944030367859503,0.826094275155552671],"hpluv":[268.134901078425969,316.655201018988919,46.3040490971424106],"hsluv":[268.134901078425969,89.8701820385079344,46.3040490971424106]},"#6655ff":{"lch":[47.6767252326213651,126.781348408818275,267.771145841725911],"luv":[47.6767252326213651,-4.93065761335473951,-126.685432942615918],"rgb":[0.4,0.333333333333333315,1],"xyz":[0.267758035006553374,0.165412449731792199,0.963928463447334516],"hpluv":[267.771145841725911,337.433561350206048,47.6767252326213651],"hsluv":[267.771145841725911,99.9999999999992468,47.6767252326213651]},"#dddd00":{"lch":[85.547159878993142,94.3072427966830844,85.8743202181747449],"luv":[85.547159878993142,6.78488618903739749,94.0628585750738466],"rgb":[0.866666666666666696,0.866666666666666696,0],"xyz":[0.556734473143156827,0.670856105031634,0.100161644489793561],"hpluv":[85.8743202181747449,283.614606809988061,85.547159878993142],"hsluv":[85.8743202181747449,100.000000000002203,85.547159878993142]},"#dddd11":{"lch":[85.5675738163798627,93.4011806547303394,85.8743202181746881],"luv":[85.5675738163798627,6.71970001318247423,93.159144368282],"rgb":[0.866666666666666696,0.866666666666666696,0.0666666666666666657],"xyz":[0.557746138642794,0.671260771231488862,0.105489749454549198],"hpluv":[85.8743202181746881,281.335749103468061,85.5675738163798627],"hsluv":[85.8743202181746881,99.0156164862488,85.5675738163798627]},"#dddd22":{"lch":[85.6053941241358558,91.7307060091609401,85.8743202181746739],"luv":[85.6053941241358558,6.59951857201479086,91.4929985275198447],"rgb":[0.866666666666666696,0.866666666666666696,0.133333333333333331],"xyz":[0.559621496781270933,0.672010914486879662,0.11536663565052839],"hpluv":[85.8743202181746739,277.118842420723468,85.6053941241358558],"hsluv":[85.8743202181746739,97.2017654403352083,85.6053941241358558]},"#dddd33":{"lch":[85.667603455332241,89.0058006932873,85.8743202181745602],"luv":[85.667603455332241,6.4034766573555908,88.775154428206335],"rgb":[0.866666666666666696,0.866666666666666696,0.2],"xyz":[0.56270924751372875,0.673246014779862789,0.131628789508139526],"hpluv":[85.8743202181745602,270.196330508983522,85.667603455332241],"hsluv":[85.8743202181745602,94.2458512979473113,85.667603455332241]},"#dddd44":{"lch":[85.7572852094861418,85.1265937151141117,85.8743202181744607],"luv":[85.7572852094861418,6.12438910193468278,84.9059998802570419],"rgb":[0.866666666666666696,0.866666666666666696,0.266666666666666663],"xyz":[0.567167242757947609,0.675029212877550355,0.155107564461026165],"hpluv":[85.8743202181744607,260.24482525674506,85.7572852094861418],"hsluv":[85.8743202181744607,90.0440000232135844,85.7572852094861418]},"#dddd55":{"lch":[85.8769849033878074,80.0369945631262,85.874320218174276],"luv":[85.8769849033878074,5.75822050268421481,79.8295897229865545],"rgb":[0.866666666666666696,0.866666666666666696,0.333333333333333315],"xyz":[0.573129656797309539,0.677414178493295105,0.18650961173500008],"hpluv":[85.874320218174276,247.008869171162701,85.8769849033878074],"hsluv":[85.874320218174276,84.5423921226573327,85.8769849033878074]},"#dddd66":{"lch":[86.0288537292730098,73.7198014533942398,85.8743202181739775],"luv":[86.0288537292730098,5.30373328608645522,73.5287667485177252],"rgb":[0.866666666666666696,0.866666666666666696,0.4],"xyz":[0.58071465257081778,0.680448176802698423,0.226457256142144042],"hpluv":[85.8743202181739775,230.281095596483937,86.0288537292730098],"hsluv":[85.8743202181739775,77.7321300368988,86.0288537292730098]},"#dddd77":{"lch":[86.2147251389940834,66.1931358813644124,85.8743202181736365],"luv":[86.2147251389940834,4.76223119383214133,66.0216054929389315],"rgb":[0.866666666666666696,0.866666666666666696,0.466666666666666674],"xyz":[0.59002866559101963,0.684173782010779274,0.275511058048541924],"hpluv":[85.8743202181736365,209.886373280136951,86.2147251389940834],"hsluv":[85.8743202181736365,69.6453389130317362,86.2147251389940834]},"#dddd88":{"lch":[86.4361603707972,57.5066396271378224,85.8743202181730823],"luv":[86.4361603707972,4.13728567831694072,57.3576190965201391],"rgb":[0.866666666666666696,0.866666666666666696,0.533333333333333326],"xyz":[0.601169082692963541,0.688629948851556817,0.334183921452114119],"hpluv":[85.8743202181730823,185.665493576193455,86.4361603707972],"hsluv":[85.8743202181730823,60.3508056243124429,86.4361603707972]},"#dddd99":{"lch":[86.6944777431662,47.7369558995854888,85.8743202181722154],"luv":[86.6944777431662,3.43441079587341314,47.613252157820078],"rgb":[0.866666666666666696,0.866666666666666696,0.6],"xyz":[0.614226046802036185,0.693852734495186,0.402950599093232054],"hpluv":[85.8743202181722154,157.456397081560084,86.6944777431662],"hsluv":[85.8743202181722154,49.9486591868920939,86.6944777431662]},"#ddddaa":{"lch":[86.990772885999732,36.9824894935128,85.874320218170638],"luv":[86.990772885999732,2.66068622896724838,36.886654469181245],"rgb":[0.866666666666666696,0.866666666666666696,0.66666666666666663],"xyz":[0.629283739767288797,0.699875811681287097,0.482254448710230599],"hpluv":[85.874320218170638,125.071764704863014,86.990772885999732],"hsluv":[85.874320218170638,38.5641267001819443,86.990772885999732]},"#ddddbb":{"lch":[87.3259337660435477,25.3576808227713499,85.8743202181676821],"luv":[87.3259337660435477,1.82434533444747116,25.2919698878957568],"rgb":[0.866666666666666696,0.866666666666666696,0.733333333333333282],"xyz":[0.64642133187462536,0.706730848524221855,0.572512433808872401],"hpluv":[85.8743202181676821,88.2719508819342735,87.3259337660435477],"hsluv":[85.8743202181676821,26.340671416181145,87.3259337660435477]},"#ddddcc":{"lch":[87.7006527393466797,12.9871390430395461,85.8743202181585445],"luv":[87.7006527393466797,0.934353054076054512,12.9534846621895881],"rgb":[0.866666666666666696,0.866666666666666696,0.8],"xyz":[0.665713707318347114,0.714447798701710712,0.674118944479142557],"hpluv":[85.8743202181585445,46.7319159493201113,87.7006527393466797],"hsluv":[85.8743202181585445,13.4329442518860063,87.7006527393466797]},"#dddddd":{"lch":[88.1154369871094,4.67545248961294327e-12,0],"luv":[88.1154369871094,4.4193702762792188e-12,1.52611347670073729e-12],"rgb":[0.866666666666666696,0.866666666666666696,0.866666666666666696],"xyz":[0.687232032868980713,0.723055128921964219,0.787448792379148554],"hpluv":[0,1.74708563976297451e-11,88.1154369871094],"hsluv":[0,1.74437740136320375e-11,88.1154369871094]},"#ddddee":{"lch":[88.5706181797242209,13.4751686036456029,265.874320218195521],"luv":[88.5706181797242209,-0.969464090371862097,-13.4402495614536726],"rgb":[0.866666666666666696,0.866666666666666696,0.933333333333333348],"xyz":[0.711044213135155423,0.732580001028434236,0.912859608447671778],"hpluv":[265.874320218195521,52.5550848411252431,88.5706181797242209],"hsluv":[265.874320218195521,47.1269490590101725,88.5706181797242209]},"#ddddff":{"lch":[89.0663618949558753,27.3146757005029208,265.874320218186369],"luv":[89.0663618949558753,-1.9651403266809826,-27.2438934831293338],"rgb":[0.866666666666666696,0.866666666666666696,1],"xyz":[0.737215261544986844,0.743048420392367,1.05069379673945362],"hpluv":[265.874320218186369,111.815120511018762,89.0663618949558753],"hsluv":[265.874320218186369,99.9999999999922125,89.0663618949558753]},"#666600":{"lch":[41.7321583215394583,46.0055575524193685,85.8743202181747449],"luv":[41.7321583215394583,3.30984623025532709,45.8863404908370924],"rgb":[0.4,0.4,0],"xyz":[0.102305304310569861,0.123276249782752534,0.0184056637662898],"hpluv":[85.8743202181747449,139.887458074797365,41.7321583215394583],"hsluv":[85.8743202181747449,100.000000000002203,41.7321583215394583]},"#666611":{"lch":[41.7952597887023742,43.6298127640598423,85.8743202181746],"luv":[41.7952597887023742,3.13892449057558931,43.5167521176544625],"rgb":[0.4,0.4,0.0666666666666666657],"xyz":[0.103316969810206979,0.123680915982607387,0.0237337687310454348],"hpluv":[85.8743202181746,132.463323325332908,41.7952597887023742],"hsluv":[85.8743202181746,94.6927802880713756,41.7952597887023742]},"#666622":{"lch":[41.9118699845736913,39.3503176022612067,85.874320218174276],"luv":[41.9118699845736913,2.83103840719259514,39.248346677737],"rgb":[0.4,0.4,0.133333333333333331],"xyz":[0.105192327948684008,0.124431059237998201,0.0336106549270246274],"hpluv":[85.874320218174276,119.138061739500813,41.9118699845736913],"hsluv":[85.874320218174276,85.1670788640685288,41.9118699845736913]},"#666633":{"lch":[42.1028501842444953,32.6344620115447057,85.8743202181736507],"luv":[42.1028501842444953,2.34786962297492563,32.5498943011565842],"rgb":[0.4,0.4,0.2],"xyz":[0.108280078681141742,0.125666159530981314,0.0498728087846357776],"hpluv":[85.8743202181736507,98.3567766096709306,42.1028501842444953],"hsluv":[85.8743202181736507,70.3113616926845,42.1028501842444953]},"#666644":{"lch":[42.3763861696741557,23.5947988734222314,85.8743202181723575],"luv":[42.3763861696741557,1.69751569722617934,23.5336562041455402],"rgb":[0.4,0.4,0.266666666666666663],"xyz":[0.112738073925360616,0.127449357628668908,0.0733515837375224161],"hpluv":[85.8743202181723575,70.6531759312171346,42.3763861696741557],"hsluv":[85.8743202181723575,50.5071554688203506,42.3763861696741557]},"#666655":{"lch":[42.7382714661199543,12.562340839470254,85.87432021816781],"luv":[42.7382714661199543,0.903791165304248856,12.5297872646162745],"rgb":[0.4,0.4,0.333333333333333315],"xyz":[0.118700487964722615,0.129834323244413741,0.104753631011496318],"hpluv":[85.87432021816781,37.2986356199978459,42.7382714661199543],"hsluv":[85.87432021816781,26.6633164497530721,42.7382714661199543]},"#666666":{"lch":[43.1922895629847048,2.27708065554704512e-12,0],"luv":[43.1922895629847048,2.15069538500574498e-12,7.48067960001998255e-13],"rgb":[0.4,0.4,0.4],"xyz":[0.126285483738230786,0.132868321553817031,0.144701275418640279],"hpluv":[0,6.68977504875838914e-12,43.1922895629847048],"hsluv":[0,1.91542116883063395e-12,43.1922895629847048]},"#666677":{"lch":[43.7404449074606489,13.5883126365404472,265.874320218186085],"luv":[43.7404449074606489,-0.977604179760566572,-13.5531003971814314],"rgb":[0.4,0.4,0.466666666666666674],"xyz":[0.135599496758432692,0.136593926761897855,0.193755077325038189],"hpluv":[265.874320218186085,39.4204575510779804,43.7404449074606489],"hsluv":[265.874320218186085,10.3527957183817456,43.7404449074606489]},"#666688":{"lch":[44.3831523723879684,27.7327571842679852,265.874320218181708],"luv":[44.3831523723879684,-1.9952189844931838,-27.660891566352042],"rgb":[0.4,0.4,0.533333333333333326],"xyz":[0.146739913860376547,0.141050093602675453,0.252427940728610356],"hpluv":[265.874320218181708,79.2892354857961692,44.3831523723879684],"hsluv":[265.874320218181708,21.2254167484079588,44.3831523723879684]},"#666699":{"lch":[45.1194249231942308,42.0446421145154,265.87432021818023],"luv":[45.1194249231942308,-3.02488020162380478,-41.9356892193690598],"rgb":[0.4,0.4,0.6],"xyz":[0.159796877969449247,0.14627287924630461,0.321194618369728291],"hpluv":[265.87432021818023,118.245992523098394,45.1194249231942308],"hsluv":[265.87432021818023,32.3647541960069702,45.1194249231942308]},"#6666aa":{"lch":[45.9470714788517682,56.2348015337582652,265.874320218179548],"luv":[45.9470714788517682,-4.04578393932889835,-56.0890767962662125],"rgb":[0.4,0.4,0.66666666666666663],"xyz":[0.174854570934701803,0.152295956432405705,0.400498467986726892],"hpluv":[265.874320218179548,155.305436018888514,45.9470714788517682],"hsluv":[265.874320218179548,43.5990379455573205,45.9470714788517682]},"#6666bb":{"lch":[46.8629040956598786,70.1103551977131,265.874320218179093],"luv":[46.8629040956598786,-5.04405352741049562,-69.9286738753289541],"rgb":[0.4,0.4,0.733333333333333282],"xyz":[0.191992163042038422,0.159150993275340463,0.490756453085368638],"hpluv":[265.874320218179093,189.841997809706953,46.8629040956598786],"hsluv":[265.874320218179093,54.8353857399755285,46.8629040956598786]},"#6666cc":{"lch":[47.8629477245616854,83.5592716582008,265.874320218178866],"luv":[47.8629477245616854,-6.01162892081844,-83.3427393224351505],"rgb":[0.4,0.4,0.8],"xyz":[0.211284538485760176,0.166867943452829265,0.592362963755638794],"hpluv":[265.874320218178866,221.531011478982748,47.8629477245616854],"hsluv":[265.874320218178866,66.0482344892977693,47.8629477245616854]},"#6666dd":{"lch":[48.9426439028117102,96.5306872715973583,265.874320218178696],"luv":[48.9426439028117102,-6.94485076081307,-96.2805413000828736],"rgb":[0.4,0.4,0.866666666666666696],"xyz":[0.23280286403639372,0.175475273673082799,0.705692811655644792],"hpluv":[265.874320218178696,250.274901054084751,48.9426439028117102],"hsluv":[265.874320218178696,77.2646968282616911,48.9426439028117102]},"#6666ee":{"lch":[50.0970402589656203,109.016062738443594,265.874320218178525],"luv":[50.0970402589656203,-7.84310469187671711,-108.73356263723052],"rgb":[0.4,0.4,0.933333333333333348],"xyz":[0.256615044302568429,0.185000145779552844,0.831103627724168],"hpluv":[265.874320218178525,276.132643737939816,50.0970402589656203],"hsluv":[265.874320218178525,88.5507283896609181,50.0970402589656203]},"#6666ff":{"lch":[51.3209595583197142,121.033610519319112,265.874320218178411],"luv":[51.3209595583197142,-8.70770100014002502,-120.719968599376287],"rgb":[0.4,0.4,1],"xyz":[0.28278609271239985,0.19546856514348554,0.96893781601594986],"hpluv":[265.874320218178411,299.261292593223402,51.3209595583197142],"hsluv":[265.874320218178411,99.9999999999991616,51.3209595583197142]},"#ddee00":{"lch":[90.1008574130140261,100.518542770188731,92.3281002120423295],"luv":[90.1008574130140261,-4.08324753875312307,100.435574027231638],"rgb":[0.866666666666666696,0.933333333333333348,0],"xyz":[0.603913249483671644,0.765213657712664919,0.115887903269964759],"hpluv":[92.3281002120423295,458.324419080212692,90.1008574130140261],"hsluv":[92.3281002120423295,100.000000000002288,90.1008574130140261]},"#ddee11":{"lch":[90.1195571422023676,99.6821059706602739,92.3717344777628284],"luv":[90.1195571422023676,-4.12512016496088219,99.5967149778072667],"rgb":[0.866666666666666696,0.933333333333333348,0.0666666666666666657],"xyz":[0.604924914983308804,0.765618323912519827,0.121216008234720396],"hpluv":[92.3717344777628284,455.439701471196656,90.1195571422023676],"hsluv":[92.3717344777628284,99.1349582088955827,90.1195571422023676]},"#ddee22":{"lch":[90.1542040339558213,98.139145338163118,92.4541942657322409],"luv":[90.1542040339558213,-4.20238430415396635,98.0491295925940562],"rgb":[0.866666666666666696,0.933333333333333348,0.133333333333333331],"xyz":[0.606800273121785749,0.766368467167910628,0.131092894430699575],"hpluv":[92.4541942657322409,450.094002053356689,90.1542040339558213],"hsluv":[92.4541942657322409,97.539848527320828,90.1542040339558213]},"#ddee33":{"lch":[90.2112004280082402,95.6198982889531237,92.5945991605726562],"luv":[90.2112004280082402,-4.32860020636881337,95.5218727257959728],"rgb":[0.866666666666666696,0.933333333333333348,0.2],"xyz":[0.609888023854243566,0.767603567460893754,0.147355048288310725],"hpluv":[92.5945991605726562,441.296742170845221,90.2112004280082402],"hsluv":[92.5945991605726562,94.9371734060285348,90.2112004280082402]},"#ddee44":{"lch":[90.2933822328294582,92.028546743238266,92.808164678773025],"luv":[90.2933822328294582,-4.50867173729536486,91.9180357429253689],"rgb":[0.866666666666666696,0.933333333333333348,0.266666666666666663],"xyz":[0.614346019098462426,0.76938676555858132,0.170833823241197363],"hpluv":[92.808164678773025,428.602609406071736,90.2933822328294582],"hsluv":[92.808164678773025,91.2305485856041827,90.2933822328294582]},"#ddee55":{"lch":[90.4030992965535,87.3081168904988658,93.1158428735316477],"luv":[90.4030992965535,-4.74562541158387852,87.1790474507375137],"rgb":[0.866666666666666696,0.933333333333333348,0.333333333333333315],"xyz":[0.620308433137824355,0.77177173117432607,0.202235870515171279],"hpluv":[93.1158428735316477,411.63119840797242,90.4030992965535],"hsluv":[93.1158428735316477,86.365058197250562,90.4030992965535]},"#ddee66":{"lch":[90.5423480313319828,81.4363754503924,93.5488244177654451],"luv":[90.5423480313319828,-5.04083628618753,81.2802141731499717],"rgb":[0.866666666666666696,0.933333333333333348,0.4],"xyz":[0.627893428911332596,0.774805729483729388,0.242183514922315241],"hpluv":[93.5488244177654451,390.03815237863023,90.5423480313319828],"hsluv":[93.5488244177654451,80.3228278296054583,90.5423480313319828]},"#ddee77":{"lch":[90.7128424721769449,74.4235139877598613,94.1564113073248],"luv":[90.7128424721769449,-5.39417557361030209,74.2277731322134855],"rgb":[0.866666666666666696,0.933333333333333348,0.466666666666666674],"xyz":[0.637207441931534446,0.77853133469181024,0.291237316828713122],"hpluv":[94.1564113073248,363.492124647987794,90.7128424721769449],"hsluv":[94.1564113073248,73.1200108954656116,90.7128424721769449]},"#ddee88":{"lch":[90.9160566530372449,66.3104835404903099,95.0215233218939801],"luv":[90.9160566530372449,-5.80415396856009735,66.0559764448523197],"rgb":[0.866666666666666696,0.933333333333333348,0.533333333333333326],"xyz":[0.648347859033478358,0.782987501532587782,0.349910180232285317],"hpluv":[95.0215233218939801,331.65301907995223,90.9160566530372449],"hsluv":[95.0215233218939801,64.803658473982523,90.9160566530372449]},"#ddee99":{"lch":[91.1532518637430798,57.1683554138076389,96.2947128608995513],"luv":[91.1532518637430798,-6.26808654843775237,56.8236918172404799],"rgb":[0.866666666666666696,0.933333333333333348,0.6],"xyz":[0.661404823142551,0.788210287176217,0.418676857873403252],"hpluv":[96.2947128608995513,294.152965661212647,91.1532518637430798],"hsluv":[96.2947128608995513,55.4479539090275679,91.1532518637430798]},"#ddeeaa":{"lch":[91.4254953447680805,47.1012792006961263,98.2790075719046712],"luv":[91.4254953447680805,-6.78228473243696595,46.6104185365255219],"rgb":[0.866666666666666696,0.933333333333333348,0.66666666666666663],"xyz":[0.676462516107803613,0.794233364362318062,0.497980707490401797],"hpluv":[98.2790075719046712,250.593114601078071,91.4254953447680805],"hsluv":[98.2790075719046712,45.1497304611624699,91.4254953447680805]},"#ddeebb":{"lch":[91.7336739482950634,36.2629153409390739,101.681625346389353],"luv":[91.7336739482950634,-7.34227032126066,35.5118303605101318],"rgb":[0.866666666666666696,0.933333333333333348,0.733333333333333282],"xyz":[0.693600108215140176,0.80108840120525282,0.588238692589043599],"hpluv":[101.681625346389353,200.613962446551909,91.7336739482950634],"hsluv":[101.681625346389353,34.0234190840686495,91.7336739482950634]},"#ddeecc":{"lch":[92.0785048140775189,24.9340669502590622,108.575873850927678],"luv":[92.0785048140775189,-7.94300120518182506,23.6350677285782567],"rgb":[0.866666666666666696,0.933333333333333348,0.8],"xyz":[0.712892483658861931,0.808805351382741677,0.689845203259313755],"hpluv":[108.575873850927678,144.339382081965653,92.0785048140775189],"hsluv":[108.575873850927678,22.1956929245148693,92.0785048140775189]},"#ddeedd":{"lch":[92.4605443140240908,14.0242187757329084,127.71501294922345],"luv":[92.4605443140240908,-8.57909621466854766,11.0940443666446207],"rgb":[0.866666666666666696,0.933333333333333348,0.866666666666666696],"xyz":[0.73441080920949553,0.817412681602995184,0.803175051159319753],"hpluv":[127.71501294922345,85.5555802205660854,92.4605443140240908],"hsluv":[127.71501294922345,19.0167034911391681,92.4605443140240908]},"#ddeeee":{"lch":[92.8801960589335636,9.45784403502816851,192.177050630058346],"luv":[92.8801960589335636,-9.24504689815110403,-1.99497409554724747],"rgb":[0.866666666666666696,0.933333333333333348,0.933333333333333348],"xyz":[0.758222989475670239,0.826937553709465201,0.928585867227843],"hpluv":[192.177050630058346,61.3009405779386327,92.8801960589335636],"hsluv":[192.177050630058346,16.5065503962475049,92.8801960589335636]},"#ddeeff":{"lch":[93.3377184761608305,18.4254994321377019,237.36941304521946],"luv":[93.3377184761608305,-9.93540601395951306,-15.5173044263971267],"rgb":[0.866666666666666696,0.933333333333333348,1],"xyz":[0.78439403788550166,0.837405973073397925,1.06642005551962482],"hpluv":[237.36941304521946,128.083838047846456,93.3377184761608305],"hsluv":[237.36941304521946,99.9999999999860592,93.3377184761608305]},"#667700":{"lch":[46.9985837429297462,53.5023535392226,97.7743932102929705],"luv":[46.9985837429297462,-7.23741162388150272,53.0105810873873509],"rgb":[0.4,0.466666666666666674,0],"xyz":[0.12075904236398749,0.160183725889588319,0.0245569097840955056],"hpluv":[97.7743932102929705,144.453291553004675,46.9985837429297462],"hsluv":[97.7743932102929705,100.000000000002416,46.9985837429297462]},"#667711":{"lch":[47.0515894602548315,51.4525286527524344,98.1592061252685681],"luv":[47.0515894602548315,-7.3023584206057679,50.9317019768564],"rgb":[0.4,0.466666666666666674,0.0666666666666666657],"xyz":[0.121770707863624608,0.160588392089443172,0.0298850147488511353],"hpluv":[98.1592061252685681,138.762383385982389,47.0515894602548315],"hsluv":[98.1592061252685681,95.8888552433840573,47.0515894602548315]},"#667722":{"lch":[47.1496128779850068,47.7434140964333835,98.9413563019921],"luv":[47.1496128779850068,-7.4204465613794337,47.1632331632727],"rgb":[0.4,0.466666666666666674,0.133333333333333331],"xyz":[0.123646066002101637,0.161338535344834,0.0397619009448303348],"hpluv":[98.9413563019921,128.491579290861381,47.1496128779850068],"hsluv":[98.9413563019921,88.4562635009272071,47.1496128779850068]},"#667733":{"lch":[47.3103471969426579,41.884713336750373,100.466311561708949],"luv":[47.3103471969426579,-7.6086666810921777,41.1878307590699961],"rgb":[0.4,0.466666666666666674,0.2],"xyz":[0.126733816734559357,0.162573635637817099,0.0560240548024414781],"hpluv":[100.466311561708949,112.341117260385403,47.3103471969426579],"hsluv":[100.466311561708949,76.7252257071794,47.3103471969426579]},"#667744":{"lch":[47.5409803755201068,33.9506682862991624,103.399633201782777],"luv":[47.5409803755201068,-7.86778476785512915,33.0264415269496823],"rgb":[0.4,0.466666666666666674,0.266666666666666663],"xyz":[0.131191811978778244,0.164356833735504693,0.0795028297553281166],"hpluv":[103.399633201782777,90.6190532449782324,47.5409803755201068],"hsluv":[103.399633201782777,60.8161329795325543,47.5409803755201068]},"#667755":{"lch":[47.8468512336942808,24.3055974565694441,109.700167733355244],"luv":[47.8468512336942808,-8.19336864569332768,22.8829800934354815],"rgb":[0.4,0.466666666666666674,0.333333333333333315],"xyz":[0.137154226018140257,0.166741799351249526,0.110904877029302018],"hpluv":[109.700167733355244,64.4602914823941262,47.8468512336942808],"hsluv":[109.700167733355244,41.23982633361328,47.8468512336942808]},"#667766":{"lch":[48.2317738399223543,14.0211946941261125,127.715012949232488],"luv":[48.2317738399223543,-8.57724628010491408,11.0916521267580634],"rgb":[0.4,0.466666666666666674,0.4],"xyz":[0.144739221791648415,0.169775797660652816,0.15085252143644598],"hpluv":[127.715012949232488,36.8885098590324958,48.2317738399223543],"hsluv":[127.715012949232488,18.7828263722028552,48.2317738399223543]},"#667777":{"lch":[48.6982180758881356,9.21652694043341,192.177050630059739],"luv":[48.6982180758881356,-9.00915932709454736,-1.94407228846053126],"rgb":[0.4,0.466666666666666674,0.466666666666666674],"xyz":[0.154053234811850348,0.17350140286873364,0.199906323342843889],"hpluv":[192.177050630059739,24.0156061835451808,48.6982180758881356],"hsluv":[192.177050630059739,23.9216020554503501,48.6982180758881356]},"#667788":{"lch":[49.2474401880289605,18.4334880243097601,239.056580638027469],"luv":[49.2474401880289605,-9.47834019220879398,-15.8099509152663327],"rgb":[0.4,0.466666666666666674,0.533333333333333326],"xyz":[0.165193651913794148,0.177957569709511237,0.258579186746416056],"hpluv":[239.056580638027469,47.4966726259429564,49.2474401880289605],"hsluv":[239.056580638027469,29.274081353383373,49.2474401880289605]},"#667799":{"lch":[49.8796002039077422,31.7351192214463786,251.680675473596239],"luv":[49.8796002039077422,-9.97474964621831,-30.126768188683684],"rgb":[0.4,0.466666666666666674,0.6],"xyz":[0.178250616022866876,0.183180355353140395,0.327345864387534],"hpluv":[251.680675473596239,80.734004933806176,49.8796002039077422],"hsluv":[251.680675473596239,34.661761655835349,49.8796002039077422]},"#6677aa":{"lch":[50.5938810850088174,45.7960576637453798,256.758518919433186],"luv":[50.5938810850088174,-10.4898463625666416,-44.5784928057335676],"rgb":[0.4,0.466666666666666674,0.66666666666666663],"xyz":[0.193308308988119404,0.18920343253924149,0.406649714004532592],"hpluv":[256.758518919433186,114.860161977636537,50.5938810850088174],"hsluv":[256.758518919433186,39.9381656359214858,50.5938810850088174]},"#6677bb":{"lch":[51.388614147457119,59.9444468574027738,259.409682348511467],"luv":[51.388614147457119,-11.0169047239158306,-58.9233783768730106],"rgb":[0.4,0.466666666666666674,0.733333333333333282],"xyz":[0.210445901095456078,0.196058469382176248,0.496907699103174338],"hpluv":[259.409682348511467,148.020333314730891,51.388614147457119],"hsluv":[259.409682348511467,49.2101017344363356,51.388614147457119]},"#6677cc":{"lch":[52.2614099661724225,73.9004259234932306,261.00752312302825],"luv":[52.2614099661724225,-11.5509895931656974,-72.9921063615257566],"rgb":[0.4,0.466666666666666674,0.8],"xyz":[0.229738276539177805,0.20377541955966505,0.598514209773444494],"hpluv":[261.00752312302825,179.434168102703751,52.2614099661724225],"hsluv":[261.00752312302825,61.6581230008595327,52.2614099661724225]},"#6677dd":{"lch":[53.2092913421323,87.5170631601914266,262.060353074135],"luv":[53.2092913421323,-12.0887245225321198,-86.6781349799548],"rgb":[0.4,0.466666666666666674,0.866666666666666696],"xyz":[0.251256602089811376,0.212382749779918584,0.711844057673450492],"hpluv":[262.060353074135,208.710638687620559,53.2092913421323],"hsluv":[262.060353074135,74.2459971892304083,53.2092913421323]},"#6677ee":{"lch":[54.2288239257805884,100.719531231348427,262.797438231409785],"luv":[54.2288239257805884,-12.6279723106459851,-99.9247631309883531],"rgb":[0.4,0.466666666666666674,0.933333333333333348],"xyz":[0.275068782355986086,0.221907621886388629,0.837254873741973715],"hpluv":[262.797438231409785,235.68005803746027,54.2288239257805884],"hsluv":[262.797438231409785,87.0042080584200193,54.2288239257805884]},"#6677ff":{"lch":[55.3162401631211793,113.47857319487936,263.336661992011841],"luv":[55.3162401631211793,-13.1675101506557386,-112.712036849566218],"rgb":[0.4,0.466666666666666674,1],"xyz":[0.301239830765817507,0.232376041250321325,0.97508906203375556],"hpluv":[263.336661992011841,260.315806593762318,55.3162401631211793],"hsluv":[263.336661992011841,99.999999999999,55.3162401631211793]},"#ddff00":{"lch":[94.69236188875891,107.73563953931891,97.6513944636985],"luv":[94.69236188875891,-14.3445112693176284,106.77641604488548],"rgb":[0.866666666666666696,1,0],"xyz":[0.65576562191334542,0.868918402572014,0.13317202741318887],"hpluv":[97.6513944636985,949.977135711580445,94.69236188875891],"hsluv":[97.6513944636985,100.000000000002302,94.69236188875891]},"#ddff11":{"lch":[94.7095428290633237,106.965998536257018,97.7198690947758308],"luv":[94.7095428290633237,-14.3687245726656343,105.996531061225838],"rgb":[0.866666666666666696,1,0.0666666666666666657],"xyz":[0.65677728741298258,0.869323068771868934,0.138500132377944507],"hpluv":[97.7198690947758308,946.378692368412885,94.7095428290633237],"hsluv":[97.7198690947758308,99.9999999999867697,94.7095428290633237]},"#ddff22":{"lch":[94.7413776147606086,105.545731309599958,97.8489007917202827],"luv":[94.7413776147606086,-14.4134418215914106,104.556941866783148],"rgb":[0.866666666666666696,1,0.133333333333333331],"xyz":[0.658652645551459526,0.870073212027259735,0.148377018573923686],"hpluv":[97.8489007917202827,939.695870823628752,94.7413776147606086],"hsluv":[97.8489007917202827,99.9999999999872,94.7413776147606086]},"#ddff33":{"lch":[94.7937532988665197,103.225383790498825,98.0674915546983],"luv":[94.7937532988665197,-14.4865977424562669,102.203807876928138],"rgb":[0.866666666666666696,1,0.2],"xyz":[0.661740396283917343,0.871308312320242861,0.164639172431534836],"hpluv":[98.0674915546983,928.656435156239354,94.7937532988665197],"hsluv":[98.0674915546983,99.9999999999868834,94.7937532988665197]},"#ddff44":{"lch":[94.8692843830354491,99.9146373114600692,98.397314807396512],"luv":[94.8692843830354491,-14.5912004882884094,98.8434702820129729],"rgb":[0.866666666666666696,1,0.266666666666666663],"xyz":[0.666198391528136202,0.873091510417930428,0.188117947384421474],"hpluv":[98.397314807396512,912.633071017653265,94.8692843830354491],"hsluv":[98.397314807396512,99.9999999999866276,94.8692843830354491]},"#ddff55":{"lch":[94.9701440016210654,95.558111661139634,98.8668834316730738],"luv":[94.9701440016210654,-14.7292629682473848,94.4161083536863828],"rgb":[0.866666666666666696,1,0.333333333333333315],"xyz":[0.672160805567498132,0.875476476033675177,0.21951999465839539],"hpluv":[98.8668834316730738,891.031026100052486,94.9701440016210654],"hsluv":[98.8668834316730738,99.9999999999861586,94.9701440016210654]},"#ddff66":{"lch":[95.0981866754888,90.1320341607989235,99.5166683548804798],"luv":[95.0981866754888,-14.9019372161492765,88.8915960547979438],"rgb":[0.866666666666666696,1,0.4],"xyz":[0.679745801341006373,0.878510474343078496,0.259467639065539379],"hpluv":[99.5166683548804798,863.234823568518,95.0981866754888],"hsluv":[99.5166683548804798,99.9999999999856186,95.0981866754888]},"#ddff77":{"lch":[95.2550143462764396,83.6430269583913599,100.407261812829162],"luv":[95.2550143462764396,-15.1095945804084604,82.2669806810598487],"rgb":[0.866666666666666696,1,0.466666666666666674],"xyz":[0.689059814361208223,0.882236079551159347,0.308521440971937233],"hpluv":[100.407261812829162,828.556184265804632,95.2550143462764396],"hsluv":[100.407261812829162,99.9999999999855476,95.2550143462764396]},"#ddff88":{"lch":[95.4420158908659175,76.1281736437493,101.633961649281417],"luv":[95.4420158908659175,-15.3518949618923237,74.5641880758576434],"rgb":[0.866666666666666696,1,0.533333333333333326],"xyz":[0.700200231463152134,0.886692246391936889,0.367194304375509428],"hpluv":[101.633961649281417,786.17501332264635,95.4420158908659175],"hsluv":[101.633961649281417,99.9999999999848512,95.4420158908659175]},"#ddff99":{"lch":[95.6603925662724208,67.6570848719276086,103.355147801887099],"luv":[95.6603925662724208,-15.6278614338241617,65.8274341013866859],"rgb":[0.866666666666666696,1,0.6],"xyz":[0.713257195572224778,0.891915032035566102,0.435960982016627363],"hpluv":[103.355147801887099,735.074270676232231,95.6603925662724208],"hsluv":[103.355147801887099,99.9999999999844107,95.6603925662724208]},"#ddffaa":{"lch":[95.9111754000973775,58.338925144698,105.852499131344544],"luv":[95.9111754000973775,-15.935965587620279,56.1201852084333268],"rgb":[0.866666666666666696,1,0.66666666666666663],"xyz":[0.72831488853747739,0.897938109221667169,0.515264831633625908],"hpluv":[105.852499131344544,673.992295850936557,95.9111754000973775],"hsluv":[105.852499131344544,99.9999999999831886,95.9111754000973775]},"#ddffbb":{"lch":[96.1952377631310185,48.3433070572267596,109.672211431084662],"luv":[96.1952377631310185,-16.2742233848326485,45.5216980180866813],"rgb":[0.866666666666666696,1,0.733333333333333282],"xyz":[0.745452480644814,0.904793146064601927,0.60552281673226771],"hpluv":[109.672211431084662,601.502194015230771,96.1952377631310185],"hsluv":[109.672211431084662,99.9999999999821654,96.1952377631310185]},"#ddffcc":{"lch":[96.513305005727517,37.9644197829535202,115.996292551248089],"luv":[96.513305005727517,-16.6402982513575566,34.1232712904577653],"rgb":[0.866666666666666696,1,0.8],"xyz":[0.764744856088535707,0.912510096242090785,0.707129327402537866],"hpluv":[115.996292551248089,516.693096965009204,96.513305005727517],"hsluv":[115.996292551248089,99.9999999999804885,96.513305005727517]},"#ddffdd":{"lch":[96.8659623148576,27.841508205801528,127.715012949232161],"luv":[96.8659623148576,-17.0316066426751398,22.0243945284064],"rgb":[0.866666666666666696,1,0.866666666666666696],"xyz":[0.786263181639169306,0.921117426462344291,0.820459175302543864],"hpluv":[127.715012949232161,422.676993554754517,96.8659623148576],"hsluv":[127.715012949232161,99.9999999999786411,96.8659623148576]},"#ddffee":{"lch":[97.2536615310726802,19.7831433293950418,151.864226334417424],"luv":[97.2536615310726802,-17.4454209009420502,9.32898974060759478],"rgb":[0.866666666666666696,1,0.933333333333333348],"xyz":[0.810075361905344,0.930642298568814308,0.945869991371067087],"hpluv":[151.864226334417424,343.73229759561508,97.2536615310726802],"hsluv":[151.864226334417424,99.9999999999752,97.2536615310726802]},"#ddffff":{"lch":[97.6767274082888406,18.2904922799610645,192.177050630059568],"luv":[97.6767274082888406,-17.878964623675607,-3.85807359036494368],"rgb":[0.866666666666666696,1,1],"xyz":[0.836246410315175437,0.941110717932747,1.08370417966284882],"hpluv":[192.177050630059568,376.852754928906336,97.6767274082888406],"hsluv":[192.177050630059568,99.9999999999715072,97.6767274082888406]},"#668800":{"lch":[52.32310792684153,62.4331707825390509,105.73052795354684],"luv":[52.32310792684153,-16.9264656143939405,60.0948881001240167],"rgb":[0.4,0.533333333333333326,0],"xyz":[0.142831412088957943,0.204328465339529863,0.0319143663590854554],"hpluv":[105.73052795354684,151.412310196323318,52.32310792684153],"hsluv":[105.73052795354684,100.000000000002359,52.32310792684153]},"#668811":{"lch":[52.3681821172622222,60.6739112189649603,106.201766876928076],"luv":[52.3681821172622222,-16.9292783492562116,58.26425179456308],"rgb":[0.4,0.533333333333333326,0.0666666666666666657],"xyz":[0.143843077588595075,0.204733131539384716,0.0372424713238410851],"hpluv":[106.201766876928076,147.019120365759306,52.3681821172622222],"hsluv":[106.201766876928076,96.7617570127925859,52.3681821172622222]},"#668822":{"lch":[52.4515808002199,57.4815115963739842,107.134347730867304],"luv":[52.4515808002199,-16.9348150675510247,54.9302850350507796],"rgb":[0.4,0.533333333333333326,0.133333333333333331],"xyz":[0.145718435727072076,0.205483274794775544,0.0471193575198202846],"hpluv":[107.134347730867304,139.062145386582984,52.4515808002199],"hsluv":[107.134347730867304,90.8761910280814647,52.4515808002199]},"#668833":{"lch":[52.5884544541714121,52.4173031151438593,108.860637572968898],"luv":[52.5884544541714121,-16.9448041098426323,49.6028958786070291],"rgb":[0.4,0.533333333333333326,0.2],"xyz":[0.14880618645952981,0.206718375087758643,0.0633815113774314209],"hpluv":[108.860637572968898,126.480505252334424,52.5884544541714121],"hsluv":[108.860637572968898,81.504484256448066,52.5884544541714121]},"#668844":{"lch":[52.7851097594501937,45.5231929703366234,111.874794573011059],"luv":[52.7851097594501937,-16.9610118856818559,42.2455343678863215],"rgb":[0.4,0.533333333333333326,0.266666666666666663],"xyz":[0.153264181703748698,0.208501573185446237,0.0868602863303180595],"hpluv":[111.874794573011059,109.436101408621766,52.7851097594501937],"hsluv":[111.874794573011059,68.6312430201703734,52.7851097594501937]},"#668855":{"lch":[53.0463844713544859,37.0894540992544819,117.255878513522262],"luv":[53.0463844713544859,-16.9856764955971045,32.9714179156375593],"rgb":[0.4,0.533333333333333326,0.333333333333333315],"xyz":[0.15922659574311071,0.21088653880119107,0.118262333604291975],"hpluv":[117.255878513522262,88.7225425584692715,53.0463844713544859],"hsluv":[117.255878513522262,52.5261258187504225,53.0463844713544859]},"#668866":{"lch":[53.3759296841588906,27.8248149657310222,127.715012949236794],"luv":[53.3759296841588906,-17.0213948144824521,22.0111891193247189],"rgb":[0.4,0.533333333333333326,0.4],"xyz":[0.166811591516618868,0.213920537110594361,0.158209978011435937],"hpluv":[127.715012949236794,66.1494380276081415,53.3759296841588906],"hsluv":[127.715012949236794,33.681854155652033,53.3759296841588906]},"#668877":{"lch":[53.7763606180623839,19.6211535767711887,150.461713858693599],"luv":[53.7763606180623839,-17.0709226847205855,9.67332757511772101],"rgb":[0.4,0.533333333333333326,0.466666666666666674],"xyz":[0.176125604536820801,0.217646142318675184,0.207263779917833846],"hpluv":[150.461713858693599,46.2990901048939207,53.7763606180623839],"hsluv":[150.461713858693599,37.1484166060608132,53.7763606180623839]},"#668888":{"lch":[54.2493559855519436,17.5313913512660982,192.17705063006045],"luv":[54.2493559855519436,-17.1369431164247104,-3.69795393909545],"rgb":[0.4,0.533333333333333326,0.533333333333333326],"xyz":[0.187266021638764601,0.222102309159452782,0.265936643321406],"hpluv":[192.17705063006045,41.0072951616226788,54.2493559855519436],"hsluv":[192.17705063006045,40.8467805779917228,54.2493559855519436]},"#668899":{"lch":[54.7957384612029728,24.7393499057112685,225.882505108050964],"luv":[54.7957384612029728,-17.2218541013304964,-17.7607200042594577],"rgb":[0.4,0.533333333333333326,0.6],"xyz":[0.200322985747837329,0.22732509480308194,0.33470332096252392],"hpluv":[225.882505108050964,57.2902642666713859,54.7957384612029728],"hsluv":[225.882505108050964,44.6631352998217963,54.7957384612029728]},"#6688aa":{"lch":[55.4155508256813363,36.5699037808867828,241.717344836465486],"luv":[55.4155508256813363,-17.3276119763631087,-32.2042190673817643],"rgb":[0.4,0.533333333333333326,0.66666666666666663],"xyz":[0.215380678713089857,0.233348171989183034,0.414007170579522521],"hpluv":[241.717344836465486,83.7397171719788389,55.4155508256813363],"hsluv":[241.717344836465486,48.4952118884804193,55.4155508256813363]},"#6688bb":{"lch":[56.1081340603271457,49.918102431374308,249.531909378681803],"luv":[56.1081340603271457,-17.4556451944419777,-46.7666270025424495],"rgb":[0.4,0.533333333333333326,0.733333333333333282],"xyz":[0.232518270820426531,0.240203208832117793,0.504265155678164323],"hpluv":[249.531909378681803,112.8941838879785,56.1081340603271457],"hsluv":[249.531909378681803,52.2580147864780216,56.1081340603271457]},"#6688cc":{"lch":[56.8722093096567107,63.7230017864969795,253.960340799970709],"luv":[56.8722093096567107,-17.6068348542363715,-61.2423082770199372],"rgb":[0.4,0.533333333333333326,0.8],"xyz":[0.251810646264148286,0.247920159009606594,0.605871666348434479],"hpluv":[253.960340799970709,142.178999158492672,56.8722093096567107],"hsluv":[253.960340799970709,56.6402695601832349,56.8722093096567107]},"#6688dd":{"lch":[57.7059632125805564,77.5471512008463719,256.744147904563079],"luv":[57.7059632125805564,-17.7815469636593271,-75.4809727477468755],"rgb":[0.4,0.533333333333333326,0.866666666666666696],"xyz":[0.273328971814781774,0.256527489229860128,0.719201514248440477],"hpluv":[256.744147904563079,170.523595036459966,57.7059632125805564],"hsluv":[256.744147904563079,70.7529337108087475,57.7059632125805564]},"#6688ee":{"lch":[58.6071348177704721,91.1720868217648501,258.626369492504523],"luv":[58.6071348177704721,-17.979697586292076,-89.3816529839368599],"rgb":[0.4,0.533333333333333326,0.933333333333333348],"xyz":[0.297141152080956539,0.266052361336330145,0.8446123303169637],"hpluv":[258.626369492504523,197.40162879311913,58.6071348177704721],"hsluv":[258.626369492504523,85.1920367601911295,58.6071348177704721]},"#6688ff":{"lch":[59.57310174908622,104.481663139573541,259.967822360236937],"luv":[59.57310174908622,-18.2008336002305597,-102.884146439906075],"rgb":[0.4,0.533333333333333326,1],"xyz":[0.323312200490787904,0.276520780700262869,0.982446518608745434],"hpluv":[259.967822360236937,222.550815911907222,59.57310174908622],"hsluv":[259.967822360236937,99.9999999999987352,59.57310174908622]},"#669900":{"lch":[57.6618978033021961,71.9113437902946373,111.072092359847389],"luv":[57.6618978033021961,-25.8551729794803826,67.1025438856612624],"rgb":[0.4,0.6,0],"xyz":[0.168701012541425444,0.25606766624446553,0.0405375665099077104],"hpluv":[111.072092359847389,158.251486754186431,57.6618978033021961],"hsluv":[111.072092359847389,100.000000000002444,57.6618978033021961]},"#669911":{"lch":[57.7006802499588929,70.3894808316696867,111.521292839157113],"luv":[57.7006802499588929,-25.8221679479897865,65.4820177928093727],"rgb":[0.4,0.6,0.0666666666666666657],"xyz":[0.169712678041062576,0.256472332444320383,0.0458656714746633401],"hpluv":[111.521292839157113,154.798288730060023,57.7006802499588929],"hsluv":[111.521292839157113,97.4070268725327821,57.7006802499588929]},"#669922":{"lch":[57.7724648019637499,67.6202459496272326,112.394641072548438],"luv":[57.7724648019637499,-25.7622250908158499,62.5204400229094404],"rgb":[0.4,0.6,0.133333333333333331],"xyz":[0.171588036179539577,0.257222475699711184,0.0557425576706425396],"hpluv":[112.394641072548438,148.523500329687067,57.7724648019637499],"hsluv":[112.394641072548438,92.6757293451634183,57.7724648019637499]},"#669933":{"lch":[57.8903535973237524,63.206621217633213,113.958803391015238],"luv":[57.8903535973237524,-25.6669247559924365,57.7605915769530824],"rgb":[0.4,0.6,0.2],"xyz":[0.174675786911997311,0.258457575992694311,0.0720047115282536898],"hpluv":[113.958803391015238,138.546544821103367,57.8903535973237524],"hsluv":[113.958803391015238,85.092275495173979,57.8903535973237524]},"#669944":{"lch":[58.0598969225296457,57.1535921702901888,116.538768682419729],"luv":[58.0598969225296457,-25.5364113217858204,51.131446241744662],"rgb":[0.4,0.6,0.266666666666666663],"xyz":[0.179133782156216198,0.260240774090381877,0.0954834864811403283],"hpluv":[116.538768682419729,124.912700512594284,58.0598969225296457],"hsluv":[116.538768682419729,74.5746503624431796,58.0598969225296457]},"#669955":{"lch":[58.2854489010818355,49.6561447471622515,120.7300937454592],"luv":[58.2854489010818355,-25.3740154630121886,42.6836274282534163],"rgb":[0.4,0.6,0.333333333333333315],"xyz":[0.185096196195578211,0.262625739706126737,0.126885533755114244],"hpluv":[120.7300937454592,108.106592630407334,58.2854489010818355],"hsluv":[120.7300937454592,61.2495338993745833,58.2854489010818355]},"#669966":{"lch":[58.5704165792398754,41.1710358166226,127.715012949238272],"luv":[58.5704165792398754,-25.1857364161826034,32.5688942303571949],"rgb":[0.4,0.6,0.4],"xyz":[0.192681191969086368,0.265659738015530056,0.166833178162258178],"hpluv":[127.715012949238272,89.1975256314243552,58.5704165792398754],"hsluv":[127.715012949238272,45.4174387408809324,58.5704165792398754]},"#669977":{"lch":[58.9173908027988489,32.643461159974926,139.926834832055846],"luv":[58.9173908027988489,-24.9795271581232114,21.0147276798767138],"rgb":[0.4,0.6,0.466666666666666674],"xyz":[0.201995204989288302,0.269385343223610851,0.215886980068656087],"hpluv":[139.926834832055846,70.3059403526018514,58.9173908027988489],"hsluv":[139.926834832055846,47.7876005322921813,58.9173908027988489]},"#669988":{"lch":[59.328227692638464,26.116847909850911,161.480821243886396],"luv":[59.328227692638464,-24.7644493579715288,8.29528738156475498],"rgb":[0.4,0.6,0.533333333333333326],"xyz":[0.213135622091232102,0.273841510064388449,0.274559843472228282],"hpluv":[161.480821243886396,55.8597144892801083,59.328227692638464],"hsluv":[161.480821243886396,50.3655359274122105,59.328227692638464]},"#669999":{"lch":[59.8041090330486043,25.1148951486962346,192.17705063006062],"luv":[59.8041090330486043,-24.5498215694726056,-5.29756729424584893],"rgb":[0.4,0.6,0.6],"xyz":[0.226192586200304829,0.279064295708017607,0.343326521113346161],"hpluv":[192.17705063006062,53.2892577697712042,59.8041090330486043],"hsluv":[192.17705063006062,53.0806679813151447,59.8041090330486043]},"#6699aa":{"lch":[60.3455948386344119,31.1785657150768039,218.6653689057203],"luv":[60.3455948386344119,-24.3444790905776323,-19.4794583563761137],"rgb":[0.4,0.6,0.66666666666666663],"xyz":[0.241250279165557358,0.285087372894118729,0.422630370730344762],"hpluv":[218.6653689057203,65.5616517705923911,60.3455948386344119],"hsluv":[218.6653689057203,55.8649153078387357,60.3455948386344119]},"#6699bb":{"lch":[60.9526745558420231,41.7013653705125407,234.60099737489486],"luv":[60.9526745558420231,-24.1562241025528444,-33.9923625373734168],"rgb":[0.4,0.6,0.733333333333333282],"xyz":[0.258387871272894032,0.291942409737053488,0.512888355828986509],"hpluv":[234.60099737489486,86.8154127469588,60.9526745558420231],"hsluv":[234.60099737489486,58.6571249967150123,60.9526745558420231]},"#6699cc":{"lch":[61.6248198105828493,54.2138016672169485,243.734276496040906],"luv":[61.6248198105828493,-23.9914938552849968,-48.6162988492970101],"rgb":[0.4,0.6,0.8],"xyz":[0.277680246716615731,0.299659359914542289,0.614494866499256664],"hpluv":[243.734276496040906,111.633239234030881,61.6248198105828493],"hsluv":[243.734276496040906,61.4057918386087067,61.6248198105828493]},"#6699dd":{"lch":[62.361039595623,67.5283063616342361,249.312993820438976],"luv":[62.361039595623,-23.8552311607989473,-63.1743627299522288],"rgb":[0.4,0.6,0.866666666666666696],"xyz":[0.29919857226724933,0.308266690134795796,0.727824714399262662],"hpluv":[249.312993820438976,137.407942777337979,62.361039595623],"hsluv":[249.312993820438976,66.62550454031512,62.361039595623]},"#6699ee":{"lch":[63.1599376048740453,81.0888167917790526,252.968345076420633],"luv":[63.1599376048740453,-23.7509145884581336,-77.5325110189427278],"rgb":[0.4,0.6,0.933333333333333348],"xyz":[0.323010752533424039,0.317791562241265813,0.853235530467785885],"hpluv":[252.968345076420633,162.914071535813093,63.1599376048740453],"hsluv":[252.968345076420633,83.0301883133999183,63.1599376048740453]},"#6699ff":{"lch":[64.0197707514621186,94.6074384193794771,255.504450424431923],"luv":[64.0197707514621186,-23.6806962224400728,-91.5958079318982499],"rgb":[0.4,0.6,1],"xyz":[0.34918180094325546,0.328259981605198536,0.99106971875956773],"hpluv":[255.504450424431923,187.521252715437782,64.0197707514621186],"hsluv":[255.504450424431923,99.9999999999985079,64.0197707514621186]},"#550000":{"lch":[15.1243819173422267,50.8637728648741643,12.1770506300617765],"luv":[15.1243819173422267,49.7193613905117289,10.7288626130266547],"rgb":[0.333333333333333315,0,0],"xyz":[0.0374622858816120868,0.019316491157706641,0.00175604465070052949],"hpluv":[12.1770506300617765,426.746789183125202,15.1243819173422267],"hsluv":[12.1770506300617765,100.000000000002203,15.1243819173422267]},"#550011":{"lch":[15.3402258633588957,47.2707050856887108,7.4875089370669734],"luv":[15.3402258633588957,46.8676416739534929,6.15984766208174239],"rgb":[0.333333333333333315,0,0.0666666666666666657],"xyz":[0.0384739513812492051,0.0197211573575614939,0.00708414961545616138],"hpluv":[7.4875089370669734,391.020613457768548,15.3402258633588957],"hsluv":[7.4875089370669734,99.9999999999966889,15.3402258633588957]},"#550022":{"lch":[15.7326592199860933,42.4312907985821823,358.411234527054887],"luv":[15.7326592199860933,42.4149789665186745,-1.17643448760390168],"rgb":[0.333333333333333315,0,0.133333333333333331],"xyz":[0.0403493095197262272,0.0204713006129523117,0.0169610358114353557],"hpluv":[358.411234527054887,342.234221563623748,15.7326592199860933],"hsluv":[358.411234527054887,99.9999999999971578,15.7326592199860933]},"#550033":{"lch":[16.358416636328208,38.360101220613565,343.406058671947278],"luv":[16.358416636328208,36.7625096026365128,-10.9551473459637485],"rgb":[0.333333333333333315,0,0.2],"xyz":[0.0434370602521839677,0.0217064009059354281,0.0332231896690465],"hpluv":[343.406058671947278,297.562230749163234,16.358416636328208],"hsluv":[343.406058671947278,99.9999999999977547,16.358416636328208]},"#550044":{"lch":[17.2212923868602061,37.8614359764106112,324.728975934647224],"luv":[17.2212923868602061,30.9112016871952413,-21.8628896637516235],"rgb":[0.333333333333333315,0,0.266666666666666663],"xyz":[0.0478950554964028483,0.0234895990036230046,0.0567019646219331375],"hpluv":[324.728975934647224,278.978456842737614,17.2212923868602061],"hsluv":[324.728975934647224,99.9999999999983089,17.2212923868602061]},"#550055":{"lch":[18.3096014215038,41.7063030886972754,307.715012949243544],"luv":[18.3096014215038,25.5131777875110508,-32.9923245090298636],"rgb":[0.333333333333333315,0,0.333333333333333315],"xyz":[0.0538574695357648403,0.025874564619367834,0.0881040118959070528],"hpluv":[307.715012949243544,289.042783730483393,18.3096014215038],"hsluv":[307.715012949243544,99.9999999999988,18.3096014215038]},"#550066":{"lch":[19.6013792550641099,48.6148100748190828,295.355623011865077],"luv":[19.6013792550641099,20.818580180871372,-43.9316113733990079],"rgb":[0.333333333333333315,0,0.4],"xyz":[0.0614424653092730116,0.028908562928771149,0.128051656303051015],"hpluv":[295.355623011865077,314.717786655224245,19.6013792550641099],"hsluv":[295.355623011865077,99.9999999999992468,19.6013792550641099]},"#550077":{"lch":[21.069395574911745,57.1127554515679421,287.139622223683091],"luv":[21.069395574911745,16.83119884103942,-54.5763463493480572],"rgb":[0.333333333333333315,0,0.466666666666666674],"xyz":[0.0707564783294749311,0.0326341681368519654,0.177105458209448924],"hpluv":[287.139622223683091,343.969838941793114,21.069395574911745],"hsluv":[287.139622223683091,99.9999999999995737,21.069395574911745]},"#550088":{"lch":[22.6852054601189934,66.3294491167530822,281.703433904835379],"luv":[22.6852054601189934,13.454662288017035,-64.9505033302079084],"rgb":[0.333333333333333315,0,0.533333333333333326],"xyz":[0.0818968954314187592,0.0370903349776295563,0.235778321613021091],"hpluv":[281.703433904835379,371.024851449370942,22.6852054601189934],"hsluv":[281.703433904835379,99.9999999999998721,22.6852054601189934]},"#550099":{"lch":[24.4218644362266417,75.8503102235033424,278.01254475278904],"luv":[24.4218644362266417,10.5727682252252198,-75.1098271403773339],"rgb":[0.333333333333333315,0,0.6],"xyz":[0.0949538595404914726,0.0423131206212587208,0.304544999254138971],"hpluv":[278.01254475278904,394.110378481836165,24.4218644362266417],"hsluv":[278.01254475278904,100.000000000000071,24.4218644362266417]},"#5500aa":{"lch":[26.2553935553790794,85.4876195151354,275.424483319872081],"luv":[26.2553935553790794,8.0814629277942,-85.1047768771603614],"rgb":[0.333333333333333315,0,0.66666666666666663],"xyz":[0.110011552505744015,0.0483361978073598153,0.383848848871137571],"hpluv":[275.424483319872081,413.165469396605374,26.2553935553790794],"hsluv":[275.424483319872081,100.00000000000027,26.2553935553790794]},"#5500bb":{"lch":[28.1653177219846,95.1546470205467756,273.553022331801344],"luv":[28.1653177219846,5.89694295360029841,-94.9717479748942708],"rgb":[0.333333333333333315,0,0.733333333333333282],"xyz":[0.127149144613080661,0.0551912346502945739,0.474106833969779318],"hpluv":[273.553022331801344,428.701175528050442,28.1653177219846],"hsluv":[273.553022331801344,100.000000000000355,28.1653177219846]},"#5500cc":{"lch":[30.1346298593711452,104.80902699908826,272.162345307959299],"luv":[30.1346298593711452,3.95455850560158062,-104.734395532324456],"rgb":[0.333333333333333315,0,0.8],"xyz":[0.146441520056802388,0.0629081848277833755,0.575713344640049529],"hpluv":[272.162345307959299,441.338845171454864,30.1346298593711452],"hsluv":[272.162345307959299,100.000000000000441,30.1346298593711452]},"#5500dd":{"lch":[32.1494591091083208,114.428501102308275,271.104225820707256],"luv":[32.1494591091083208,2.20517261265448461,-114.407250986418532],"rgb":[0.333333333333333315,0,0.866666666666666696],"xyz":[0.167959845607435931,0.0715155150480369095,0.689043192540055527],"hpluv":[271.104225820707256,451.647764573950099,32.1494591091083208],"hsluv":[271.104225820707256,100.000000000000483,32.1494591091083208]},"#5500ee":{"lch":[34.1986254005705774,124.000502171291956,270.282536199645165],"luv":[34.1986254005705774,0.611467178704377612,-123.998994538754019],"rgb":[0.333333333333333315,0,0.933333333333333348],"xyz":[0.191772025873610696,0.0810403871545069404,0.81445400860857875],"hpluv":[270.282536199645165,460.101999214721616,34.1986254005705774],"hsluv":[270.282536199645165,100.000000000000597,34.1986254005705774]},"#5500ff":{"lch":[36.2731838611955055,133.517545782829444,269.6330586770423],"luv":[36.2731838611955055,-0.855085145745556,-133.514807647929],"rgb":[0.333333333333333315,0,1],"xyz":[0.217943074283442062,0.0915088065184396504,0.952288196900360595],"hpluv":[269.6330586770423,467.080772865482345,36.2731838611955055],"hsluv":[269.6330586770423,100.000000000000668,36.2731838611955055]},"#551100":{"lch":[17.1436512350983392,46.6418802884309827,16.9386517648024579],"luv":[17.1436512350983392,44.618427652544149,13.5889996193616174],"rgb":[0.333333333333333315,0.0666666666666666657,0],"xyz":[0.0394666861425404941,0.0233252916795635146,0.00242417807100998037],"hpluv":[16.9386517648024579,345.232802292268,17.1436512350983392],"hsluv":[16.9386517648024579,100.000000000002245,17.1436512350983392]},"#551111":{"lch":[17.3342210988239742,43.3325537190722372,12.1770506300618173],"luv":[17.3342210988239742,42.3575912084996133,9.14027783111198566],"rgb":[0.333333333333333315,0.0666666666666666657,0.0666666666666666657],"xyz":[0.0404783516421776124,0.0237299578794183674,0.0077522830357656114],"hpluv":[12.1770506300618173,317.211759513802576,17.3342210988239742],"hsluv":[12.1770506300618173,74.3325474389658751,17.3342210988239742]},"#551122":{"lch":[17.681833534927847,38.7809423842287515,2.75476418742331486],"luv":[17.681833534927847,38.7361268795629599,1.86385798259144919],"rgb":[0.333333333333333315,0.0666666666666666657,0.133333333333333331],"xyz":[0.0423537097806546345,0.0244801011348091888,0.0176291692317448075],"hpluv":[2.75476418742331486,278.311009894887945,17.681833534927847],"hsluv":[2.75476418742331486,76.7057995287142234,17.681833534927847]},"#551133":{"lch":[18.2390179286851222,34.9181665436168771,346.660743506282301],"luv":[18.2390179286851222,33.9761101882180157,-8.05619582966011727],"rgb":[0.333333333333333315,0.0666666666666666657,0.2],"xyz":[0.045441460513112375,0.0257152014277923,0.0338913230893559542],"hpluv":[346.660743506282301,242.9345634355779,18.2390179286851222],"hsluv":[346.660743506282301,79.7834922439867285,18.2390179286851222]},"#551144":{"lch":[19.0128230091186055,34.7408929356053093,326.164658676814156],"luv":[19.0128230091186055,28.8572161490225767,-19.3440098762325228],"rgb":[0.333333333333333315,0.0666666666666666657,0.266666666666666663],"xyz":[0.0498994557573312555,0.0274983995254798746,0.0573700980422425927],"hpluv":[326.164658676814156,231.864199750183133,19.0128230091186055],"hsluv":[326.164658676814156,83.0221027238197706,19.0128230091186055]},"#551155":{"lch":[19.9971255718025702,39.1813209297373,307.715012949243771],"luv":[19.9971255718025702,23.9685594933690105,-30.9949038651824331],"rgb":[0.333333333333333315,0.0666666666666666657,0.333333333333333315],"xyz":[0.0558618697966932476,0.0298833651412247076,0.0887721453162165],"hpluv":[307.715012949243771,248.628452083429778,19.9971255718025702],"hsluv":[307.715012949243771,86.0178721207098391,19.9971255718025702]},"#551166":{"lch":[21.1763147828962417,46.7756191769153702,294.771362117319313],"luv":[21.1763147828962417,19.5989049109657927,-42.4716549674572263],"rgb":[0.333333333333333315,0.0666666666666666657,0.4],"xyz":[0.0634468655702014189,0.0329173634506280191,0.128719789723360456],"hpluv":[294.771362117319313,280.29057047770084,21.1763147828962417],"hsluv":[294.771362117319313,88.5810746573468464,21.1763147828962417]},"#551177":{"lch":[22.529041607596703,55.8726050260016436,286.442196236272423],"luv":[22.529041607596703,15.8146223861076685,-53.5877384405836494],"rgb":[0.333333333333333315,0.0666666666666666657,0.466666666666666674],"xyz":[0.0727608785904033384,0.0366429686587088355,0.177773591629758365],"hpluv":[286.442196236272423,314.699121073082495,22.529041607596703],"hsluv":[286.442196236272423,90.6792509168865166,22.529041607596703]},"#551188":{"lch":[24.0315326783493077,65.5523157673088548,281.05474383939486],"luv":[24.0315326783493077,12.5694476912001676,-64.3359548557037613],"rgb":[0.333333333333333315,0.0666666666666666657,0.533333333333333326],"xyz":[0.0839012956923471664,0.0410991354994864333,0.236446455033330533],"hpluv":[281.05474383939486,346.135302225987516,24.0315326783493077],"hsluv":[281.05474383939486,92.3586421581981654,24.0315326783493077]},"#551199":{"lch":[25.6600874124784752,75.409923320082811,277.450872837297311],"luv":[25.6600874124784752,9.77886091464338847,-74.7731931533810439],"rgb":[0.333333333333333315,0.0666666666666666657,0.6],"xyz":[0.0969582598014198799,0.0463219211431155908,0.30521313267444844],"hpluv":[277.450872837297311,372.914863977489176,25.6600874124784752],"hsluv":[277.450872837297311,93.6909530677945099,25.6600874124784752]},"#5511aa":{"lch":[27.3926712394503795,85.2829889480110097,274.948569823839534],"luv":[27.3926712394503795,7.3566383451248436,-84.9650991652784882],"rgb":[0.333333333333333315,0.0666666666666666657,0.66666666666666663],"xyz":[0.112015952766672422,0.0523449983292166923,0.38451698229144704],"hpluv":[274.948569823839534,395.063906765864772,27.3926712394503795],"hsluv":[274.948569823839534,94.7471527755802185,27.3926712394503795]},"#5511bb":{"lch":[29.2097366740877575,95.1102004757886732,273.151254165932869],"luv":[29.2097366740877575,5.22840137893499524,-94.9663838079847125],"rgb":[0.333333333333333315,0.0666666666666666657,0.733333333333333282],"xyz":[0.129153544874009069,0.0592000351721514509,0.474774967390088787],"hpluv":[273.151254165932869,413.179515249173164,29.2097366740877575],"hsluv":[273.151254165932869,95.5878244802283,29.2097366740877575]},"#5511cc":{"lch":[31.0944914716528729,104.870266468627406,271.822015936655589],"luv":[31.0944914716528729,3.33433100744475697,-104.81724584215],"rgb":[0.333333333333333315,0.0666666666666666657,0.8],"xyz":[0.148445920317730795,0.0669169853496402456,0.576381478060359],"hpluv":[271.822015936655589,427.964986778194486,31.0944914716528729],"hsluv":[271.822015936655589,96.2613872132177733,31.0944914716528729]},"#5511dd":{"lch":[33.0328257175950526,114.557035031638449,270.814150293263936],"luv":[33.0328257175950526,1.62775523553093748,-114.545469959022128],"rgb":[0.333333333333333315,0.0666666666666666657,0.866666666666666696],"xyz":[0.169964245868364339,0.0755243155698937796,0.689711325960365],"hpluv":[270.814150293263936,440.063516862193467,33.0328257175950526],"hsluv":[270.814150293263936,96.8053522828386832,33.0328257175950526]},"#5511ee":{"lch":[35.0130604571318926,124.169729525043778,270.033521846843314],"luv":[35.0130604571318926,0.0726475571782520396,-124.169708273213573],"rgb":[0.333333333333333315,0.0666666666666666657,0.933333333333333348],"xyz":[0.193776426134539104,0.0850491876763638244,0.815122142028888219],"hpluv":[270.033521846843314,450.012925469310176,35.0130604571318926],"hsluv":[270.033521846843314,97.2483877085506663,35.0130604571318926]},"#5511ff":{"lch":[37.0256255288684244,133.709282746677673,269.417732433602225],"luv":[37.0256255288684244,-1.35879534673770408,-133.702378317802101],"rgb":[0.333333333333333315,0.0666666666666666657,1],"xyz":[0.219947474544370469,0.0955176070402965205,0.952956330320670064],"hpluv":[269.417732433602225,458.245787382607887,37.0256255288684244],"hsluv":[269.417732433602225,99.999999999999531,37.0256255288684244]},"#552200":{"lch":[20.34436993371488,40.5799496107340403,26.5709502396200712],"luv":[20.34436993371488,36.2939416756913289,18.1516420207988389],"rgb":[0.333333333333333315,0.133333333333333331,0],"xyz":[0.0431823098773084293,0.0307565391490994891,0.0036627193159325909],"hpluv":[26.5709502396200712,253.10841584108,20.34436993371488],"hsluv":[26.5709502396200712,100.000000000002359,20.34436993371488]},"#552211":{"lch":[20.5030711832139332,37.4561676233306144,21.8926823519782197],"luv":[20.5030711832139332,34.7549742653004543,13.9662542166947503],"rgb":[0.333333333333333315,0.133333333333333331,0.0666666666666666657],"xyz":[0.0441939753769455546,0.031161205348954342,0.00899082428068822236],"hpluv":[21.8926823519782197,231.816181029165051,20.5030711832139332],"hsluv":[21.8926823519782197,79.998991439989,20.5030711832139332]},"#552222":{"lch":[20.7936643332181177,32.9512801850020054,12.1770506300619488],"luv":[20.7936643332181177,32.2098915499349658,6.95052171940595098],"rgb":[0.333333333333333315,0.133333333333333331,0.133333333333333331],"xyz":[0.0460693335154225697,0.0319113486043451633,0.0188677104766674167],"hpluv":[12.1770506300619488,201.08542320769223,20.7936643332181177],"hsluv":[12.1770506300619488,47.1205474310924046,20.7936643332181177]},"#552233":{"lch":[21.2623572347893699,28.8586800011052311,354.1745907436],"luv":[21.2623572347893699,28.7096478626609084,-2.92908364650122532],"rgb":[0.333333333333333315,0.133333333333333331,0.2],"xyz":[0.0491570842478803102,0.0331464488973282762,0.0351298643342785599],"hpluv":[354.1745907436,172.228245917758017,21.2623572347893699],"hsluv":[354.1745907436,52.8325366869496236,21.2623572347893699]},"#552244":{"lch":[21.9189283311679688,28.7014290952845421,329.54904741067952],"luv":[21.9189283311679688,24.7424491748557642,-14.5459011732283336],"rgb":[0.333333333333333315,0.133333333333333331,0.266666666666666663],"xyz":[0.0536150794920991908,0.0349296469950158492,0.0586086392871652],"hpluv":[329.54904741067952,166.158870546468904,21.9189283311679688],"hsluv":[329.54904741067952,59.1960886419386,21.9189283311679688]},"#552255":{"lch":[22.7630226511172538,33.9275210993755394,307.715012949244226],"luv":[22.7630226511172538,20.7546297224435,-26.8388157904337739],"rgb":[0.333333333333333315,0.133333333333333331,0.333333333333333315],"xyz":[0.0595774935314611828,0.0373146126107606821,0.0900106865611391138],"hpluv":[307.715012949244226,189.13048019699076,22.7630226511172538],"hsluv":[307.715012949244226,65.4333859354686211,22.7630226511172538]},"#552266":{"lch":[23.7863579144178132,42.6539605518829816,293.531429927677038],"luv":[23.7863579144178132,17.0296819355444384,-39.1069083914310625],"rgb":[0.333333333333333315,0.133333333333333331,0.4],"xyz":[0.0671624893049693611,0.0403486109201639936,0.129958330968283076],"hpluv":[293.531429927677038,227.546804006344104,23.7863579144178132],"hsluv":[293.531429927677038,71.0608597854246,23.7863579144178132]},"#552277":{"lch":[24.975052770659552,52.81712200152176,285.022920758889427],"luv":[24.975052770659552,13.6904851349353347,-51.0119495147337858],"rgb":[0.333333333333333315,0.133333333333333331,0.466666666666666674],"xyz":[0.0764765023251712805,0.04407421612824481,0.179012132874680985],"hpluv":[285.022920758889427,268.353735360872861,24.975052770659552],"hsluv":[285.022920758889427,75.8822745115455604,24.975052770659552]},"#552288":{"lch":[26.3119033569515395,63.3751525334233818,279.769698022236867],"luv":[26.3119033569515395,10.754023379801918,-62.4560720809542573],"rgb":[0.333333333333333315,0.133333333333333331,0.533333333333333326],"xyz":[0.0876169194271151086,0.0485303829690224,0.237684996278253152],"hpluv":[279.769698022236867,305.637106002952862,26.3119033569515395],"hsluv":[279.769698022236867,79.8897505498065357,26.3119033569515395]},"#552299":{"lch":[27.7783456471686065,73.9162973481211,276.357347681517297],"luv":[27.7783456471686065,8.18468635974612368,-73.4617582341209783],"rgb":[0.333333333333333315,0.133333333333333331,0.6],"xyz":[0.100673883536187808,0.0537531686126515654,0.306451673919371059],"hpluv":[276.357347681517297,337.654974874305083,27.7783456471686065],"hsluv":[276.357347681517297,83.1678045973750102,27.7783456471686065]},"#5522aa":{"lch":[29.3559430420228864,84.3037876124251824,274.032676149589577],"luv":[29.3559430420228864,5.92869585954675404,-84.0950603258353482],"rgb":[0.333333333333333315,0.133333333333333331,0.66666666666666663],"xyz":[0.115731576501440364,0.0597762457987526669,0.38575552353636966],"hpluv":[274.032676149589577,364.410076381253305,29.3559430420228864],"hsluv":[274.032676149589577,85.8312635149374898,29.3559430420228864]},"#5522bb":{"lch":[31.0273723986379082,94.5090555446981568,272.384235640696716],"luv":[31.0273723986379082,3.93164792491766635,-94.4272403734501324],"rgb":[0.333333333333333315,0.133333333333333331,0.733333333333333282],"xyz":[0.132869168608777,0.0666312826416874254,0.476013508635011406],"hpluv":[272.384235640696716,386.516244750379769,31.0273723986379082],"hsluv":[272.384235640696716,87.9935415010939437,31.0273723986379082]},"#5522cc":{"lch":[32.7769760620793207,104.54175742802569,271.176024316906762],"luv":[32.7769760620793207,2.1456208028374788,-104.519736688869415],"rgb":[0.333333333333333315,0.133333333333333331,0.8],"xyz":[0.152161544052498737,0.0743482328191762271,0.577620019305281507],"hpluv":[271.176024316906762,404.725193356887132,32.7769760620793207],"hsluv":[271.176024316906762,89.7538092894248507,32.7769760620793207]},"#5522dd":{"lch":[34.5909880118612847,114.421842397276407,270.265889656874094],"luv":[34.5909880118612847,0.530989812409553341,-114.420610326139567],"rgb":[0.333333333333333315,0.133333333333333331,0.866666666666666696],"xyz":[0.173679869603132281,0.0829555630394297611,0.690949867205287505],"hpluv":[270.265889656874094,419.744772471420788,34.5909880118612847],"hsluv":[270.265889656874094,91.1938440016712519,34.5909880118612847]},"#5522ee":{"lch":[36.4575428526747132,124.16924767107497,269.564389707514863],"luv":[36.4575428526747132,-0.94402906580191559,-124.165659005715739],"rgb":[0.333333333333333315,0.133333333333333331,0.933333333333333348],"xyz":[0.197492049869307018,0.092480435145899792,0.816360683273810728],"hpluv":[269.564389707514863,432.181309790662738,36.4575428526747132],"hsluv":[269.564389707514863,92.960018101107309,36.4575428526747132]},"#5522ff":{"lch":[38.3665568136218695,133.800754994484379,269.013084090219763],"luv":[38.3665568136218695,-2.30459494965050871,-133.780906258001124],"rgb":[0.333333333333333315,0.133333333333333331,1],"xyz":[0.223663098279138411,0.102948854509832488,0.954194871565592573],"hpluv":[269.013084090219763,442.532391911887146,38.3665568136218695],"hsluv":[269.013084090219763,99.9999999999994458,38.3665568136218695]},"#ccaa00":{"lch":[70.5858735612972623,80.4904122142546186,67.9906634155396],"luv":[70.5858735612972623,30.1643998932495876,74.6244962294604335],"rgb":[0.8,0.66666666666666663,0],"xyz":[0.392753797737474875,0.415879162748823417,0.059586129772359088],"hpluv":[67.9906634155396,144.699051457387782,70.5858735612972623],"hsluv":[67.9906634155396,100.000000000002373,70.5858735612972623]},"#ccaa11":{"lch":[70.6139482370970342,79.3332745728624786,67.7767588069511078],"luv":[70.6139482370970342,30.0051392857341135,73.4401802210267078],"rgb":[0.8,0.66666666666666663,0.0666666666666666657],"xyz":[0.393765463237112,0.416283828948678269,0.0649142347371147177],"hpluv":[67.7767588069511078,142.56214209062793,70.6139482370970342],"hsluv":[67.7767588069511078,98.4234445622979308,70.6139482370970342]},"#ccaa22":{"lch":[70.6659431154106,77.2098224605726529,67.3668792611096166],"luv":[70.6659431154106,29.7125737342128318,71.263733037795],"rgb":[0.8,0.66666666666666663,0.133333333333333331],"xyz":[0.395640821375589036,0.41703397220406907,0.0747911209330939103],"hpluv":[67.3668792611096166,138.644204697820271,70.6659431154106],"hsluv":[67.3668792611096166,95.5289103121581746,70.6659431154106]},"#ccaa33":{"lch":[70.7514162745237911,73.7740913884545,66.6515854645136159],"luv":[70.7514162745237911,29.2382542862800783,67.7328653349528622],"rgb":[0.8,0.66666666666666663,0.2],"xyz":[0.398728572108046742,0.418269072497052197,0.0910532747907050605],"hpluv":[66.6515854645136159,132.314688307412609,70.7514162745237911],"hsluv":[66.6515854645136159,90.8407422295077822,70.7514162745237911]},"#ccaa44":{"lch":[70.8745233475107597,68.9449101039795096,65.5199261400916271],"luv":[70.8745233475107597,28.5691680681362534,62.74713750555],"rgb":[0.8,0.66666666666666663,0.266666666666666663],"xyz":[0.403186567352265657,0.420052270594739763,0.114532049743591699],"hpluv":[65.5199261400916271,123.438713002021714,70.8745233475107597],"hsluv":[65.5199261400916271,84.237349466135143,70.8745233475107597]},"#ccaa55":{"lch":[71.0386313772099,62.7256766939065713,63.7915144306433959],"luv":[71.0386313772099,27.7020883768036121,56.2770363138665672],"rgb":[0.8,0.66666666666666663,0.333333333333333315],"xyz":[0.409148981391627642,0.422437236210484623,0.1459340970175656],"hpluv":[63.7915144306433959,112.044384698186093,71.0386313772099],"hsluv":[63.7915144306433959,75.6976413431368229,71.0386313772099]},"#ccaa66":{"lch":[71.2465086991263661,55.2096541299921952,61.1466680322388356],"luv":[71.2465086991263661,26.6424757380098143,48.3558103613508123],"rgb":[0.8,0.66666666666666663,0.4],"xyz":[0.416733977165135827,0.425471234519887942,0.185881741424709562],"hpluv":[61.1466680322388356,98.331070119416168,71.2465086991263661],"hsluv":[61.1466680322388356,65.2901205751262,71.2465086991263661]},"#ccaa77":{"lch":[71.5004247203994794,46.6032511345785068,56.9687004258729388],"luv":[71.5004247203994794,25.4032971934547263,39.0709035986321638],"rgb":[0.8,0.66666666666666663,0.466666666666666674],"xyz":[0.426047990185337733,0.429196839727968737,0.234935543331107471],"hpluv":[56.9687004258729388,82.707885898124573,71.5004247203994794],"hsluv":[56.9687004258729388,53.160756563752912,71.5004247203994794]},"#ccaa88":{"lch":[71.8022091544958556,37.3024926838847648,49.9478623796008847],"luv":[71.8022091544958556,24.003572993357885,28.5535364531929083],"rgb":[0.8,0.66666666666666663,0.533333333333333326],"xyz":[0.437188407287281533,0.433653006568746335,0.293608406734679639],"hpluv":[49.9478623796008847,65.9233659814751149,71.8022091544958556],"hsluv":[49.9478623796008847,39.5178130280575743,71.8022091544958556]},"#ccaa99":{"lch":[72.1532912119235874,28.1535194843350283,37.0598425499876214],"luv":[72.1532912119235874,22.4666918036374241,16.9666855559712388],"rgb":[0.8,0.66666666666666663,0.6],"xyz":[0.450245371396354233,0.438875792212375493,0.362375084375797574],"hpluv":[37.0598425499876214,49.5126161932360702,72.1532912119235874],"hsluv":[37.0598425499876214,26.6696495224772221,72.1532912119235874]},"#ccaaaa":{"lch":[72.5547286434336,21.297823518763618,12.177050630063027],"luv":[72.5547286434336,20.8186322940273918,4.49241984263274841],"rgb":[0.8,0.66666666666666663,0.66666666666666663],"xyz":[0.465303064361606789,0.444898869398476615,0.441678933992796174],"hpluv":[12.177050630063027,37.2485034287350203,72.5547286434336],"hsluv":[12.177050630063027,27.9047031904792959,72.5547286434336]},"#ccaabb":{"lch":[73.0072318845295,20.9674028584132515,335.544386587188285],"luv":[73.0072318845295,19.0862548050106788,-8.68025691700441193],"rgb":[0.8,0.66666666666666663,0.733333333333333282],"xyz":[0.482440656468943463,0.451753906241411374,0.531936919091437921],"hpluv":[335.544386587188285,36.4433325399841053,73.0072318845295],"hsluv":[335.544386587188285,29.1493731958161852,73.0072318845295]},"#ccaacc":{"lch":[73.5111862218870442,28.2733952257813925,307.715012949249683],"luv":[73.5111862218870442,17.2958067637387,-22.366044486780595],"rgb":[0.8,0.66666666666666663,0.8],"xyz":[0.501733031912665162,0.459470856418900175,0.633543429761708077],"hpluv":[307.715012949249683,48.8049486057506,73.5111862218870442],"hsluv":[307.715012949249683,30.3693282248248444,73.5111862218870442]},"#ccaadd":{"lch":[74.0666736076556,39.5441054640130645,293.032470315564865],"luv":[74.0666736076556,15.4717391639018693,-36.3917787995197202],"rgb":[0.8,0.66666666666666663,0.866666666666666696],"xyz":[0.523251357463298761,0.468078186639153682,0.746873277661714075],"hpluv":[293.032470315564865,67.7482749884916871,74.0666736076556],"hsluv":[293.032470315564865,52.1368854824616719,74.0666736076556]},"#ccaaee":{"lch":[74.6734949675833093,52.4074038625381462,285.081329657377239],"luv":[74.6734949675833093,13.6358764846886817,-50.6023601436286],"rgb":[0.8,0.66666666666666663,0.933333333333333348],"xyz":[0.54706353772947347,0.477603058745623699,0.872284093730237298],"hpluv":[285.081329657377239,89.0564736794959799,74.6734949675833093],"hsluv":[285.081329657377239,75.3315532053798194,74.6734949675833093]},"#ccaaff":{"lch":[75.3311933526529316,65.9300530396585458,280.316334998223624],"luv":[75.3311933526529316,11.8069327652914797,-64.8642292214135239],"rgb":[0.8,0.66666666666666663,1],"xyz":[0.573234586139304891,0.488071478109556423,1.01011828202201914],"hpluv":[280.316334998223624,111.057502918871393,75.3311933526529316],"hsluv":[280.316334998223624,99.9999999999973426,75.3311933526529316]},"#553300":{"lch":[24.6368918170402651,35.1311640480653367,43.6144672720514848],"luv":[24.6368918170402651,25.4348822629288698,24.2335604409056025],"rgb":[0.333333333333333315,0.2,0],"xyz":[0.049300031966319241,0.0429919833271212859,0.00570196001226947087],"hpluv":[43.6144672720514848,180.944734702515461,24.6368918170402651],"hsluv":[43.6144672720514848,100.000000000002245,24.6368918170402651]},"#553311":{"lch":[24.7639934196671305,31.9442274162558917,39.8156129865950632],"luv":[24.7639934196671305,24.536650698978292,20.4544967598277161],"rgb":[0.333333333333333315,0.2,0.0666666666666666657],"xyz":[0.0503116974659563593,0.0433966495269761388,0.0110300649770251023],"hpluv":[39.8156129865950632,163.685811409294416,24.7639934196671305],"hsluv":[39.8156129865950632,85.3309596574143256,24.7639934196671305]},"#553322":{"lch":[24.9975315322943885,26.9096454002331456,31.2519949010175395],"luv":[24.9975315322943885,23.0048892205904032,13.9608054035092266],"rgb":[0.333333333333333315,0.2,0.133333333333333331],"xyz":[0.0521870556044333814,0.0441467927823669601,0.0209069511730043],"hpluv":[31.2519949010175395,136.59983556614165,24.9975315322943885],"hsluv":[31.2519949010175395,60.4417762068684823,24.9975315322943885]},"#553333":{"lch":[25.3763514371309924,21.2787516643900716,12.1770506300621495],"luv":[25.3763514371309924,20.7999895475976082,4.48839695377019332],"rgb":[0.333333333333333315,0.2,0.2],"xyz":[0.0552748063368911219,0.0453818930753500729,0.0371691050306154416],"hpluv":[12.1770506300621495,106.403592780468983,25.3763514371309924],"hsluv":[12.1770506300621495,24.9336598370546909,25.3763514371309924]},"#553344":{"lch":[25.9113402150992655,19.4972565515274532,338.627269772390264],"luv":[25.9113402150992655,18.1564179844864455,-7.10545558065754257],"rgb":[0.333333333333333315,0.2,0.266666666666666663],"xyz":[0.05973280158111,0.047165091173037646,0.0606478799835020801],"hpluv":[338.627269772390264,95.4823185470749536,25.9113402150992655],"hsluv":[338.627269772390264,32.9723178491547841,25.9113402150992655]},"#553355":{"lch":[26.6061908173450519,25.0719265662328183,307.715012949245363],"luv":[26.6061908173450519,15.3373584467403763,-19.8334802195371829],"rgb":[0.333333333333333315,0.2,0.333333333333333315],"xyz":[0.065695215620472,0.0495500567887824789,0.0920499272574759886],"hpluv":[307.715012949245363,119.576085528419512,26.6061908173450519],"hsluv":[307.715012949245363,41.369683748934996,26.6061908173450519]},"#553366":{"lch":[27.4586282592714284,35.2024776289392847,290.893042573756475],"luv":[27.4586282592714284,12.5540679631371699,-32.8878367910220533],"rgb":[0.333333333333333315,0.2,0.4],"xyz":[0.0732802113939801658,0.0525840550981857904,0.13199757166461995],"hpluv":[290.893042573756475,162.679833835368925,27.4586282592714284],"hsluv":[290.893042573756475,49.429407074258,27.4586282592714284]},"#553377":{"lch":[28.461655060413058,46.8206771520520633,282.253113271302652],"luv":[28.461655060413058,9.93678843358592445,-45.7540822725452898],"rgb":[0.333333333333333315,0.2,0.466666666666666674],"xyz":[0.0825942244141820853,0.0563096603062666068,0.18105137357101786],"hpluv":[282.253113271302652,208.74537696470955,28.461655060413058],"hsluv":[282.253113271302652,56.732994513665389,28.461655060413058]},"#553388":{"lch":[29.6048600369324433,58.6666973974172876,277.388246485053742],"luv":[29.6048600369324433,7.54407762538358551,-58.1796207988872567],"rgb":[0.333333333333333315,0.2,0.533333333333333326],"xyz":[0.0937346415161259133,0.0607658271470442046,0.239724236974590027],"hpluv":[277.388246485053742,251.459446283522851,29.6048600369324433],"hsluv":[277.388246485053742,63.1061783000114715,29.6048600369324433]},"#553399":{"lch":[30.8756880539778678,70.2946203588512759,274.394660626066695],"luv":[30.8756880539778678,5.38640350826703,-70.0879469569565714],"rgb":[0.333333333333333315,0.2,0.6],"xyz":[0.106791605625198627,0.0659886127906733622,0.308490914615707934],"hpluv":[274.394660626066695,288.898157334443908,30.8756880539778678],"hsluv":[274.394660626066695,68.537799314251,30.8756880539778678]},"#5533aa":{"lch":[32.2605562861205,81.571224268378316,272.422737250332261],"luv":[32.2605562861205,3.44819039224039026,-81.498310483475251],"rgb":[0.333333333333333315,0.2,0.66666666666666663],"xyz":[0.121849298590451169,0.0720116899767744567,0.387794764232706535],"hpluv":[272.422737250332261,320.851781583216223,32.2605562861205],"hsluv":[272.422737250332261,73.1042224024611897,32.2605562861205]},"#5533bb":{"lch":[33.7457437232739395,92.4864953275551755,271.055064965734516],"luv":[33.7457437232739395,1.70298313903478205,-92.4708152143261231],"rgb":[0.333333333333333315,0.2,0.733333333333333282],"xyz":[0.138986890697787802,0.0788667268197092153,0.478052749331348281],"hpluv":[271.055064965734516,347.775228922495899,33.7457437232739395],"hsluv":[271.055064965734516,76.9172199670655772,33.7457437232739395]},"#5533cc":{"lch":[35.3180325241442,103.075547069605378,270.067872161558512],"luv":[35.3180325241442,0.12210251098248695,-103.075474748725966],"rgb":[0.333333333333333315,0.2,0.8],"xyz":[0.158279266141509556,0.0865836769971980169,0.579659260001618493],"hpluv":[270.067872161558512,370.338167129355497,35.3180325241442],"hsluv":[270.067872161558512,80.0940957669769205,35.3180325241442]},"#5533dd":{"lch":[36.9651203282397915,113.385246995104879,269.332372034398134],"luv":[36.9651203282397915,-1.32116971635525937,-113.377549570986602],"rgb":[0.333333333333333315,0.2,0.866666666666666696],"xyz":[0.179797591692143099,0.0951910072174515509,0.69298910790162449],"hpluv":[269.332372034398134,389.227711455139399,36.9651203282397915],"hsluv":[269.332372034398134,84.8119298710034855,36.9651203282397915]},"#5533ee":{"lch":[38.6758450270606247,123.460606758128,268.77009087446072],"luv":[38.6758450270606247,-2.64999738284680575,-123.432163292052948],"rgb":[0.333333333333333315,0.2,0.933333333333333348],"xyz":[0.203609771958317837,0.104715879323921596,0.818399923970147714],"hpluv":[268.77009087446072,405.067987408818738,38.6758450270606247],"hsluv":[268.77009087446072,92.2936685874649356,38.6758450270606247]},"#5533ff":{"lch":[40.4402700894382363,133.340096114557781,268.33094335317071],"luv":[40.4402700894382363,-3.88371885476632706,-133.283524712158766],"rgb":[0.333333333333333315,0.2,1],"xyz":[0.22978082036814923,0.115184298687854292,0.956234112261929559],"hpluv":[268.33094335317071,418.394573227645935,40.4402700894382363],"hsluv":[268.33094335317071,99.99999999999946,40.4402700894382363]},"#ccbb00":{"lch":[75.0632334950121418,83.0331806403360275,77.5616137481136292],"luv":[75.0632334950121418,17.8844849446013434,81.0842419062853423],"rgb":[0.8,0.733333333333333282,0],"xyz":[0.426708295646073654,0.483788158566022,0.0709042957418917],"hpluv":[77.5616137481136292,140.366584388758554,75.0632334950121418],"hsluv":[77.5616137481136292,100.000000000002373,75.0632334950121418]},"#ccbb11":{"lch":[75.0886164663743898,81.9438461169387438,77.472162284636525],"luv":[75.0886164663743898,17.7747618107910519,79.9928231718707394],"rgb":[0.8,0.733333333333333282,0.0666666666666666657],"xyz":[0.427719961145710759,0.484192824765876828,0.0762324007066473436],"hpluv":[77.472162284636525,138.478250548668058,75.0886164663743898],"hsluv":[77.472162284636525,98.6397508878022222,75.0886164663743898]},"#ccbb22":{"lch":[75.1356323460541802,79.9401497843360289,77.301186242421764],"luv":[75.1356323460541802,17.5729239259544805,77.9847414064744839],"rgb":[0.8,0.733333333333333282,0.133333333333333331],"xyz":[0.429595319284187815,0.484942968021267629,0.0861092869026265362],"hpluv":[77.301186242421764,135.007637737713509,75.1356323460541802],"hsluv":[77.301186242421764,96.1390577710114087,75.1356323460541802]},"#ccbb33":{"lch":[75.2129378077961235,76.6847204783522471,77.0041162235267223],"luv":[75.2129378077961235,17.2449407213965777,74.720535158405653],"rgb":[0.8,0.733333333333333282,0.2],"xyz":[0.432683070016645521,0.486178068314250755,0.102371440760237686],"hpluv":[77.0041162235267223,129.376563997369885,75.2129378077961235],"hsluv":[77.0041162235267223,92.0797058264172392,75.2129378077961235]},"#ccbb44":{"lch":[75.3243183189310628,72.0782997366288,76.5373230188340585],"luv":[75.3243183189310628,16.7806861485978907,70.0977165484408431],"rgb":[0.8,0.733333333333333282,0.266666666666666663],"xyz":[0.437141065260864436,0.487961266411938321,0.125850215713124325],"hpluv":[76.5373230188340585,121.425150369898518,75.3243183189310628],"hsluv":[76.5373230188340585,86.34290383100182,75.3243183189310628]},"#ccbb55":{"lch":[75.4728625341146397,66.0852327898053,75.831238609121371],"luv":[75.4728625341146397,16.1762634357197506,64.0748507149330351],"rgb":[0.8,0.733333333333333282,0.333333333333333315],"xyz":[0.443103479300226422,0.490346232027683182,0.157252262987098212],"hpluv":[75.831238609121371,111.10994393806304,75.4728625341146397],"hsluv":[75.831238609121371,78.8905565478608395,75.4728625341146397]},"#ccbb66":{"lch":[75.6611363515091284,58.7289677793131,74.7643785098968863],"luv":[75.6611363515091284,15.4333320312120961,56.6648384700597134],"rgb":[0.8,0.733333333333333282,0.4],"xyz":[0.450688475073734607,0.493380230337086501,0.197199907394242202],"hpluv":[74.7643785098968863,98.4960546107130739,75.6611363515091284],"hsluv":[74.7643785098968863,69.7569980114599701,75.6611363515091284]},"#ccbb77":{"lch":[75.8912747684230737,50.090867045562554,73.1036630558194389],"luv":[75.8912747684230737,14.5584607724557671,47.9285528814827799],"rgb":[0.8,0.733333333333333282,0.466666666666666674],"xyz":[0.460002488093936512,0.497105835545167296,0.246253709300640111],"hpluv":[73.1036630558194389,83.7540906733876795,75.8912747684230737],"hsluv":[73.1036630558194389,59.0406908273499624,75.8912747684230737]},"#ccbb88":{"lch":[76.1650362860674335,40.3168412407358332,70.3426656865815119],"luv":[76.1650362860674335,13.5623472284534756,37.9672283066009157],"rgb":[0.8,0.733333333333333282,0.533333333333333326],"xyz":[0.471142905195880313,0.501562002385944838,0.304926572704212251],"hpluv":[70.3426656865815119,67.6831847004182379,76.1650362860674335],"hsluv":[70.3426656865815119,46.8939441374685586,76.1650362860674335]},"#ccbb99":{"lch":[76.4838383644648871,29.6573629081618826,65.1594516064859732],"luv":[76.4838383644648871,12.4588924968264081,26.9134756658990248],"rgb":[0.8,0.733333333333333282,0.6],"xyz":[0.484199869304953068,0.506784788029574,0.373693250345330186],"hpluv":[65.1594516064859732,50.6096239917615662,76.4838383644648871],"hsluv":[65.1594516064859732,33.5105935092195324,76.4838383644648871]},"#ccbbaa":{"lch":[76.8487828748923,18.695758935396551,52.9508743401004551],"luv":[76.8487828748923,11.26418644921627,14.9214444946778713],"rgb":[0.8,0.733333333333333282,0.66666666666666663],"xyz":[0.499257562270205568,0.512807865215675118,0.452997099962328786],"hpluv":[52.9508743401004551,32.5142912020767696,76.8487828748923],"hsluv":[52.9508743401004551,19.1124274046376854,76.8487828748923]},"#ccbbbb":{"lch":[77.2606763328388126,10.2255548171674207,12.1770506300639045],"luv":[77.2606763328388126,9.99548454110707,2.15690985147396086],"rgb":[0.8,0.733333333333333282,0.733333333333333282],"xyz":[0.516395154377542243,0.519662902058609877,0.543255085060970533],"hpluv":[12.1770506300639045,18.1733155366010308,77.2606763328388126],"hsluv":[12.1770506300639045,17.1437484893634,77.2606763328388126]},"#ccbbcc":{"lch":[77.7200476270310361,14.1732404034447406,307.715012949257925],"luv":[77.7200476270310361,8.67025786172679247,-11.2119299027867267],"rgb":[0.8,0.733333333333333282,0.8],"xyz":[0.535687529821264,0.527379852236098734,0.644861595731240689],"hpluv":[307.715012949257925,25.815587331502627,77.7200476270310361],"hsluv":[307.715012949257925,18.1614974693692588,77.7200476270310361]},"#ccbbdd":{"lch":[78.2271648233418375,26.0669286991650679,286.275412631614586],"luv":[78.2271648233418375,7.3053819239814537,-25.022313377306272],"rgb":[0.8,0.733333333333333282,0.866666666666666696],"xyz":[0.557205855371897485,0.53598718245635224,0.758191443631246687],"hpluv":[286.275412631614586,48.8074477639820898,78.2271648233418375],"hsluv":[286.275412631614586,43.4510455050629929,78.2271648233418375]},"#ccbbee":{"lch":[78.7820519440635,39.5678846485468299,278.599571826643512],"luv":[78.7820519440635,5.9165048525659989,-39.1230426461218741],"rgb":[0.8,0.733333333333333282,0.933333333333333348],"xyz":[0.581018035638072305,0.545512054562822257,0.88360225969976991],"hpluv":[278.599571826643512,76.4037468789834,78.7820519440635],"hsluv":[278.599571826643512,70.6968150087455314,78.7820519440635]},"#ccbbff":{"lch":[79.3845061922316546,53.5695670840829834,274.837592460092935],"luv":[79.3845061922316546,4.51760925339512553,-53.3787385033564235],"rgb":[0.8,0.733333333333333282,1],"xyz":[0.607189084047903616,0.555980473926755,1.02143644799155164],"hpluv":[274.837592460092935,107.038572744282547,79.3845061922316546],"hsluv":[274.837592460092935,99.9999999999963762,79.3845061922316546]},"#554400":{"lch":[29.5776499109456879,34.0768703371065413,65.9474553070004674],"luv":[29.5776499109456879,13.8888553561515469,31.1180460322924546],"rgb":[0.333333333333333315,0.266666666666666663,0],"xyz":[0.0581326024492852811,0.0606571242930536,0.0086461501732580659],"hpluv":[65.9474553070004674,146.195957524823825,29.5776499109456879],"hsluv":[65.9474553070004674,100.000000000002217,29.5776499109456879]},"#554411":{"lch":[29.6787804923011507,30.8713815411758574,64.2244588846852906],"luv":[29.6787804923011507,13.4243191404277429,27.7998175151708296],"rgb":[0.333333333333333315,0.266666666666666663,0.0666666666666666657],"xyz":[0.0591442679489224,0.0610617904929084548,0.0139742551380136974],"hpluv":[64.2244588846852906,131.992525946838612,29.6787804923011507],"hsluv":[64.2244588846852906,89.4077694450363509,29.6787804923011507]},"#554422":{"lch":[29.8650740872788916,25.3442505658492152,60.1547603291711539],"luv":[29.8650740872788916,12.6127938179319639,21.9829131111162219],"rgb":[0.333333333333333315,0.266666666666666663,0.133333333333333331],"xyz":[0.0610196260873994215,0.0618119337482992762,0.0238511413339928952],"hpluv":[60.1547603291711539,107.684992873038837,29.8650740872788916],"hsluv":[60.1547603291711539,70.9921927199271892,29.8650740872788916]},"#554433":{"lch":[30.1685472793317686,17.4710669916127905,49.2680266756281497],"luv":[30.1685472793317686,11.400244593092479,13.2390560480378525],"rgb":[0.333333333333333315,0.266666666666666663,0.2],"xyz":[0.064107376819857162,0.0630470340412823821,0.0401132951916040384],"hpluv":[49.2680266756281497,73.4859575586117302,30.1685472793317686],"hsluv":[49.2680266756281497,43.7071568358896,30.1685472793317686]},"#554444":{"lch":[30.5997780424982437,10.1013456632853149,12.1770506300629258],"luv":[30.5997780424982437,9.87407003600776356,2.13071000682558],"rgb":[0.333333333333333315,0.266666666666666663,0.266666666666666663],"xyz":[0.0685653720640760356,0.0648302321389699621,0.06359207014449067],"hpluv":[12.1770506300629258,41.8890279889816597,30.5997780424982437],"hsluv":[12.1770506300629258,9.81589763549682282,30.5997780424982437]},"#554455":{"lch":[31.1643459369041338,13.3310860490153988,307.715012949249],"luv":[31.1643459369041338,8.15508312366709198,-10.5457325251654854],"rgb":[0.333333333333333315,0.266666666666666663,0.333333333333333315],"xyz":[0.0745277861034380346,0.0672151977547148,0.0949941174184645853],"hpluv":[307.715012949249,54.2808752323906702,31.1643459369041338],"hsluv":[307.715012949249,18.7795296363480162,31.1643459369041338]},"#554466":{"lch":[31.8635722620044533,24.8340912161126894,284.841165372516684],"luv":[31.8635722620044533,6.36101223964894835,-24.005616214070443],"rgb":[0.333333333333333315,0.266666666666666663,0.4],"xyz":[0.0821127818769462,0.0702491960641181135,0.134941761825608547],"hpluv":[284.841165372516684,98.8992811700442331,31.8635722620044533],"hsluv":[284.841165372516684,27.8963704264996828,31.8635722620044533]},"#554477":{"lch":[32.6951743277909443,37.9095930577936784,276.944338121378166],"luv":[32.6951743277909443,4.58346102749711282,-37.6314912117090259],"rgb":[0.333333333333333315,0.266666666666666663,0.466666666666666674],"xyz":[0.0914267948971481254,0.0739748012721989229,0.183995563732006456],"hpluv":[276.944338121378166,147.131204947893167,32.6951743277909443],"hsluv":[276.944338121378166,36.6308714978363952,32.6951743277909443]},"#554488":{"lch":[33.6539551717380903,51.1018638808679526,273.231940865766],"luv":[33.6539551717380903,2.88102600900669881,-51.0205858574182116],"rgb":[0.333333333333333315,0.266666666666666663,0.533333333333333326],"xyz":[0.102567211999091953,0.0784309681129765207,0.242668427135578624],"hpluv":[273.231940865766,192.681471981123309,33.6539551717380903],"hsluv":[273.231940865766,44.6505812495932801,33.6539551717380903]},"#554499":{"lch":[34.7325237210335871,63.9719124096453271,271.149517924849135],"luv":[34.7325237210335871,1.28337422751110575,-63.9590378909774913],"rgb":[0.333333333333333315,0.266666666666666663,0.6],"xyz":[0.115624176108164667,0.0836537537566056782,0.311435104776696559],"hpluv":[271.149517924849135,233.718085138698228,34.7325237210335871],"hsluv":[271.149517924849135,51.7999710200133876,34.7325237210335871]},"#5544aa":{"lch":[35.9219992682327671,76.3678985235758461,269.849629436139082],"luv":[35.9219992682327671,-0.200424374653859844,-76.367635520403681],"rgb":[0.333333333333333315,0.266666666666666663,0.66666666666666663],"xyz":[0.130681869073417223,0.0896768309427067867,0.390738954393695104],"hpluv":[269.849629436139082,269.767524553786757,35.9219992682327671],"hsluv":[269.849629436139082,58.0490239963672465,35.9219992682327671]},"#5544bb":{"lch":[37.2126506061998725,88.2627815084196925,268.978337620063314],"luv":[37.2126506061998725,-1.57376312233016602,-88.2487499584998574],"rgb":[0.333333333333333315,0.266666666666666663,0.733333333333333282],"xyz":[0.147819461180753842,0.0965318677856415452,0.480996939492336906],"hpluv":[268.978337620063314,300.972163983169935,37.2126506061998725],"hsluv":[268.978337620063314,66.0075029321504729,37.2126506061998725]},"#5544cc":{"lch":[38.5944341452357733,99.6871153018899605,268.363808876145868],"luv":[38.5944341452357733,-2.84637030136680202,-99.6464707519528758],"rgb":[0.333333333333333315,0.266666666666666663,0.8],"xyz":[0.167111836624475596,0.104248817963130347,0.582603450162607062],"hpluv":[268.363808876145868,327.758284181939189,38.5944341452357733],"hsluv":[268.363808876145868,74.5283681063652352,38.5944341452357733]},"#5544dd":{"lch":[40.0574145710935738,110.694467066426,267.913412719582],"luv":[40.0574145710935738,-4.03035995406870118,-110.621070496360275],"rgb":[0.333333333333333315,0.266666666666666663,0.866666666666666696],"xyz":[0.18863016217510914,0.112856148183383881,0.695933298062613059],"hpluv":[267.913412719582,350.65684831918054,40.0574145710935738],"hsluv":[267.913412719582,82.9425769408534,40.0574145710935738]},"#5544ee":{"lch":[41.5920687629554777,121.343449115737442,267.573227144435918],"luv":[41.5920687629554777,-5.13798666158471651,-121.23462268002875],"rgb":[0.333333333333333315,0.266666666666666663,0.933333333333333348],"xyz":[0.212442342441283877,0.122381020289853898,0.821344114131136283],"hpluv":[267.573227144435918,370.207437425804358,41.5920687629554777],"hsluv":[267.573227144435918,91.3878688389195872,41.5920687629554777]},"#5544ff":{"lch":[43.1894854939413833,131.689092168021887,267.309962581974105],"luv":[43.1894854939413833,-6.18053297470727,-131.543977468321657],"rgb":[0.333333333333333315,0.266666666666666663,1],"xyz":[0.23861339085111527,0.132849439653786594,0.959178302422918128],"hpluv":[267.309962581974105,386.911020330846497,43.1894854939413833],"hsluv":[267.309962581974105,99.9999999999994174,43.1894854939413833]},"#cccc00":{"lch":[79.627228346343,87.7811065558180132,85.8743202181747449],"luv":[79.627228346343,6.31536666608958797,87.5536339167982192],"rgb":[0.8,0.8,0],"xyz":[0.464932038955690574,0.560235645185256814,0.0836455435117636481],"hpluv":[85.8743202181747449,177.871840357077815,79.627228346343],"hsluv":[85.8743202181747449,100.000000000002245,79.627228346343]},"#cccc11":{"lch":[79.6502471087807891,86.7718911178833707,85.8743202181747],"luv":[79.6502471087807891,6.24275917928854351,86.5470337215737],"rgb":[0.8,0.8,0.0666666666666666657],"xyz":[0.465943704455327679,0.560640311385111723,0.0889736484765192848],"hpluv":[85.8743202181747,176.061859354342118,79.6502471087807891],"hsluv":[85.8743202181747,98.8217369524532927,79.6502471087807891]},"#cccc22":{"lch":[79.6928884771461838,84.9132131482774497,85.8743202181746597],"luv":[79.6928884771461838,6.10903754655005482,84.6931722597497298],"rgb":[0.8,0.8,0.133333333333333331],"xyz":[0.467819062593804735,0.561390454640502523,0.0988505346724984774],"hpluv":[85.8743202181746597,172.717957044242922,79.6928884771461838],"hsluv":[85.8743202181746597,96.653203912443459,79.6928884771461838]},"#cccc33":{"lch":[79.7630142061039891,81.8867831673476445,85.8743202181745602],"luv":[79.7630142061039891,5.89130259459140682,81.6745848549912665],"rgb":[0.8,0.8,0.2],"xyz":[0.470906813326262441,0.56262555493348565,0.115112688530109614],"hpluv":[85.8743202181745602,167.243641009868185,79.7630142061039891],"hsluv":[85.8743202181745602,93.1263971058523623,79.7630142061039891]},"#cccc44":{"lch":[79.8640786601047523,77.5899505798540901,85.8743202181744],"luv":[79.8640786601047523,5.58216917901353593,77.3888869169280156],"rgb":[0.8,0.8,0.266666666666666663],"xyz":[0.475364808570481356,0.564408753031173216,0.138591463482996252],"hpluv":[85.8743202181744,159.406599578518,79.8640786601047523],"hsluv":[85.8743202181744,88.1281264379617113,79.8640786601047523]},"#cccc55":{"lch":[79.9989166638852396,71.9729259129294832,85.8743202181741481],"luv":[79.9989166638852396,5.17805522174052,71.7864179952492236],"rgb":[0.8,0.8,0.333333333333333315],"xyz":[0.481327222609843342,0.566793718646918,0.169993510756970168],"hpluv":[85.8743202181741481,149.042041148428552,79.9989166638852396],"hsluv":[85.8743202181741481,81.6104176612222147,79.9989166638852396]},"#cccc66":{"lch":[80.1699032642976448,65.0330295388014,85.8743202181738],"luv":[80.1699032642976448,4.67876793832737103,64.8645054060685453],"rgb":[0.8,0.8,0.4],"xyz":[0.488912218383351527,0.569827716956321284,0.209941155164114129],"hpluv":[85.8743202181738,136.038559250079544,80.1699032642976448],"hsluv":[85.8743202181738,73.5839630734023,80.1699032642976448]},"#cccc77":{"lch":[80.3790384438565724,56.8098315426934803,85.8743202181733096],"luv":[80.3790384438565724,4.0871541782499472,56.6626166941875837],"rgb":[0.8,0.8,0.466666666666666674],"xyz":[0.498226231403553432,0.573553322164402135,0.258994957070512],"hpluv":[85.8743202181733096,120.326663009793734,80.3790384438565724],"hsluv":[85.8743202181733096,64.1122831116318252,80.3790384438565724]},"#cccc88":{"lch":[80.6279973255091704,47.3795499902223085,85.8743202181724854],"luv":[80.6279973255091704,3.40869741112766222,47.2567724166107865],"rgb":[0.8,0.8,0.533333333333333326],"xyz":[0.509366648505497288,0.578009489005179677,0.317667820474084206],"hpluv":[85.8743202181724854,101.866799769447482,80.6279973255091704],"hsluv":[85.8743202181724854,53.3047126681541172,80.6279973255091704]},"#cccc99":{"lch":[80.9181626169042119,36.8483625211582861,85.8743202181711496],"luv":[80.9181626169042119,2.65103653276840934,36.7528750683892724],"rgb":[0.8,0.8,0.6],"xyz":[0.522423612614569932,0.58323227464880889,0.386434498115202141],"hpluv":[85.8743202181711496,80.635831276566,80.9181626169042119],"hsluv":[85.8743202181711496,41.30786304104587,80.9181626169042119]},"#ccccaa":{"lch":[81.2506473976222452,25.3448572993520607,85.8743202181683216],"luv":[81.2506473976222452,1.82342275263520492,25.27917959487],"rgb":[0.8,0.8,0.66666666666666663],"xyz":[0.537481305579822544,0.58925535183491,0.465738347732200686],"hpluv":[85.8743202181683216,56.6117825452175509,81.2506473976222452],"hsluv":[85.8743202181683216,28.2959036617823898,81.2506473976222452]},"#ccccbb":{"lch":[81.6263125989092657,13.0121158497344798,85.8743202181599],"luv":[81.6263125989092657,0.936149997616518514,12.9783967449324749],"rgb":[0.8,0.8,0.733333333333333282],"xyz":[0.554618897687159107,0.596110388677844716,0.555996332830842488],"hpluv":[85.8743202181599,29.7570160502500514,81.6263125989092657],"hsluv":[85.8743202181599,14.4603328966824272,81.6263125989092657]},"#cccccc":{"lch":[82.0457816743453,4.34523248843710382e-12,0],"luv":[82.0457816743453,4.08534684758697557e-12,1.48019813318368677e-12],"rgb":[0.8,0.8,0.8],"xyz":[0.573911273130880861,0.603827338855333573,0.657602843501112644],"hpluv":[0,1.02065966511349575e-11,82.0457816743453],"hsluv":[0,1.01642596056880755e-11,82.0457816743453]},"#ccccdd":{"lch":[82.5094539517328087,13.5418343873660199,265.874320218194214],"luv":[82.5094539517328087,-0.974260325972223118,-13.5067425899839115],"rgb":[0.8,0.8,0.866666666666666696],"xyz":[0.59542959868151446,0.612434669075587079,0.770932691401118642],"hpluv":[265.874320218194214,32.7843842039110882,82.5094539517328087],"hsluv":[265.874320218194214,30.4637656032122131,82.5094539517328087]},"#ccccee":{"lch":[83.0175175610870895,27.4698052042972165,265.874320218185687],"luv":[83.0175175610870895,-1.97630103922669687,-27.3986209901955817],"rgb":[0.8,0.8,0.933333333333333348],"xyz":[0.61924177894768917,0.621959541182057096,0.896343507469641865],"hpluv":[265.874320218185687,68.7964750954906776,83.0175175610870895],"hsluv":[265.874320218185687,63.7216981471091941,83.0175175610870895]},"#ccccff":{"lch":[83.5699624582004219,41.6509292947620153,265.874320218182845],"luv":[83.5699624582004219,-2.99655473483939438,-41.5429966521238825],"rgb":[0.8,0.8,1],"xyz":[0.645412827357520591,0.63242796054598982,1.03417769576142371],"hpluv":[265.874320218182845,108.336501116640306,83.5699624582004219],"hsluv":[265.874320218182845,99.9999999999952536,83.5699624582004219]},"#555500":{"lch":[34.8595382729148753,38.4291768930055397,85.8743202181747307],"luv":[34.8595382729148753,2.76476741155027961,38.3295929776711901],"rgb":[0.333333333333333315,0.333333333333333315,0],"xyz":[0.0699458591636312466,0.084283637721745866,0.0125839024113732767],"hpluv":[85.8743202181747307,139.887458074797564,34.8595382729148753],"hsluv":[85.8743202181747307,100.000000000002331,34.8595382729148753]},"#555511":{"lch":[34.9408046802893,35.5443725161734108,85.8743202181745318],"luv":[34.9408046802893,2.55722164100294558,35.4522641737772517],"rgb":[0.333333333333333315,0.333333333333333315,0.0666666666666666657],"xyz":[0.0709575246632683648,0.0846883039216007188,0.0179120073761289064],"hpluv":[85.8743202181745318,129.085444875460666,34.9408046802893],"hsluv":[85.8743202181745318,92.2780688504912,34.9408046802893]},"#555522":{"lch":[35.0907688239250604,30.4130442263608813,85.8743202181740202],"luv":[35.0907688239250604,2.18805086034508589,30.3342330139914047],"rgb":[0.333333333333333315,0.333333333333333315,0.133333333333333331],"xyz":[0.0728328828017454,0.0854384471769915332,0.027788893572108106],"hpluv":[85.8743202181740202,109.978131404858061,35.0907688239250604],"hsluv":[85.8743202181740202,78.6190076783406653,35.0907688239250604]},"#555533":{"lch":[35.3357817552570097,22.5221214621125654,85.8743202181728549],"luv":[35.3357817552570097,1.62034247131604014,22.4637584885032275],"rgb":[0.333333333333333315,0.333333333333333315,0.2],"xyz":[0.0759206335342031274,0.0866735474699746461,0.0440510474297192492],"hpluv":[85.8743202181728549,80.8786547215116656,35.3357817552570097],"hsluv":[85.8743202181728549,57.8169450175211566,35.3357817552570097]},"#555544":{"lch":[35.6854507669058592,12.1926559388895619,85.8743202181691743],"luv":[35.6854507669058592,0.877194374836262392,12.1610603515028455],"rgb":[0.333333333333333315,0.333333333333333315,0.266666666666666663],"xyz":[0.080378628778422,0.0884567455676622261,0.0675298223826058808],"hpluv":[85.8743202181691743,43.355725530805,35.6854507669058592],"hsluv":[85.8743202181691743,30.9932899828832262,35.6854507669058592]},"#555555":{"lch":[36.1458508397197278,1.89718584003012571e-12,0],"luv":[36.1458508397197278,1.79982851973451413e-12,5.9994283991150471e-13],"rgb":[0.333333333333333315,0.333333333333333315,0.333333333333333315],"xyz":[0.086341042817784,0.090841711183407059,0.0989318696565798],"hpluv":[0,6.66025333978279224e-12,36.1458508397197278],"hsluv":[0,1.90696849203660445e-12,36.1458508397197278]},"#555566":{"lch":[36.7200402720523087,13.391014832031539,265.874320218184835],"luv":[36.7200402720523087,-0.963409690459316,-13.3563138627398903],"rgb":[0.333333333333333315,0.333333333333333315,0.4],"xyz":[0.0939260385912921714,0.0938757094928103775,0.138879514063723758],"hpluv":[265.874320218184835,46.2753453717946712,36.7200402720523087],"hsluv":[265.874320218184835,10.0205788523093844,36.7200402720523087]},"#555577":{"lch":[37.4084382237490445,27.3651172837118537,265.874320218181],"luv":[37.4084382237490445,-1.96876932050326592,-27.294204353927416],"rgb":[0.333333333333333315,0.333333333333333315,0.466666666666666674],"xyz":[0.103240051611494091,0.0976013147008911869,0.187933315970121667],"hpluv":[265.874320218181,92.8254499938530131,37.4084382237490445],"hsluv":[265.874320218181,20.457601163446,37.4084382237490445]},"#555588":{"lch":[38.2091925227490421,41.4380747403329508,265.874320218179832],"luv":[38.2091925227490421,-2.98124102314999906,-41.330693680935326],"rgb":[0.333333333333333315,0.333333333333333315,0.533333333333333326],"xyz":[0.114380468713437919,0.102057481541668785,0.246606179373693835],"hpluv":[265.874320218179832,137.616667264503377,38.2091925227490421],"hsluv":[265.874320218179832,30.9677616121988244,38.2091925227490421]},"#555599":{"lch":[39.1185695394092079,55.2798607696674651,265.874320218179207],"luv":[39.1185695394092079,-3.97708121608675258,-55.1366106295487626],"rgb":[0.333333333333333315,0.333333333333333315,0.6],"xyz":[0.127437432822510632,0.107280267185297942,0.315372857014811769],"hpluv":[265.874320218179207,179.317758559659353,39.1185695394092079],"hsluv":[265.874320218179207,41.3377460212352688,39.1185695394092079]},"#5555aa":{"lch":[40.1313601009005083,68.6985541131433166,265.874320218178866],"luv":[40.1313601009005083,-4.94248222285034178,-68.5205312786852829],"rgb":[0.333333333333333315,0.333333333333333315,0.66666666666666663],"xyz":[0.142495125787763188,0.113303344371399051,0.394676706631810315],"hpluv":[265.874320218178866,217.221618066114,40.1313601009005083],"hsluv":[265.874320218178866,51.4705865731736907,40.1313601009005083]},"#5555bb":{"lch":[41.2412811653463791,81.6070675548115787,265.874320218178639],"luv":[41.2412811653463791,-5.8711785983783864,-81.3955940869131],"rgb":[0.333333333333333315,0.333333333333333315,0.733333333333333282],"xyz":[0.159632717895099807,0.120158381214333809,0.484934691730452117],"hpluv":[265.874320218178639,251.093199488524249,41.2412811653463791],"hsluv":[265.874320218178639,61.3584924374872642,41.2412811653463791]},"#5555cc":{"lch":[42.4413509436270431,93.9883543596933,265.874320218178468],"luv":[42.4413509436270431,-6.76194392407029365,-93.7447964935174838],"rgb":[0.333333333333333315,0.333333333333333315,0.8],"xyz":[0.178925093338821561,0.127875331391822611,0.586541202400722272],"hpluv":[265.874320218178468,281.011551484187919,42.4413509436270431],"hsluv":[265.874320218178468,71.0546332315999791,42.4413509436270431]},"#5555dd":{"lch":[43.7242196004532389,105.866759380085014,265.874320218178411],"luv":[43.7242196004532389,-7.61652967783202328,-105.592420264465588],"rgb":[0.333333333333333315,0.333333333333333315,0.866666666666666696],"xyz":[0.200443418889455105,0.136482661612076145,0.69987105030072827],"hpluv":[265.874320218178411,307.239379297131052,43.7242196004532389],"hsluv":[265.874320218178411,80.6500300064864462,43.7242196004532389]},"#5555ee":{"lch":[45.0824447652298588,117.287521338877212,265.874320218178354],"luv":[45.0824447652298588,-8.43819053636753402,-116.983586892732674],"rgb":[0.333333333333333315,0.333333333333333315,0.933333333333333348],"xyz":[0.224255599155629842,0.146007533718546162,0.825281866369251493],"hpluv":[265.874320218178354,330.128999417958312,45.0824447652298588],"hsluv":[265.874320218178354,90.2572110855712708,45.0824447652298588]},"#5555ff":{"lch":[46.508708270344421,128.30356479361032,265.874320218178241],"luv":[46.508708270344421,-9.23073412981071,-127.971083789162734],"rgb":[0.333333333333333315,0.333333333333333315,1],"xyz":[0.250426647565461236,0.156475953082478858,0.963116054661033338],"hpluv":[265.874320218178241,350.061034522531031,46.508708270344421],"hsluv":[265.874320218178241,99.9999999999992468,46.508708270344421]},"#ccdd00":{"lch":[84.2515012159558552,94.1174138813685772,92.7819892835375555],"luv":[84.2515012159558552,-4.56806363508048818,94.0064912138661128],"rgb":[0.8,0.866666666666666696,0],"xyz":[0.507566029502865779,0.645503626279608334,0.0978568736941549666],"hpluv":[92.7819892835375555,256.902059824464118,84.2515012159558552],"hsluv":[92.7819892835375555,100.000000000002373,84.2515012159558552]},"#ccdd11":{"lch":[84.2724460606142287,93.1910749716768692,92.8373396690251695],"luv":[84.2724460606142287,-4.61302172096193619,93.0768310858219508],"rgb":[0.8,0.866666666666666696,0.0666666666666666657],"xyz":[0.508577695002502939,0.645908292479463242,0.103184978658910603],"hpluv":[92.8373396690251695,254.758074317949962,84.2724460606142287],"hsluv":[92.8373396690251695,98.9747327605244465,84.2724460606142287]},"#ccdd22":{"lch":[84.3112490917695396,91.4838404394451175,92.9423140418060711],"luv":[84.3112490917695396,-4.69591125178302349,91.3632392106652],"rgb":[0.8,0.866666666666666696,0.133333333333333331],"xyz":[0.510453053140979884,0.646658435734854,0.113061864854889796],"hpluv":[92.9423140418060711,250.792999873820406,84.3112490917695396],"hsluv":[92.9423140418060711,97.0860193213801637,84.3112490917695396]},"#ccdd33":{"lch":[84.3750724084435291,88.7007441607730271,93.1221866378423329],"luv":[84.3750724084435291,-4.83112791130122865,88.5690816130525],"rgb":[0.8,0.866666666666666696,0.2],"xyz":[0.513540803873437701,0.647893536027837169,0.129324018712500932],"hpluv":[93.1221866378423329,244.290353733928498,84.3750724084435291],"hsluv":[93.1221866378423329,94.0094146319777,84.3750724084435291]},"#ccdd44":{"lch":[84.4670755276021197,84.7426243382763857,93.3985511967960491],"luv":[84.4670755276021197,-5.02363867224446459,84.5935897939611152],"rgb":[0.8,0.866666666666666696,0.266666666666666663],"xyz":[0.517998799117656561,0.649676734125524735,0.152802793665387571],"hpluv":[93.3985511967960491,234.956854948695792,84.4670755276021197],"hsluv":[93.3985511967960491,89.638788485123,84.4670755276021197]},"#ccdd55":{"lch":[84.5898637292301601,79.5568981087007359,93.8026723407881633],"luv":[84.5898637292301601,-5.27624840258561711,79.3817437416967095],"rgb":[0.8,0.866666666666666696,0.333333333333333315],"xyz":[0.523961213157018491,0.652061699741269485,0.184204840939361486],"hpluv":[93.8026723407881633,222.570337020009788,84.5898637292301601],"hsluv":[93.8026723407881633,83.9211409492819485,84.5898637292301601]},"#ccdd66":{"lch":[84.7456349568684857,73.1331501088793772,94.3836122863904],"luv":[84.7456349568684857,-5.58984810871231,72.9192103836116],"rgb":[0.8,0.866666666666666696,0.4],"xyz":[0.531546208930526731,0.655095698050672803,0.224152485346505448],"hpluv":[94.3836122863904,206.963810787645969,84.7456349568684857],"hsluv":[94.3836122863904,76.851201462777,84.7456349568684857]},"#ccdd77":{"lch":[84.9362580835765186,65.5005774458529828,95.2238145131341156],"luv":[84.9362580835765186,-5.96359854749608687,65.2285300930849274],"rgb":[0.8,0.866666666666666696,0.466666666666666674],"xyz":[0.540860221950728581,0.658821303258753654,0.273206287252903357],"hpluv":[95.2238145131341156,188.015270942662227,84.9362580835765186],"hsluv":[95.2238145131341156,68.4671748287691,84.9362580835765186]},"#ccdd88":{"lch":[85.1633194008604733,56.7265968622164536,96.4730545580279],"luv":[85.1633194008604733,-6.39512608731957588,56.3649638862273221],"rgb":[0.8,0.866666666666666696,0.533333333333333326],"xyz":[0.552000639052672493,0.663277470099531197,0.331879150656475552],"hpluv":[96.4730545580279,165.642146962004915,85.1633194008604733],"hsluv":[96.4730545580279,58.8458897999489707,85.1633194008604733]},"#ccdd99":{"lch":[85.4281525463895548,46.9188240443766134,98.432972024211054],"luv":[85.4281525463895548,-6.88075351903593724,46.4115425375783843],"rgb":[0.8,0.866666666666666696,0.6],"xyz":[0.565057603161745137,0.66850025574316041,0.400645828297593432],"hpluv":[98.432972024211054,139.807612964747022,85.4281525463895548],"hsluv":[98.432972024211054,48.0968721297954644,85.4281525463895548]},"#ccddaa":{"lch":[85.7318592309590457,36.2402041704229134,101.807730551991185],"luv":[85.7318592309590457,-7.41576493035038453,35.4733537857886176],"rgb":[0.8,0.866666666666666696,0.66666666666666663],"xyz":[0.580115296126997748,0.674523332929261477,0.479949677914592032],"hpluv":[101.807730551991185,110.570541660882469,85.7318592309590457],"hsluv":[101.807730551991185,36.355428538792907,85.7318592309590457]},"#ccddbb":{"lch":[86.0753247228475828,24.9849555175277693,108.661729708420211],"luv":[86.0753247228475828,-7.99469198849898,23.671351930590518],"rgb":[0.8,0.866666666666666696,0.733333333333333282],"xyz":[0.597252888234334312,0.681378369772196235,0.570207663013233779],"hpluv":[108.661729708420211,78.3375416693066313,86.0753247228475828],"hsluv":[108.661729708420211,23.7751141135998658,86.0753247228475828]},"#ccddcc":{"lch":[86.4592303781436158,14.0773589090278701,127.715012949224516],"luv":[86.4592303781436158,-8.61160385902942771,11.1360815742673065],"rgb":[0.8,0.866666666666666696,0.8],"xyz":[0.616545263678056066,0.689095319949685092,0.671814173683503935],"hpluv":[127.715012949224516,45.5363150686036633,86.4592303781436158],"hsluv":[127.715012949224516,10.5200784033656536,86.4592303781436158]},"#ccdddd":{"lch":[86.8840646031333677,9.47353258269296106,192.177050630057835],"luv":[86.8840646031333677,-9.26038246071566817,-1.99828333241680145],"rgb":[0.8,0.866666666666666696,0.866666666666666696],"xyz":[0.638063589228689665,0.697702650169938599,0.785144021583509932],"hpluv":[192.177050630057835,31.7497104564534354,86.8840646031333677],"hsluv":[192.177050630057835,13.7818607651735867,86.8840646031333677]},"#ccddee":{"lch":[87.3501331068194276,18.4943223550678582,237.507437159903361],"luv":[87.3501331068194276,-9.9349674143158051,-15.5992429896340141],"rgb":[0.8,0.866666666666666696,0.933333333333333348],"xyz":[0.661875769494864374,0.707227522276408616,0.910554837652033155],"hpluv":[237.507437159903361,64.5162574350921432,87.3501331068194276],"hsluv":[237.507437159903361,51.9237885878372083,87.3501331068194276]},"#ccddff":{"lch":[87.8575689716950876,31.3946063828198874,250.2096672964189],"luv":[87.8575689716950876,-10.6295595905023852,-29.5403752996496962],"rgb":[0.8,0.866666666666666696,1],"xyz":[0.688046817904695795,0.717695941640341339,1.04838902594381489],"hpluv":[250.2096672964189,114.576774718516177,87.8575689716950876],"hsluv":[250.2096672964189,99.999999999992923,87.8575689716950876]},"#556600":{"lch":[40.3019892206732919,46.2375853800199934,99.381148915360626],"luv":[40.3019892206732919,-7.53678920078613679,45.6191967302971264],"rgb":[0.333333333333333315,0.4,0],"xyz":[0.0849739168694777086,0.114339753133439206,0.0175932549799886241],"hpluv":[99.381148915360626,145.582103533726,40.3019892206732919],"hsluv":[99.381148915360626,100.000000000002302,40.3019892206732919]},"#556611":{"lch":[40.3683315206726334,43.7939991819964618,99.9948312384981364],"luv":[40.3683315206726334,-7.60085740022420797,43.1293557931736729],"rgb":[0.333333333333333315,0.4,0.0666666666666666657],"xyz":[0.0859855823691148269,0.114744419333294059,0.0229213599447442573],"hpluv":[99.9948312384981364,137.661701347396985,40.3683315206726334],"hsluv":[99.9948312384981364,94.2576138599214204,40.3683315206726334]},"#556622":{"lch":[40.4909010608148421,39.4175015547736436,101.28961011017671],"luv":[40.4909010608148421,-7.7166980000465113,38.6547797923705758],"rgb":[0.333333333333333315,0.4,0.133333333333333331],"xyz":[0.0878609405075918559,0.115494562588684874,0.0327982461407234499],"hpluv":[101.28961011017671,123.529583899053776,40.4909010608148421],"hsluv":[101.28961011017671,83.977954812826539,40.4909010608148421]},"#556633":{"lch":[40.6915589391927455,32.6300466430477343,104.01044750968255],"luv":[40.6915589391927455,-7.89969574444685207,31.6593548745491518],"rgb":[0.333333333333333315,0.4,0.2],"xyz":[0.0909486912400495895,0.116729662881667987,0.0490603999983346],"hpluv":[104.01044750968255,101.754281640855311,40.6915589391927455],"hsluv":[104.01044750968255,68.015525760737134,40.6915589391927455]},"#556644":{"lch":[40.9787805135115306,23.7356999706126039,110.078417815454017],"luv":[40.9787805135115306,-8.1486066005911173,22.2931304119395044],"rgb":[0.333333333333333315,0.4,0.266666666666666663],"xyz":[0.0954066864842684631,0.118512860979355567,0.0725391749512212386],"hpluv":[110.078417815454017,73.4991539757345436,40.9787805135115306],"hsluv":[110.078417815454017,46.8659194429644117,40.9787805135115306]},"#556655":{"lch":[41.3584605937638372,13.8246485480389332,127.71501294923371],"luv":[41.3584605937638372,-8.45701225317865202,10.9361716896901875],"rgb":[0.333333333333333315,0.4,0.333333333333333315],"xyz":[0.101369100523630462,0.120897826595100399,0.10394122222519514],"hpluv":[127.71501294923371,42.4159365242361659,41.3584605937638372],"hsluv":[127.71501294923371,21.5972717302380097,41.3584605937638372]},"#556666":{"lch":[41.8343160733152146,9.01834401177998402,192.177050630060307],"luv":[41.8343160733152146,-8.8154354231024481,-1.90226891261946607],"rgb":[0.333333333333333315,0.4,0.4],"xyz":[0.108954096297138633,0.123931824904503718,0.143888866632339102],"hpluv":[192.177050630060307,27.3547941496945484,41.8343160733152146],"hsluv":[192.177050630060307,27.2477194602778816,41.8343160733152146]},"#556677":{"lch":[42.4081371223492525,18.1914318380534858,239.570903430569189],"luv":[42.4081371223492525,-9.21344558994119289,-15.6856817728697795],"rgb":[0.333333333333333315,0.4,0.466666666666666674],"xyz":[0.118268109317340553,0.127657430112584541,0.192942668538737],"hpluv":[239.570903430569189,54.4323412384199443,42.4081371223492525],"hsluv":[239.570903430569189,33.1626844996427934,42.4081371223492525]},"#556688":{"lch":[43.0800011190655425,31.444407039181371,252.144687081813345],"luv":[43.0800011190655425,-9.64130614192028546,-29.9298504828121246],"rgb":[0.333333333333333315,0.4,0.533333333333333326],"xyz":[0.129408526419284381,0.132113596953362111,0.251615531942309179],"hpluv":[252.144687081813345,92.6204805766441694,43.0800011190655425],"hsluv":[252.144687081813345,39.0862788716996903,43.0800011190655425]},"#556699":{"lch":[43.8484890486876964,45.3842681536749,257.153237313451427],"luv":[43.8484890486876964,-10.090933534038701,-44.2482186789059639],"rgb":[0.333333333333333315,0.4,0.6],"xyz":[0.142465490528357108,0.137336382596991269,0.320382209583427113],"hpluv":[257.153237313451427,131.337888607863903,43.8484890486876964],"hsluv":[257.153237313451427,44.8182326355090055,43.8484890486876964]},"#5566aa":{"lch":[44.7109144588579,59.3119903927914223,259.748012643434],"luv":[44.7109144588579,-10.5562103110165033,-58.3650462882037928],"rgb":[0.333333333333333315,0.4,0.66666666666666663],"xyz":[0.157523183493609636,0.143359459783092391,0.399686059200425714],"hpluv":[259.748012643434,168.332615885742257,44.7109144588579],"hsluv":[259.748012643434,50.2202557252039341,44.7109144588579]},"#5566bb":{"lch":[45.6635615252987463,72.9454914642558805,261.300749278862554],"luv":[45.6635615252987463,-11.0328519112314041,-72.1063166696695532],"rgb":[0.333333333333333315,0.4,0.733333333333333282],"xyz":[0.174660775600946283,0.15021449662602715,0.48994404429906746],"hpluv":[261.300749278862554,202.706651650989187,45.6635615252987463],"hsluv":[261.300749278862554,56.1551480082100767,45.6635615252987463]},"#5566cc":{"lch":[46.7019230239281953,86.153038102066219,262.316955218783903],"luv":[46.7019230239281953,-11.5180515282988498,-85.3796255742992],"rgb":[0.333333333333333315,0.4,0.8],"xyz":[0.193953151044668037,0.157931446803515951,0.591550554969337616],"hpluv":[262.316955218783903,234.085848684940913,46.7019230239281953],"hsluv":[262.316955218783903,67.0801136297732086,46.7019230239281953]},"#5566dd":{"lch":[47.8209277182799539,98.8836589551542,263.023825475898036],"luv":[47.8209277182799539,-12.010072956506761,-98.1515978267222664],"rgb":[0.333333333333333315,0.4,0.866666666666666696],"xyz":[0.215471476595301581,0.166538777023769485,0.704880402869343614],"hpluv":[263.023825475898036,262.38914084011509,47.8209277182799539],"hsluv":[263.023825475898036,77.9738615315733909,47.8209277182799539]},"#5566ee":{"lch":[49.0151480019121095,111.133834597019145,263.537783903780621],"luv":[49.0151480019121095,-12.5078880087352609,-110.427722650603215],"rgb":[0.333333333333333315,0.4,0.933333333333333348],"xyz":[0.23928365686147629,0.176063649130239502,0.830291218937866837],"hpluv":[263.537783903780621,287.710232398192659,49.0151480019121095],"hsluv":[263.537783903780621,88.9133133505171145,49.0151480019121095]},"#5566ff":{"lch":[50.2789812841098751,122.927042369796439,263.924295565134457],"luv":[50.2789812841098751,-13.0108962765956715,-122.236550687040406],"rgb":[0.333333333333333315,0.4,1],"xyz":[0.265454705271307712,0.186532068494172198,0.968125407229648682],"hpluv":[263.924295565134457,310.2417842032321,50.2789812841098751],"hsluv":[263.924295565134457,99.99999999999919,50.2789812841098751]},"#ccee00":{"lch":[88.9159222564839382,101.512339113439552,98.3897184755654],"luv":[88.9159222564839382,-14.8112090817394879,100.426007975120399],"rgb":[0.8,0.933333333333333348,0],"xyz":[0.554744805843380595,0.739861178960639299,0.113583132474326151],"hpluv":[98.3897184755654,409.405376777149172,88.9159222564839382],"hsluv":[98.3897184755654,100.000000000002402,88.9159222564839382]},"#ccee11":{"lch":[88.9350466502285855,100.665090554083037,98.4749110233884863],"luv":[88.9350466502285855,-14.8356507509631186,99.5658773027044],"rgb":[0.8,0.933333333333333348,0.0666666666666666657],"xyz":[0.555756471343017755,0.740265845160494207,0.118911237439081788],"hpluv":[98.4749110233884863,406.753799510206477,88.9350466502285855],"hsluv":[98.4749110233884863,99.103544824997428,88.9350466502285855]},"#ccee22":{"lch":[88.9704797513205108,99.1029038393990191,98.635890718104875],"luv":[88.9704797513205108,-14.8807650249594605,97.9793262973016823],"rgb":[0.8,0.933333333333333348,0.133333333333333331],"xyz":[0.557631829481494701,0.741015988415885,0.12878812363506098],"hpluv":[98.635890718104875,401.844579090604725,88.9704797513205108],"hsluv":[98.635890718104875,97.4508266239822376,88.9704797513205108]},"#ccee33":{"lch":[89.0287677898111696,96.5543294248683281,98.9099371535565837],"luv":[89.0287677898111696,-14.95450175665089,95.3892101230339335],"rgb":[0.8,0.933333333333333348,0.2],"xyz":[0.560719580213952518,0.742251088708868134,0.145050277492672131],"hpluv":[98.9099371535565837,393.778440936160052,89.0287677898111696],"hsluv":[98.9099371535565837,94.7550356083218333,89.0287677898111696]},"#ccee44":{"lch":[89.1128082270408157,92.9258219449750698,99.3266297509707101],"luv":[89.1128082270408157,-15.0597883526499068,91.6973890518296],"rgb":[0.8,0.933333333333333348,0.266666666666666663],"xyz":[0.565177575458171377,0.7440342868065557,0.168529052445558769],"hpluv":[99.3266297509707101,382.168331694223468,89.1128082270408157],"hsluv":[99.3266297509707101,90.9176847425828782,89.1128082270408157]},"#ccee55":{"lch":[89.224999764075946,88.1655281542066263,99.9265688821158591],"luv":[89.224999764075946,-15.1984931464969293,86.8456456063635187],"rgb":[0.8,0.933333333333333348,0.333333333333333315],"xyz":[0.571139989497533307,0.74641925242230045,0.199931099719532657],"hpluv":[99.9265688821158591,366.702481299920066,89.224999764075946],"hsluv":[99.9265688821158591,85.8839575374920372,89.224999764075946]},"#ccee66":{"lch":[89.3673776950467555,82.2600687786622444,100.76990980050725],"luv":[89.3673776950467555,-15.3715621348797811,80.8111006793235873],"rgb":[0.8,0.933333333333333348,0.4],"xyz":[0.578724985271041548,0.749453250731703768,0.239878744126676646],"hpluv":[100.76990980050725,347.124780760482849,89.3673776950467555],"hsluv":[100.76990980050725,79.6381055931254451,89.3673776950467555]},"#ccee77":{"lch":[89.5416863487684651,75.2338064272131817,101.95104715507324],"luv":[89.5416863487684651,-15.5791079616514043,73.6031047215169707],"rgb":[0.8,0.933333333333333348,0.466666666666666674],"xyz":[0.588038998291243398,0.753178855939784619,0.288932546033074555],"hpluv":[101.95104715507324,323.225079834159544,89.5416863487684651],"hsluv":[101.95104715507324,72.2002225208687349,89.5416863487684651]},"#ccee88":{"lch":[89.7494222523926481,67.150335761217363,103.626883623375818],"luv":[89.7494222523926481,-15.8204941270879562,65.2600916212887654],"rgb":[0.8,0.933333333333333348,0.533333333333333326],"xyz":[0.599179415393187309,0.757635022780562162,0.347605409436646695],"hpluv":[103.626883623375818,294.840431689210504,89.7494222523926481],"hsluv":[103.626883623375818,63.6228180815060256,89.7494222523926481]},"#ccee99":{"lch":[89.9918618926625697,58.1187887690418705,106.076645299715267],"luv":[89.9918618926625697,-16.094429395756972,55.8458857070554586],"rgb":[0.8,0.933333333333333348,0.6],"xyz":[0.61223637950226,0.762857808424191375,0.41637208707776463],"hpluv":[106.076645299715267,261.881276027636488,89.9918618926625697],"hsluv":[106.076645299715267,53.9866751643902418,89.9918618926625697]},"#cceeaa":{"lch":[90.2700807835134071,48.3136880988356481,109.842100564752428],"luv":[90.2700807835134071,-16.3990756203548145,45.4453823452884791],"rgb":[0.8,0.933333333333333348,0.66666666666666663],"xyz":[0.627294072467512565,0.768880885610292442,0.495675936694763231],"hpluv":[109.842100564752428,224.429228200920562,90.2700807835134071],"hsluv":[109.842100564752428,43.3959332818477037,90.2700807835134071]},"#cceebb":{"lch":[90.5849674500281736,38.0375276056681,116.096591597387416],"luv":[90.5849674500281736,-16.7321662581560417,34.1597441246474745],"rgb":[0.8,0.933333333333333348,0.733333333333333282],"xyz":[0.644431664574849128,0.7757359224532272,0.585933921793405],"hpluv":[116.096591597387416,183.067580850930824,90.5849674500281736],"hsluv":[116.096591597387416,31.9725829176952736,90.5849674500281736]},"#cceecc":{"lch":[90.9372344233822,27.9388105970907,127.715012949233042],"luv":[90.9372344233822,-17.0911298567764973,22.1013668762570106],"rgb":[0.8,0.933333333333333348,0.8],"xyz":[0.663724040018570882,0.783452872630716057,0.687540432463675133],"hpluv":[127.715012949233042,140.086760618050221,90.9372344233822],"hsluv":[127.715012949233042,30.3633811556705,90.9372344233822]},"#cceedd":{"lch":[91.327427526889025,19.8359452431300802,151.749458426713772],"luv":[91.327427526889025,-17.4732117028180483,9.38890816213244861],"rgb":[0.8,0.933333333333333348,0.866666666666666696],"xyz":[0.685242365569204481,0.792060202850969564,0.800870280363681131],"hpluv":[151.749458426713772,104.258293798779974,91.327427526889025],"hsluv":[151.749458426713772,29.0871711351253381,91.327427526889025]},"#cceeee":{"lch":[91.7559342603931,18.2870370266976643,192.177050630059739],"luv":[91.7559342603931,-17.87558711202,-3.8573447624494035],"rgb":[0.8,0.933333333333333348,0.933333333333333348],"xyz":[0.709054545835379191,0.801585074957439581,0.926281096432204354],"hpluv":[192.177050630059739,101.458793010104,91.7559342603931],"hsluv":[192.177050630059739,27.4217374065650326,91.7559342603931]},"#cceeff":{"lch":[92.2229917973594553,25.3309747642836847,223.758903531404655],"luv":[92.2229917973594553,-18.2954610486514362,-17.5195430170439934],"rgb":[0.8,0.933333333333333348,1],"xyz":[0.735225594245210612,0.812053494321372304,1.06411528472398609],"hpluv":[223.758903531404655,149.53216426558339,92.2229917973594553],"hsluv":[223.758903531404655,99.9999999999890861,92.2229917973594553]},"#557700":{"lch":[45.8045523271613533,55.5294361467329836,107.801769483020877],"luv":[45.8045523271613533,-16.9767207468495087,52.8706840456749276],"rgb":[0.333333333333333315,0.466666666666666674,0],"xyz":[0.103427654922895337,0.151247229240274977,0.023744500997794328],"hpluv":[107.801769483020877,153.83457187868342,45.8045523271613533],"hsluv":[107.801769483020877,100.000000000002288,45.8045523271613533]},"#557711":{"lch":[45.859623178970125,53.470483995502839,108.496139146384877],"luv":[45.859623178970125,-16.9630166203079504,50.7084679896019068],"rgb":[0.333333333333333315,0.466666666666666674,0.0666666666666666657],"xyz":[0.104439320422532456,0.15165189544012983,0.0290726059625499578],"hpluv":[108.496139146384877,147.952722071756682,45.859623178970125],"hsluv":[108.496139146384877,95.6324690191426,45.859623178970125]},"#557722":{"lch":[45.9614512879267494,49.76586948312967,109.899607245517743],"luv":[45.9614512879267494,-16.93896350220896,46.7943723206405409],"rgb":[0.333333333333333315,0.466666666666666674,0.133333333333333331],"xyz":[0.106314678561009485,0.152402038695520659,0.0389494921585291573],"hpluv":[109.899607245517743,137.396980684000368,45.9614512879267494],"hsluv":[109.899607245517743,87.7486210093461239,45.9614512879267494]},"#557733":{"lch":[46.1283843073061,43.9801463057798472,112.602269297118809],"luv":[46.1283843073061,-16.9029726498973396,40.6022509803905223],"rgb":[0.333333333333333315,0.466666666666666674,0.2],"xyz":[0.109402429293467218,0.153637138988503757,0.0552116460161403],"hpluv":[112.602269297118809,120.983948144693443,46.1283843073061],"hsluv":[112.602269297118809,75.3373974156097432,46.1283843073061]},"#557744":{"lch":[46.3678258482665413,36.3216896494577526,117.654446368962965],"luv":[46.3678258482665413,-16.8582748313623227,32.1724060135666861],"rgb":[0.333333333333333315,0.466666666666666674,0.266666666666666663],"xyz":[0.113860424537686092,0.155420337086191351,0.0786904209690269391],"hpluv":[117.654446368962965,99.4005156049610861,46.3678258482665413],"hsluv":[117.654446368962965,58.5682493514162346,46.3678258482665413]},"#557755":{"lch":[46.6852246722490349,27.4798560002662136,127.715012949237362],"luv":[46.6852246722490349,-16.8103715694690621,21.7383047520213317],"rgb":[0.333333333333333315,0.466666666666666674,0.333333333333333315],"xyz":[0.119822838577048091,0.157805302701936184,0.110092468243000841],"hpluv":[127.715012949237362,74.6920408293198506,46.6852246722490349],"hsluv":[127.715012949237362,38.0315615795731219,46.6852246722490349]},"#557766":{"lch":[47.0844103757355299,19.3533005907945039,150.034269154893224],"luv":[47.0844103757355299,-16.7662346577491,9.66662397939114371],"rgb":[0.333333333333333315,0.466666666666666674,0.4],"xyz":[0.127407834350556276,0.160839301011339475,0.150040112650144802],"hpluv":[150.034269154893224,52.1575559127659147,47.0844103757355299],"hsluv":[150.034269154893224,41.6155983808333403,47.0844103757355299]},"#557777":{"lch":[47.5677829408255519,17.1184872206298522,192.177050630060563],"luv":[47.5677829408255519,-16.733329138647683,-3.61085871511915846],"rgb":[0.333333333333333315,0.466666666666666674,0.466666666666666674],"xyz":[0.136721847370758182,0.164564906219420298,0.199093914556542712],"hpluv":[192.177050630060563,45.665876663612373,47.5677829408255519],"hsluv":[192.177050630060563,45.4871270252879683,47.5677829408255519]},"#557788":{"lch":[48.1364533988364371,24.3189053895014062,226.569261606948],"luv":[48.1364533988364371,-16.7186932071720697,-17.6605338760746164],"rgb":[0.333333333333333315,0.466666666666666674,0.533333333333333326],"xyz":[0.147862264472702,0.169021073060197896,0.257766777960114879],"hpluv":[226.569261606948,64.1075619232690173,48.1364533988364371],"hsluv":[226.569261606948,49.4930397679002567,48.1364533988364371]},"#557799":{"lch":[48.7903733600049776,36.1922931768580227,242.470518495943224],"luv":[48.7903733600049776,-16.7282575252316086,-32.0943528610435749],"rgb":[0.333333333333333315,0.466666666666666674,0.6],"xyz":[0.160919228581774709,0.174243858703827054,0.326533455601232814],"hpluv":[242.470518495943224,94.128532149155447,48.7903733600049776],"hsluv":[242.470518495943224,53.4981409183259657,48.7903733600049776]},"#5577aa":{"lch":[49.5284680294880957,49.5215284063763121,250.210257263218182],"luv":[49.5284680294880957,-16.7664778987851584,-46.5968560588918308],"rgb":[0.333333333333333315,0.466666666666666674,0.66666666666666663],"xyz":[0.175976921547027265,0.180266935889928148,0.405837305218231414],"hpluv":[250.210257263218182,126.875705911364861,49.5284680294880957],"hsluv":[250.210257263218182,57.3943781585142503,49.5284680294880957]},"#5577bb":{"lch":[50.3487764471929324,63.2168000831305,254.554261837862072],"luv":[50.3487764471929324,-16.8362555209572413,-60.9336057753316069],"rgb":[0.333333333333333315,0.466666666666666674,0.733333333333333282],"xyz":[0.193114513654363912,0.187121972732862907,0.496095290316873161],"hpluv":[254.554261837862072,159.324628464713726,50.3487764471929324],"hsluv":[254.554261837862072,61.1035457400689737,50.3487764471929324]},"#5577cc":{"lch":[51.2485971738404942,76.8367273058076279,257.264224247337211],"luv":[51.2485971738404942,-16.9390629845235594,-74.9463195111900546],"rgb":[0.333333333333333315,0.466666666666666674,0.8],"xyz":[0.212406889098085638,0.194838922910351708,0.597701800987143317],"hpluv":[257.264224247337211,190.250673687597981,51.2485971738404942],"hsluv":[257.264224247337211,64.5753193228694329,51.2485971738404942]},"#5577dd":{"lch":[52.2246350466270428,90.1721178795433502,259.084439545341468],"luv":[52.2246350466270428,-17.075183181685393,-88.5406627612090347],"rgb":[0.333333333333333315,0.466666666666666674,0.866666666666666696],"xyz":[0.233925214648719182,0.203446253130605242,0.711031648887149315],"hpluv":[259.084439545341468,219.096874823476185,52.2246350466270428],"hsluv":[259.084439545341468,74.9139940771913757,52.2246350466270428]},"#5577ee":{"lch":[53.2731438322457791,103.123503170291656,260.373961187264626],"luv":[53.2731438322457791,-17.2439851141504441,-101.671539200978515],"rgb":[0.333333333333333315,0.466666666666666674,0.933333333333333348],"xyz":[0.257737394914893947,0.212971125237075287,0.836442464955672538],"hpluv":[260.373961187264626,245.63410016831412,53.2731438322457791],"hsluv":[260.373961187264626,87.3510385353649,53.2731438322457791]},"#5577ff":{"lch":[54.3900599484937572,115.652149768064447,261.324783585170792],"luv":[54.3900599484937572,-17.4441870719707097,-114.32899931064253],"rgb":[0.333333333333333315,0.466666666666666674,1],"xyz":[0.283908443324725313,0.223439544601007983,0.974276653247454383],"hpluv":[261.324783585170792,269.819603010977914,54.3900599484937572],"hsluv":[261.324783585170792,99.9999999999989768,54.3900599484937572]},"#ccff00":{"lch":[93.605159534834371,109.568762044642341,102.903766821995461],"luv":[93.605159534834371,-24.4682604068618268,106.801768939739262],"rgb":[0.8,1,0],"xyz":[0.606597178273054372,0.843565923819988406,0.130867256617550276],"hpluv":[102.903766821995461,795.170643052662513,93.605159534834371],"hsluv":[102.903766821995461,100.000000000002359,93.605159534834371]},"#ccff11":{"lch":[93.6226829283917681,108.793716578542018,103.00230683973929],"luv":[93.6226829283917681,-24.4775292120886689,106.004355243751533],"rgb":[0.8,1,0.0666666666666666657],"xyz":[0.607608843772691531,0.843970590019843314,0.136195361582305913],"hpluv":[103.00230683973929,791.823376913543598,93.6226829283917681],"hsluv":[103.00230683973929,99.9999999999883755,93.6226829283917681]},"#ccff22":{"lch":[93.6551518183817535,107.364125357399203,103.187929529698394],"luv":[93.6551518183817535,-24.4946701604029187,104.532609971684906],"rgb":[0.8,1,0.133333333333333331],"xyz":[0.609484201911168477,0.844720733275234115,0.146072247778285091],"hpluv":[103.187929529698394,785.615721446726184,93.6551518183817535],"hsluv":[103.187929529698394,99.9999999999883613,93.6551518183817535]},"#ccff33":{"lch":[93.7085695338431464,105.030410790236445,103.502196488744218],"luv":[93.7085695338431464,-24.5227776356263192,102.127472150246831],"rgb":[0.8,1,0.2],"xyz":[0.612571952643626294,0.845955833568217241,0.162334401635896242],"hpluv":[103.502196488744218,775.386532390006209,93.7085695338431464],"hsluv":[103.502196488744218,99.9999999999882334,93.7085695338431464]},"#ccff44":{"lch":[93.7856006692118456,101.704796230104463,103.975902087852319],"luv":[93.7856006692118456,-24.5631097372148304,98.6940687997238],"rgb":[0.8,1,0.266666666666666663],"xyz":[0.617029947887845154,0.847739031665904808,0.18581317658878288],"hpluv":[103.975902087852319,760.597322717251814,93.7856006692118456],"hsluv":[103.975902087852319,99.9999999999883329,93.7856006692118456]},"#ccff55":{"lch":[93.8884584724407887,97.3367975087049473,104.649262803016768],"luv":[93.8884584724407887,-24.6166025777849207,94.1725810773922802],"rgb":[0.8,1,0.333333333333333315],"xyz":[0.622992361927207083,0.850123997281649557,0.217215223862756796],"hpluv":[104.649262803016768,740.773636872505676,93.8884584724407887],"hsluv":[104.649262803016768,99.999999999988,93.8884584724407887]},"#ccff66":{"lch":[94.0190298395239381,91.9106503723783561,105.578857731119598],"luv":[94.0190298395239381,-24.6839280463924027,88.5340123798424514],"rgb":[0.8,1,0.4],"xyz":[0.630577357700715324,0.853157995591052876,0.257162868269900757],"hpluv":[105.578857731119598,715.472563222964368,94.0190298395239381],"hsluv":[105.578857731119598,99.9999999999875371,94.0190298395239381]},"#ccff77":{"lch":[94.1789424927264349,85.4453105292158597,106.848417981185563],"luv":[94.1789424927264349,-24.7655268674123263,81.7775627566241781],"rgb":[0.8,1,0.466666666666666674],"xyz":[0.639891370720917174,0.856883600799133727,0.306216670176298666],"hpluv":[106.848417981185563,684.262206540111833,94.1789424927264349],"hsluv":[106.848417981185563,99.9999999999873381,94.1789424927264349]},"#ccff88":{"lch":[94.3696051468525781,77.9966506735583778,108.587502777405675],"luv":[94.3696051468525781,-24.8616333733667219,73.92818611532],"rgb":[0.8,1,0.533333333333333326],"xyz":[0.651031787822861086,0.861339767639911269,0.364889533579870862],"hpluv":[108.587502777405675,646.714804777793233,94.3696051468525781],"hsluv":[108.587502777405675,99.9999999999870397,94.3696051468525781]},"#ccff99":{"lch":[94.5922333645115572,69.6635615227201868,111.00626449694991],"luv":[94.5922333645115572,-24.9722983929036886,65.0338074927618],"rgb":[0.8,1,0.6],"xyz":[0.66408875193193373,0.866562553283540482,0.433656211220988741],"hpluv":[111.00626449694991,602.43247210261859,94.5922333645115572],"hsluv":[111.00626449694991,99.999999999986656,94.5922333645115572]},"#ccffaa":{"lch":[94.8478672375315881,60.6030718965076574,114.464397640121035],"luv":[94.8478672375315881,-25.0974127381864349,55.1620539605116],"rgb":[0.8,1,0.66666666666666663],"xyz":[0.679146444897186341,0.872585630469641549,0.512960060837987397],"hpluv":[114.464397640121035,551.164539659931279,94.8478672375315881],"hsluv":[114.464397640121035,99.9999999999858886,94.8478672375315881]},"#ccffbb":{"lch":[95.1373841969384,51.0680528276179899,119.615591899534252],"luv":[95.1373841969384,-25.2367319023901224,44.3965469658538439],"rgb":[0.8,1,0.733333333333333282],"xyz":[0.696284037004522904,0.879440667312576307,0.603218045936629088],"hpluv":[119.615591899534252,493.192076617112832,95.1373841969384],"hsluv":[119.615591899534252,99.999999999985036,95.1373841969384]},"#ccffcc":{"lch":[95.4615088709507802,41.5047839306073527,127.715012949235671],"luv":[95.4615088709507802,-25.3899015983654444,32.8329101048280876],"rgb":[0.8,1,0.8],"xyz":[0.715576412448244659,0.887157617490065165,0.704824556606899244],"hpluv":[127.715012949235671,430.524428546451247,95.4615088709507802],"hsluv":[127.715012949235671,99.9999999999844,95.4615088709507802]},"#ccffdd":{"lch":[95.8208211701733603,32.8093273722257,141.163585516297758],"luv":[95.8208211701733603,-25.5564832849791728,20.5746962243056899],"rgb":[0.8,1,0.866666666666666696],"xyz":[0.737094737998878258,0.895764947710318671,0.818154404506905242],"hpluv":[141.163585516297758,370.598640927928557,95.8208211701733603],"hsluv":[141.163585516297758,99.9999999999829612,95.8208211701733603]},"#ccffee":{"lch":[96.2157633520208293,26.8716381406037179,163.283084738459195],"luv":[96.2157633520208293,-25.7359786647352209,7.72944619800421506],"rgb":[0.8,1,0.933333333333333348],"xyz":[0.760906918265053,0.905289819816788688,0.943565220575428465],"hpluv":[163.283084738459195,336.210724351278486,96.2157633520208293],"hsluv":[163.283084738459195,99.9999999999813411,96.2157633520208293]},"#ccffff":{"lch":[96.6466465538527899,26.5246444827845806,192.177050630060279],"luv":[96.6466465538527899,-25.9278521925209873,-5.59493034995961125],"rgb":[0.8,1,1],"xyz":[0.787077966674884388,0.915758239180721412,1.08139940886721031],"hpluv":[192.177050630060279,375.729722461639881,96.6466465538527899],"hsluv":[192.177050630060279,99.9999999999789111,96.6466465538527899]},"#558800":{"lch":[51.3121649295003266,65.2833526322192,113.133039202335894],"luv":[51.3121649295003266,-25.6477049188799029,60.0342515843809466],"rgb":[0.333333333333333315,0.533333333333333326,0],"xyz":[0.125500024647865804,0.195391968690216522,0.0311019575727842744],"hpluv":[113.133039202335894,161.443824642532,51.3121649295003266],"hsluv":[113.133039202335894,100.000000000002416,51.3121649295003266]},"#558811":{"lch":[51.3586018009433758,63.5282336791645363,113.757082680238781],"luv":[51.3586018009433758,-25.5929736747770171,58.1449582756467862],"rgb":[0.333333333333333315,0.533333333333333326,0.0666666666666666657],"xyz":[0.126511690147502937,0.195796634890071375,0.0364300625375399076],"hpluv":[113.757082680238781,156.961418592175818,51.3586018009433758],"hsluv":[113.757082680238781,96.6047658949560315,51.3586018009433758]},"#558822":{"lch":[51.4445144263052754,60.3557257759597761,114.985955444381503],"luv":[51.4445144263052754,-25.4940226670596211,54.707115096615226],"rgb":[0.333333333333333315,0.533333333333333326,0.133333333333333331],"xyz":[0.128387048285979938,0.196546778145462203,0.0463069487335191],"hpluv":[114.985955444381503,148.873956641671725,51.4445144263052754],"hsluv":[114.985955444381503,90.4397474873449454,51.4445144263052754]},"#558833":{"lch":[51.5854933484676366,55.3603846502330512,117.238150003797628],"luv":[51.5854933484676366,-25.3378965271949284,49.2215723864945502],"rgb":[0.333333333333333315,0.533333333333333326,0.2],"xyz":[0.131474799018437671,0.197781878438445302,0.0625691025911302434],"hpluv":[117.238150003797628,136.179218375975154,51.5854933484676366],"hsluv":[117.238150003797628,80.6386945119108844,51.5854933484676366]},"#558844":{"lch":[51.788002513998137,48.6519311113283521,121.094634958525788],"luv":[51.788002513998137,-25.1264429677671792,41.6614001762900799],"rgb":[0.333333333333333315,0.533333333333333326,0.266666666666666663],"xyz":[0.135932794262656559,0.199565076536132896,0.0860478775440168819],"hpluv":[121.094634958525788,119.20933058927335,51.788002513998137],"hsluv":[121.094634958525788,67.2069053574962112,51.788002513998137]},"#558855":{"lch":[52.0569745246593669,40.6501953066927229,127.715012949238655],"luv":[52.0569745246593669,-24.8671203906742271,32.1568764333225801],"rgb":[0.333333333333333315,0.533333333333333326,0.333333333333333315],"xyz":[0.141895208302018572,0.201950042151877729,0.117449924817990797],"hpluv":[127.715012949238655,99.0884509425644495,52.0569745246593669],"hsluv":[127.715012949238655,50.4536826414745647,52.0569745246593669]},"#558866":{"lch":[52.3961000606252156,32.296627997442414,139.535908661945541],"luv":[52.3961000606252156,-24.57168930668605,20.9595864611130054],"rgb":[0.333333333333333315,0.533333333333333326,0.4],"xyz":[0.149480204075526729,0.20498404046128102,0.157397569225134759],"hpluv":[139.535908661945541,78.2163498792783258,52.3961000606252156],"hsluv":[139.535908661945541,52.7717106037122505,52.3961000606252156]},"#558877":{"lch":[52.8079833364028417,25.6675371494617757,160.900154113051656],"luv":[52.8079833364028417,-24.2545338981935465,8.39881233868101873],"rgb":[0.333333333333333315,0.533333333333333326,0.466666666666666674],"xyz":[0.158794217095728663,0.208709645669361843,0.206451371131532668],"hpluv":[160.900154113051656,61.6770996704155934,52.8079833364028417],"hsluv":[160.900154113051656,55.3375604028527732,52.8079833364028417]},"#558888":{"lch":[53.2942460543653311,24.4817100724115,192.177050630060762],"luv":[53.2942460543653311,-23.9308828659180151,-5.16400748714853908],"rgb":[0.333333333333333315,0.533333333333333326,0.533333333333333326],"xyz":[0.169934634197672463,0.213165812510139441,0.265124234535104808],"hpluv":[192.177050630060762,58.2908991249141764,53.2942460543653311],"hsluv":[192.177050630060762,58.0627314448554515,53.2942460543653311]},"#558899":{"lch":[53.8556132197311399,30.5464388010487,219.367537814697016],"luv":[53.8556132197311399,-23.6152401502492637,-19.3753801529742589],"rgb":[0.333333333333333315,0.533333333333333326,0.6],"xyz":[0.18299159830674519,0.218388598153768598,0.333890912176222743],"hpluv":[219.367537814697016,71.9728892793730921,53.8556132197311399],"hsluv":[219.367537814697016,60.861676067449,53.8556132197311399]},"#5588aa":{"lch":[54.491995562986105,41.1624410064978434,235.49057853568965],"luv":[54.491995562986105,-23.3202411533326384,-33.9192114024460452],"rgb":[0.333333333333333315,0.533333333333333326,0.66666666666666663],"xyz":[0.198049291271997718,0.224411675339869693,0.413194761793221343],"hpluv":[235.49057853568965,95.8534470006528494,54.491995562986105],"hsluv":[235.49057853568965,63.6587877222075207,54.491995562986105]},"#5588bb":{"lch":[55.2025746803936102,53.7318677649407164,244.589939769846183],"luv":[55.2025746803936102,-23.0560079965343867,-48.5338449823709865],"rgb":[0.333333333333333315,0.533333333333333326,0.733333333333333282],"xyz":[0.215186883379334393,0.231266712182804451,0.503452746891863],"hpluv":[244.589939769846183,123.512789385845494,55.2025746803936102],"hsluv":[244.589939769846183,66.3923972476147,55.2025746803936102]},"#5588cc":{"lch":[55.9858924676882,67.0258402153595227,250.085698604565607],"luv":[55.9858924676882,-22.8299557310329213,-63.0179052166444436],"rgb":[0.333333333333333315,0.533333333333333326,0.8],"xyz":[0.234479258823056119,0.238983662360293253,0.60505925756213319],"hpluv":[250.085698604565607,151.915814945370954,55.9858924676882],"hsluv":[250.085698604565607,69.0160689386852653,55.9858924676882]},"#5588dd":{"lch":[56.8399439373084761,80.4799585659197589,253.656315856923044],"luv":[56.8399439373084761,-22.6469326722406379,-77.2278458285038596],"rgb":[0.333333333333333315,0.533333333333333326,0.866666666666666696],"xyz":[0.255997584373689691,0.247590992580546787,0.718389105462139188],"hpluv":[253.656315856923044,179.669115472769334,56.8399439373084761],"hsluv":[253.656315856923044,71.4978966707909791,56.8399439373084761]},"#5588ee":{"lch":[57.7622712344346212,93.8110643698785083,256.11666422549024],"luv":[57.7622712344346212,-22.5095618551803298,-91.0704969970917517],"rgb":[0.333333333333333315,0.533333333333333326,0.933333333333333348],"xyz":[0.2798097646398644,0.257115864687016804,0.843799921530662411],"hpluv":[256.11666422549024,206.086302990026525,57.7622712344346212],"hsluv":[256.11666422549024,85.5354286092897098,57.7622712344346212]},"#5588ff":{"lch":[58.7500561820581169,106.871298098059711,257.890974112124525],"luv":[58.7500561820581169,-22.4186692043534066,-104.493433421771144],"rgb":[0.333333333333333315,0.533333333333333326,1],"xyz":[0.305980813049695821,0.267584284050949528,0.981634109822444256],"hpluv":[257.890974112124525,230.829932612430156,58.7500561820581169],"hsluv":[257.890974112124525,99.9999999999988489,58.7500561820581169]},"#559900":{"lch":[56.7948235068901113,75.0667586450735769,116.650835958582277],"luv":[56.7948235068901113,-33.6713638042581849,67.0914116190665766],"rgb":[0.333333333333333315,0.6,0],"xyz":[0.151369625100333277,0.247131169595152217,0.0397251577236065259],"hpluv":[116.650835958582277,167.717444253109818,56.7948235068901113],"hsluv":[116.650835958582277,100.000000000002373,56.7948235068901113]},"#559911":{"lch":[56.8345345919718,73.5501475520203343,117.179331557793219],"luv":[56.8345345919718,-33.596019870913949,65.4288289193465431],"rgb":[0.333333333333333315,0.6,0.0666666666666666657],"xyz":[0.152381290599970409,0.24753583579500707,0.0450532626883621556],"hpluv":[117.179331557793219,164.214146288467191,56.8345345919718],"hsluv":[117.179331557793219,97.3073310640873501,56.8345345919718]},"#559922":{"lch":[56.9080340332033785,70.7973668034807559,118.203267177206257],"luv":[56.9080340332033785,-33.458907670269852,62.3920559351826256],"rgb":[0.333333333333333315,0.6,0.133333333333333331],"xyz":[0.154256648738447411,0.248285979050397898,0.0549301488843413552],"hpluv":[118.203267177206257,157.863907732936383,56.9080340332033785],"hsluv":[118.203267177206257,92.3971004449738444,56.9080340332033785]},"#559933":{"lch":[57.0287279601738675,66.4302504595433163,120.024921583566851],"luv":[57.0287279601738675,-33.2401456716524066,57.5158316626386181],"rgb":[0.333333333333333315,0.6,0.2],"xyz":[0.157344399470905172,0.249521079343381,0.0711923027419525],"hpluv":[120.024921583566851,147.812625691912672,57.0287279601738675],"hsluv":[120.024921583566851,84.5348632876942645,57.0287279601738675]},"#559944":{"lch":[57.2022813646338335,60.4886548808755862,122.993651447985457],"luv":[57.2022813646338335,-32.9388613723515604,50.7337045837447178],"rgb":[0.333333333333333315,0.6,0.266666666666666663],"xyz":[0.161802394715124032,0.251304277441068591,0.0946710776948391369],"hpluv":[122.993651447985457,134.183743453609452,57.2022813646338335],"hsluv":[122.993651447985457,73.6468983233054075,57.2022813646338335]},"#559955":{"lch":[57.4331244004656583,53.227141365646645,127.715012949239252],"luv":[57.4331244004656583,-32.5608701853658573,42.1060365117673499],"rgb":[0.333333333333333315,0.6,0.333333333333333315],"xyz":[0.167764808754486017,0.253689243056813396,0.126073124968813038],"hpluv":[127.715012949239252,117.600732304920115,57.4331244004656583],"hsluv":[127.715012949239252,59.8797334066369444,57.4331244004656583]},"#559966":{"lch":[57.7247064038159152,45.1954856350919556,135.286653522876605],"luv":[57.7247064038159152,-32.1175213159608433,31.7977475037242847],"rgb":[0.333333333333333315,0.6,0.4],"xyz":[0.175349804527994202,0.256723241366216715,0.166020769375957],"hpluv":[135.286653522876605,99.3510934192793371,57.7247064038159152],"hsluv":[135.286653522876605,61.4133131906424055,57.7247064038159152]},"#559977":{"lch":[58.0796295741768631,37.4448814339638858,147.624029462041108],"luv":[58.0796295741768631,-31.624170974627738,20.0507096076703846],"rgb":[0.333333333333333315,0.6,0.466666666666666674],"xyz":[0.184663817548196107,0.260448846574297566,0.215074571282354909],"hpluv":[147.624029462041108,81.8102930750829671,58.0796295741768631],"hsluv":[147.624029462041108,63.1432913181764448,58.0796295741768631]},"#559988":{"lch":[58.4997327930321092,31.9103493306277741,167.047427400638497],"luv":[58.4997327930321092,-31.0984204046450543,7.15252701768072],"rgb":[0.333333333333333315,0.6,0.533333333333333326],"xyz":[0.195804234650139963,0.264905013415075108,0.273747434685927105],"hpluv":[167.047427400638497,69.2176742514874093,58.4997327930321092],"hsluv":[167.047427400638497,65.0191416919107752,58.4997327930321092]},"#559999":{"lch":[58.9861545428406373,31.2617491707160085,192.177050630060933],"luv":[58.9861545428406373,-30.5583742056962677,-6.59414339527129822],"rgb":[0.333333333333333315,0.6,0.6],"xyz":[0.208861198759212663,0.270127799058704321,0.342514112327045],"hpluv":[192.177050630060933,67.2515837667627494,58.9861545428406373],"hsluv":[192.177050630060933,66.9883413382070216,58.9861545428406373]},"#5599aa":{"lch":[59.5393884281606915,36.5784761777074152,214.841775998693208],"luv":[59.5393884281606915,-30.0211576326403424,-20.8977274812183715],"rgb":[0.333333333333333315,0.6,0.66666666666666663],"xyz":[0.223918891724465219,0.276150876244805388,0.421817961944043585],"hpluv":[214.841775998693208,77.957978019602777,59.5393884281606915],"hsluv":[214.841775998693208,69.0007957908225,59.5393884281606915]},"#5599bb":{"lch":[60.1593377819191488,46.1560476826162613,230.269588518041076],"luv":[60.1593377819191488,-29.5018430010724479,-35.4967885479802],"rgb":[0.333333333333333315,0.6,0.733333333333333282],"xyz":[0.241056483831801838,0.283005913087740146,0.512075947042685331],"hpluv":[230.269588518041076,97.3564866347465312,60.1593377819191488],"hsluv":[230.269588518041076,71.0120526680823758,60.1593377819191488]},"#5599cc":{"lch":[60.8453721774886276,57.9560381686168284,239.960256152221575],"luv":[60.8453721774886276,-29.0128279276179057,-50.1712883614184761],"rgb":[0.333333333333333315,0.6,0.8],"xyz":[0.260348859275523592,0.290722863265228948,0.613682457712955487],"hpluv":[239.960256152221575,120.867757439807349,60.8453721774886276],"hsluv":[239.960256152221575,72.9851794318318667,60.8453721774886276]},"#5599dd":{"lch":[61.596386585270082,70.7674616346471623,246.194917025964173],"luv":[61.596386585270082,-28.563620381934669,-64.7468394355121],"rgb":[0.333333333333333315,0.6,0.866666666666666696],"xyz":[0.281867184826157136,0.29933019348548251,0.727012305612961485],"hpluv":[246.194917025964173,145.7866339341696,61.596386585270082],"hsluv":[246.194917025964173,74.8914393241793164,61.596386585270082]},"#5599ee":{"lch":[62.4108626997728209,83.9573424358243,250.401946751580681],"luv":[62.4108626997728209,-28.1609349474859023,-79.0935970339554757],"rgb":[0.333333333333333315,0.6,0.933333333333333348],"xyz":[0.305679365092331845,0.308855065591952527,0.852423121681484708],"hpluv":[250.401946751580681,170.701691169737018,62.4108626997728209],"hsluv":[250.401946751580681,83.3865807682554845,62.4108626997728209]},"#5599ff":{"lch":[63.2869312953637,97.1853240423286309,253.372761171991215],"luv":[63.2869312953637,-27.8089904224615658,-93.1216798650875859],"rgb":[0.333333333333333315,0.6,1],"xyz":[0.331850413502163266,0.319323484955885251,0.990257309973266553],"hpluv":[253.372761171991215,194.861470594675211,63.2869312953637],"hsluv":[253.372761171991215,99.9999999999986215,63.2869312953637]},"#440000":{"lch":[10.7708306123528814,36.2226426723970221,12.1770506300617765],"luv":[10.7708306123528814,35.407649887332731,7.64056094984030221],"rgb":[0.266666666666666663,0,0],"xyz":[0.0238384275584062923,0.0122916892098035059,0.00111742629180027137],"hpluv":[12.1770506300617765,426.746789183125145,10.7708306123528814],"hsluv":[12.1770506300617765,100.000000000002203,10.7708306123528814]},"#440011":{"lch":[11.0614468716721248,32.5827232355020158,4.73042674181564848],"luv":[11.0614468716721248,32.4717377839629151,2.68702414036008763],"rgb":[0.266666666666666663,0,0.0666666666666666657],"xyz":[0.024850093058043414,0.0126963554096583605,0.00644553125655590239],"hpluv":[4.73042674181564848,373.778888471265759,11.0614468716721248],"hsluv":[4.73042674181564848,99.999999999996831,11.0614468716721248]},"#440022":{"lch":[11.5842423793746683,28.6540476811609395,350.304317532446703],"luv":[11.5842423793746683,28.2447579299318896,-4.82577434136679706],"rgb":[0.266666666666666663,0,0.133333333333333331],"xyz":[0.0267254511965204326,0.0134464986650491784,0.0163224174525351],"hpluv":[350.304317532446703,313.875682434467763,11.5842423793746683],"hsluv":[350.304317532446703,99.9999999999974847,11.5842423793746683]},"#440033":{"lch":[12.4041921203750505,27.3919603751935874,328.642516788172941],"luv":[12.4041921203750505,23.3910134404871357,-14.2541216293086901],"rgb":[0.266666666666666663,0,0.2],"xyz":[0.0298132019289781731,0.0146815989580322912,0.0325845713101462417],"hpluv":[328.642516788172941,280.216663156604227,12.4041921203750505],"hsluv":[328.642516788172941,99.9999999999981668,12.4041921203750505]},"#440044":{"lch":[13.5105146335658439,30.7747615701782742,307.715012949243601],"luv":[13.5105146335658439,18.8259784531467211,-24.3447835271332202],"rgb":[0.266666666666666663,0,0.266666666666666663],"xyz":[0.0342711971731970502,0.0164647970557198695,0.0560633462630328802],"hpluv":[307.715012949243601,289.042783730483222,13.5105146335658439],"hsluv":[307.715012949243601,99.9999999999987779,13.5105146335658439]},"#440055":{"lch":[14.871657786523194,37.5926423334987589,293.358518425732086],"luv":[14.871657786523194,14.9048564440935021,-34.5116214049025416],"rgb":[0.266666666666666663,0,0.333333333333333315],"xyz":[0.0402336112125590423,0.0188497626714647,0.0874653935370067886],"hpluv":[293.358518425732086,320.761913781574776,14.871657786523194],"hsluv":[293.358518425732086,99.999999999999261,14.871657786523194]},"#440066":{"lch":[16.4463097679727497,46.0898544445027,284.618444278650202],"luv":[16.4463097679727497,11.6321972733021664,-44.597832562922008],"rgb":[0.266666666666666663,0,0.4],"xyz":[0.0478186069860672205,0.0218837609808680139,0.127413037944150764],"hpluv":[284.618444278650202,355.611827609674208,16.4463097679727497],"hsluv":[284.618444278650202,99.9999999999996447,16.4463097679727497]},"#440077":{"lch":[18.1919811936642475,55.3198462112611651,279.251207899416613],"luv":[18.1919811936642475,8.8934050845755,-54.6002997321373],"rgb":[0.266666666666666663,0,0.466666666666666674],"xyz":[0.0571326200062691331,0.0256093661889488303,0.176466839850548673],"hpluv":[279.251207899416613,385.869357778503058,18.1919811936642475],"hsluv":[279.251207899416613,100.000000000000028,18.1919811936642475]},"#440088":{"lch":[20.0701231572475791,64.8751824688912,275.807883046004235],"luv":[20.0701231572475791,6.56492582220058196,-64.5421648949036353],"rgb":[0.266666666666666663,0,0.533333333333333326],"xyz":[0.0682730371082129611,0.0300655330297264212,0.235139703254120841],"hpluv":[275.807883046004235,410.173767132845569,20.0701231572475791],"hsluv":[275.807883046004235,100.000000000000284,20.0701231572475791]},"#440099":{"lch":[22.0482755473713041,74.5764302852581267,273.495279820248],"luv":[22.0482755473713041,4.54664979059262,-74.4377050275844283],"rgb":[0.266666666666666663,0,0.6],"xyz":[0.0813300012172856746,0.0352883186733555787,0.303906380895238748],"hpluv":[273.495279820248,429.20649964036636,22.0482755473713041],"hsluv":[273.495279820248,100.000000000000384,22.0482755473713041]},"#4400aa":{"lch":[24.1003299188330615,84.3353594354864811,271.878389761009714],"luv":[24.1003299188330615,2.7643624238057809,-84.290041828810061],"rgb":[0.266666666666666663,0,0.66666666666666663],"xyz":[0.0963876941825382166,0.0413113958594566871,0.383210230512237349],"hpluv":[271.878389761009714,444.044033459252,24.1003299188330615],"hsluv":[271.878389761009714,100.000000000000398,24.1003299188330615]},"#4400bb":{"lch":[26.2058661049044161,94.1030045511215434,270.708980538846049],"luv":[26.2058661049044161,1.16440507249082947,-94.0958002589677704],"rgb":[0.266666666666666663,0,0.733333333333333282],"xyz":[0.113525286289874863,0.0481664327023914457,0.473468215610879095],"hpluv":[270.708980538846049,455.663559843794246,26.2058661049044161],"hsluv":[270.708980538846049,100.000000000000597,26.2058661049044161]},"#4400cc":{"lch":[28.3491756730399374,103.84959146554381,269.838851579513857],"luv":[28.3491756730399374,-0.292083914573144032,-103.849180711969012],"rgb":[0.266666666666666663,0,0.8],"xyz":[0.132817661733596604,0.0558833828798802473,0.575074726281149196],"hpluv":[269.838851579513857,464.840204698682,28.3491756730399374],"hsluv":[269.838851579513857,100.00000000000054,28.3491756730399374]},"#4400dd":{"lch":[30.5182871942398464,113.556060117994207,269.175711116484081],"luv":[30.5182871942398464,-1.63362415099869285,-113.544308803456943],"rgb":[0.266666666666666663,0,0.866666666666666696],"xyz":[0.154335987284230147,0.0644907131001337813,0.688404574181155193],"hpluv":[269.175711116484081,472.160320460814546,30.5182871942398464],"hsluv":[269.175711116484081,100.000000000000583,30.5182871942398464]},"#4400ee":{"lch":[32.7041215904695406,123.209994802530275,268.6598990566049],"luv":[32.7041215904695406,-2.88151723804096926,-123.176295112519156],"rgb":[0.266666666666666663,0,0.933333333333333348],"xyz":[0.178148167550404884,0.0740155852066038122,0.813815390249678416],"hpluv":[268.6598990566049,478.060407115886846,32.7041215904695406],"hsluv":[268.6598990566049,100.000000000000682,32.7041215904695406]},"#4400ff":{"lch":[34.8998090420324161,132.803387625161918,268.251574356178935],"luv":[34.8998090420324161,-4.05197057625710322,-132.741558297197031],"rgb":[0.266666666666666663,0,1],"xyz":[0.204319215960236278,0.0844840045705365084,0.951649578541460262],"hpluv":[268.251574356178935,482.864668803745815,34.8998090420324161],"hsluv":[268.251574356178935,100.000000000000824,34.8998090420324161]},"#441100":{"lch":[13.412021407860891,32.8203905090178907,19.8063713084711637],"luv":[13.412021407860891,30.878837797926078,11.1209446277644677],"rgb":[0.266666666666666663,0.0666666666666666657,0],"xyz":[0.025842827819334703,0.0163004897316603795,0.00178555971210972225],"hpluv":[19.8063713084711637,310.519467471828818,13.412021407860891],"hsluv":[19.8063713084711637,100.00000000000226,13.412021407860891]},"#441111":{"lch":[13.6534230745514442,29.3615880370140658,12.1770506300618155],"luv":[13.6534230745514442,28.7009658227648572,6.19333616848069],"rgb":[0.266666666666666663,0.0666666666666666657,0.0666666666666666657],"xyz":[0.0268544933189718248,0.0167051559315152323,0.00711366467686535414],"hpluv":[12.1770506300618155,272.883526996448495,13.6534230745514442],"hsluv":[12.1770506300618155,63.9450685777404857,13.6534230745514442]},"#441122":{"lch":[14.0908014406849,25.4444274015795777,356.558123350094036],"luv":[14.0908014406849,25.3985311285907684,-1.52758053936917793],"rgb":[0.266666666666666663,0.0666666666666666657,0.133333333333333331],"xyz":[0.0287298514574488434,0.0174552991869060536,0.0169905508728445502],"hpluv":[356.558123350094036,229.137575437366081,14.0908014406849],"hsluv":[356.558123350094036,68.4589860949294,14.0908014406849]},"#441133":{"lch":[14.7844111345271223,24.27011571268606,331.648240125609],"luv":[14.7844111345271223,21.358884082162259,-11.5254755854986932],"rgb":[0.266666666666666663,0.0666666666666666657,0.2],"xyz":[0.0318176021899065839,0.0186903994798891665,0.0332527047304557],"hpluv":[331.648240125609,208.308572243058649,14.7844111345271223],"hsluv":[331.648240125609,73.8494669394836762,14.7844111345271223]},"#441144":{"lch":[15.733846020816415,28.3218749128348932,307.715012949243942],"luv":[15.733846020816415,17.3254634530922189,-22.4043949865608347],"rgb":[0.266666666666666663,0.0666666666666666657,0.266666666666666663],"xyz":[0.0362755974341254644,0.0204735975775767395,0.0567314796833423354],"hpluv":[307.715012949243942,228.415952286272613,15.733846020816415],"hsluv":[307.715012949243942,79.0249627886423127,15.733846020816415]},"#441155":{"lch":[16.9210970319156715,36.0495621705848492,292.339268883647492],"luv":[16.9210970319156715,13.7020846665308547,-33.3440220801582683],"rgb":[0.266666666666666663,0.0666666666666666657,0.333333333333333315],"xyz":[0.0422380114734874565,0.0228585631933215724,0.0881335269573162439],"hpluv":[292.339268883647492,270.340308544513618,16.9210970319156715],"hsluv":[292.339268883647492,83.4150097743113292,16.9210970319156715]},"#441166":{"lch":[18.3175541838796221,45.305096001334384,283.521508601515677],"luv":[18.3175541838796221,10.592801308498224,-44.0493392019540195],"rgb":[0.266666666666666663,0.0666666666666666657,0.4],"xyz":[0.0498230072469956348,0.025892561502724884,0.128081171364460206],"hpluv":[283.521508601515677,313.84766122316239,18.3175541838796221],"hsluv":[283.521508601515677,86.9023417707839485,18.3175541838796221]},"#441177":{"lch":[19.8903241139664431,55.0653797371295326,278.304914930180701],"luv":[19.8903241139664431,7.95370312292975612,-54.4879312529533735],"rgb":[0.266666666666666663,0.0666666666666666657,0.466666666666666674],"xyz":[0.0591370202671975473,0.0296181667108057,0.177134973270858115],"hpluv":[278.304914930180701,351.298345972174616,19.8903241139664431],"hsluv":[278.304914930180701,89.590178354910762,19.8903241139664431]},"#441188":{"lch":[21.6068634066631873,64.9598488176177824,275.03199667533886],"luv":[21.6068634066631873,5.69776159856002,-64.7094851716016422],"rgb":[0.266666666666666663,0.0666666666666666657,0.533333333333333326],"xyz":[0.0702774373691413823,0.0340743335515832912,0.235807836674430282],"hpluv":[275.03199667533886,381.498298720028686,21.6068634066631873],"hsluv":[275.03199667533886,91.6417594317348545,21.6068634066631873]},"#441199":{"lch":[23.437698327746169,74.8628785955689153,272.864058339832695],"luv":[23.437698327746169,3.74063102269824954,-74.769367197849931],"rgb":[0.266666666666666663,0.0666666666666666657,0.6],"xyz":[0.0833344014782140818,0.0392971191952124557,0.304574514315548162],"hpluv":[272.864058339832695,405.313331644098525,23.437698327746169],"hsluv":[272.864058339832695,93.2101268622270283,23.437698327746169]},"#4411aa":{"lch":[25.3575925472355337,84.7316846097945273,271.361966301038933],"luv":[25.3575925472355337,2.01394993465393446,-84.7077468858332878],"rgb":[0.266666666666666663,0.0666666666666666657,0.66666666666666663],"xyz":[0.0983920944434666378,0.0453201963813135572,0.383878363932546762],"hpluv":[271.361966301038933,424.011024215555381,25.3575925472355337],"hsluv":[271.361966301038933,94.4180404350203872,25.3575925472355337]},"#4411bb":{"lch":[27.345710117802,94.5503656807627,270.282295464151048],"luv":[27.345710117802,0.465846378280231621,-94.5492180693092337],"rgb":[0.266666666666666663,0.0666666666666666657,0.733333333333333282],"xyz":[0.115529686550803284,0.0521752332242483158,0.474136349031188509],"hpluv":[270.282295464151048,438.746165283595928,27.345710117802],"hsluv":[270.282295464151048,95.3579307613671,27.345710117802]},"#4411cc":{"lch":[29.3852471201757481,104.311620276565549,269.482476007084244],"luv":[29.3852471201757481,-0.942181651797373232,-104.307365120864873],"rgb":[0.266666666666666663,0.0666666666666666657,0.8],"xyz":[0.134822061994525,0.0598921834017371174,0.575742859701458665],"hpluv":[269.482476007084244,450.445933463405538,29.3852471201757481],"hsluv":[269.482476007084244,96.097629526357963,29.3852471201757481]},"#4411dd":{"lch":[31.4628506304707116,114.011096091836691,268.874895171215144],"luv":[31.4628506304707116,-2.23866735310417164,-113.989115272223103],"rgb":[0.266666666666666663,0.0666666666666666657,0.866666666666666696],"xyz":[0.156340387545158555,0.0684995136219906514,0.689072707601464662],"hpluv":[268.874895171215144,459.820552568088715,31.4628506304707116],"hsluv":[268.874895171215144,96.6865382756064378,31.4628506304707116]},"#4411ee":{"lch":[33.5680052377948073,123.64577428881995,268.40345713539682],"luv":[33.5680052377948073,-3.44493495426529961,-123.597774747940718],"rgb":[0.266666666666666663,0.0666666666666666657,0.933333333333333348],"xyz":[0.180152567811333292,0.0780243857284606823,0.814483523669987886],"hpluv":[268.40345713539682,467.404695294247745,33.5680052377948073],"hsluv":[268.40345713539682,97.1606953094382817,33.5680052377948073]},"#4411ff":{"lch":[35.6924730299026081,133.21354134861582,268.030966648817412],"luv":[35.6924730299026081,-4.57713081064657,-133.134884505082312],"rgb":[0.266666666666666663,0.0666666666666666657,1],"xyz":[0.206323616221164685,0.0884928050923933784,0.952317711961769731],"hpluv":[268.030966648817412,473.599309181226886,35.6924730299026081],"hsluv":[268.030966648817412,99.999999999999531,35.6924730299026081]},"#99aa00":{"lch":[66.1528677227115907,74.3468963767982842,94.6234982733471384],"luv":[66.1528677227115907,-5.99293371363564553,74.1049643840839565],"rgb":[0.6,0.66666666666666663,0],"xyz":[0.275106719282890377,0.355217387920677,0.0540714229698005533],"hpluv":[94.6234982733471384,142.611154102436132,66.1528677227115907],"hsluv":[94.6234982733471384,100.000000000002217,66.1528677227115907]},"#99aa11":{"lch":[66.184052262829,73.0311244080130706,94.7508326892346275],"luv":[66.184052262829,-6.04863423256243316,72.7802112955118901],"rgb":[0.6,0.66666666666666663,0.0666666666666666657],"xyz":[0.276118384782527482,0.355622054120531828,0.059399527934556183],"hpluv":[94.7508326892346275,140.021252931940353,66.184052262829],"hsluv":[94.7508326892346275,98.1390759685954,66.184052262829]},"#99aa22":{"lch":[66.2417975711995695,70.6178785015108872,94.9968669170454376],"luv":[66.2417975711995695,-6.15090676716144458,70.3494926065273],"rgb":[0.6,0.66666666666666663,0.133333333333333331],"xyz":[0.277993742921004539,0.356372197375922628,0.0692764141305353826],"hpluv":[94.9968669170454376,135.276352185575888,66.2417975711995695],"hsluv":[94.9968669170454376,94.7283581868373403,66.2417975711995695]},"#99aa33":{"lch":[66.3366981156763273,66.7162457715457,95.432805623918],"luv":[66.3366981156763273,-6.31658226271684953,66.416550937003791],"rgb":[0.6,0.66666666666666663,0.2],"xyz":[0.281081493653462244,0.357607297668905755,0.0855385679881465189],"hpluv":[95.432805623918,127.619510800204154,66.3366981156763273],"hsluv":[95.432805623918,89.220332613511431,66.3366981156763273]},"#99aa44":{"lch":[66.4733277612737652,61.2361369282317085,96.1403021162386],"luv":[66.4733277612737652,-6.55002950525979344,60.8848222414533211],"rgb":[0.6,0.66666666666666663,0.266666666666666663],"xyz":[0.28553948889768116,0.359390495766593321,0.109017342941033157],"hpluv":[96.1403021162386,116.896010950353556,66.4733277612737652],"hsluv":[96.1403021162386,81.495914591183535,66.4733277612737652]},"#99aa55":{"lch":[66.6553605356915853,54.1785870660784568,97.2658616968833769],"luv":[66.6553605356915853,-6.85216039608048888,53.7435316515674231],"rgb":[0.6,0.66666666666666663,0.333333333333333315],"xyz":[0.291501902937043145,0.361775461382338182,0.140419390215007073],"hpluv":[97.2658616968833769,103.141138146130345,66.6553605356915853],"hsluv":[97.2658616968833769,71.5645731506566563,66.6553605356915853]},"#99aa66":{"lch":[66.8857782590742573,45.6318272725976186,99.1048787772859328],"luv":[66.8857782590742573,-7.22087825912546055,45.0568815765480224],"rgb":[0.6,0.66666666666666663,0.4],"xyz":[0.29908689871055133,0.3648094596917415,0.180367034622151035],"hpluv":[99.1048787772859328,86.5711928674077882,66.8857782590742573],"hsluv":[99.1048787772859328,59.5487850828384495,66.8857782590742573]},"#99aa77":{"lch":[67.16697930835997,35.7793898766585272,102.348317274789],"luv":[67.16697930835997,-7.65157453727816339,34.9516544250255947],"rgb":[0.6,0.66666666666666663,0.466666666666666674],"xyz":[0.308400911730753235,0.368535064899822296,0.229420836528548944],"hpluv":[102.348317274789,67.5952906506277742,67.16697930835997],"hsluv":[102.348317274789,45.6652750399669927,67.16697930835997]},"#99aa88":{"lch":[67.5008436530857523,24.9656779050761699,109.02352802026725],"luv":[67.5008436530857523,-8.13772239581267165,23.6021725158659379],"rgb":[0.6,0.66666666666666663,0.533333333333333326],"xyz":[0.319541328832697036,0.372991231740599893,0.288093699932121083],"hpluv":[109.02352802026725,46.9324783865521482,67.5008436530857523],"hsluv":[109.02352802026725,30.201776912068496,67.5008436530857523]},"#99aa99":{"lch":[67.8887769686822509,14.1753245834603039,127.715012949228395],"luv":[67.8887769686822509,-8.67153282620695443,11.213578621049983],"rgb":[0.6,0.66666666666666663,0.6],"xyz":[0.332598292941769791,0.378214017384229051,0.356860377573239],"hpluv":[127.715012949228395,26.4956363039349618,67.8887769686822509],"hsluv":[127.715012949228395,13.4910013502760879,67.8887769686822509]},"#99aaaa":{"lch":[68.3317447891119798,9.45739632834534838,192.177050630059227],"luv":[68.3317447891119798,-9.24460926466251642,-1.99487965930680966],"rgb":[0.6,0.66666666666666663,0.66666666666666663],"xyz":[0.347655985907022291,0.384237094570330173,0.436164227190237619],"hpluv":[192.177050630059227,17.5625836428344968,68.3317447891119798],"hsluv":[192.177050630059227,17.4938385380963979,68.3317447891119798]},"#99aabb":{"lch":[68.8303024285350205,18.6222464744475609,238.07162859052869],"luv":[68.8303024285350205,-9.84853629911531137,-15.8048852105949411],"rgb":[0.6,0.66666666666666663,0.733333333333333282],"xyz":[0.364793578014358966,0.391092131413264932,0.52642221228887931],"hpluv":[238.07162859052869,34.3314162301526622,68.8303024285350205],"hsluv":[238.07162859052869,21.6214176811966929,68.8303024285350205]},"#99aacc":{"lch":[69.3846237501618646,31.7868422871013969,250.758533684062627],"luv":[69.3846237501618646,-10.475354770609286,-30.0111693376804425],"rgb":[0.6,0.66666666666666663,0.8],"xyz":[0.38408595345808072,0.398809081590753733,0.628028722959149466],"hpluv":[250.758533684062627,58.1330991079694357,69.3846237501618646],"hsluv":[250.758533684062627,38.7837447081888556,69.3846237501618646]},"#99aadd":{"lch":[69.9945303682966,45.800012761152324,255.951164454091042],"luv":[69.9945303682966,-11.1178995355210173,-44.4300965432191859],"rgb":[0.6,0.66666666666666663,0.866666666666666696],"xyz":[0.405604279008714208,0.40741641181100724,0.741358570859155463],"hpluv":[255.951164454091042,83.0311057452140346,69.9945303682966],"hsluv":[255.951164454091042,58.1375555879370935,69.9945303682966]},"#99aaee":{"lch":[70.6595219654936,60.0690973767372896,258.700300270425373],"luv":[70.6595219654936,-11.7699993169592201,-58.9046990972259],"rgb":[0.6,0.66666666666666663,0.933333333333333348],"xyz":[0.429416459274889,0.416941283917477257,0.866769386927678687],"hpluv":[258.700300270425373,107.874733956899746,70.6595219654936],"hsluv":[258.700300270425373,78.5353046306170199,70.6595219654936]},"#99aaff":{"lch":[71.378807837336737,74.3523754541628676,260.378973553217],"luv":[71.378807837336737,-12.4265554124673407,-73.3065921746310636],"rgb":[0.6,0.66666666666666663,1],"xyz":[0.455587507684720339,0.42740970328141,1.00460357521946064],"hpluv":[260.378973553217,132.179737350703419,71.378807837336737],"hsluv":[260.378973553217,99.99999999999784,71.378807837336737]},"#442200":{"lch":[17.3350542344952459,28.221345162136295,35.6239292836567927],"luv":[17.3350542344952459,22.9399340369809366,16.4378754448194186],"rgb":[0.266666666666666663,0.133333333333333331,0],"xyz":[0.0295584515541026382,0.023731737201196354,0.00302410095703233277],"hpluv":[35.6239292836567927,206.581692971425213,17.3350542344952459],"hsluv":[35.6239292836567927,100.000000000002331,17.3350542344952459]},"#442211":{"lch":[17.5234603686317101,24.6335663377647,28.604455948929278],"luv":[17.5234603686317101,21.6269347365689519,11.7935696215031331],"rgb":[0.266666666666666663,0.133333333333333331,0.0666666666666666657],"xyz":[0.03057011705373976,0.0241364034010512069,0.00835220592178796337],"hpluv":[28.604455948929278,178.380241443971528,17.5234603686317101],"hsluv":[28.604455948929278,74.2089163354216765,17.5234603686317101]},"#442222":{"lch":[17.8672188947691239,19.9697171584766728,12.1770506300619807],"luv":[17.8672188947691239,19.520407715454283,4.21227800744330061],"rgb":[0.266666666666666663,0.133333333333333331,0.133333333333333331],"xyz":[0.0324454751922167786,0.0248865466564420282,0.0182290921177671594],"hpluv":[12.1770506300619807,141.825486578211439,17.8672188947691239],"hsluv":[12.1770506300619807,33.2341074785113406,17.8672188947691239]},"#442233":{"lch":[18.4184657925371695,17.8165085202964129,340.00784749027008],"luv":[18.4184657925371695,16.7428760354525643,-6.09131167444770583],"rgb":[0.266666666666666663,0.133333333333333331,0.2],"xyz":[0.0355332259246745191,0.026121646949425141,0.0344912459753783],"hpluv":[340.00784749027008,122.746318288975218,18.4184657925371695],"hsluv":[340.00784749027008,42.0888291674463915,18.4184657925371695]},"#442244":{"lch":[19.1844846541763658,22.4593922221866436,307.715012949244738],"luv":[19.1844846541763658,13.7391814744519145,-17.7668002578431441],"rgb":[0.266666666666666663,0.133333333333333331,0.266666666666666663],"xyz":[0.0399912211688934,0.0279048450471127141,0.0579700209282649412],"hpluv":[307.715012949244738,148.554970924606664,19.1844846541763658],"hsluv":[307.715012949244738,51.3954955066877517,19.1844846541763658]},"#442255":{"lch":[20.1595909359386596,31.6741463862469885,290.023039430837684],"luv":[20.1595909359386596,10.8451637140407797,-29.7596030436068872],"rgb":[0.266666666666666663,0.133333333333333331,0.333333333333333315],"xyz":[0.0459536352082553917,0.030289810662857547,0.0893720682022388496],"hpluv":[290.023039430837684,199.371249454156271,20.1595909359386596],"hsluv":[290.023039430837684,59.9942694866150177,20.1595909359386596]},"#442266":{"lch":[21.3287002071660226,42.3208084503031685,281.207510247893651],"luv":[21.3287002071660226,8.22559640374024781,-41.5137373852322256],"rgb":[0.266666666666666663,0.133333333333333331,0.4],"xyz":[0.0535386309817635631,0.0333238089722608585,0.129319712609382825],"hpluv":[281.207510247893651,251.784442505332123,21.3287002071660226],"hsluv":[281.207510247893651,67.3437899952651406,21.3287002071660226]},"#442277":{"lch":[22.6709734328231463,53.1747129073287113,276.391210783405313],"luv":[22.6709734328231463,5.91922219198187882,-52.8442324328661215],"rgb":[0.266666666666666663,0.133333333333333331,0.466666666666666674],"xyz":[0.0628526440019654825,0.0370494141803416749,0.178373514515780734],"hpluv":[276.391210783405313,297.628360698128461,22.6709734328231463],"hsluv":[276.391210783405313,73.3546851738733,22.6709734328231463]},"#442288":{"lch":[24.1630625686767715,63.8732961962266543,273.501787345358252],"luv":[24.1630625686767715,3.90136026108148481,-63.7540379512086801],"rgb":[0.266666666666666663,0.133333333333333331,0.533333333333333326],"xyz":[0.0739930611039093106,0.0415055810211192727,0.237046377919352902],"hpluv":[273.501787345358252,335.433687598002,24.1630625686767715],"hsluv":[273.501787345358252,78.1624380374364875,24.1630625686767715]},"#442299":{"lch":[25.7815797239733442,74.3421908873045112,271.638748742297366],"luv":[25.7815797239733442,2.1260128283266071,-74.3117851715204836],"rgb":[0.266666666666666663,0.133333333333333331,0.6],"xyz":[0.087050025212982024,0.0467283666647484303,0.305813055560470781],"hpluv":[271.638748742297366,365.902315457699217,25.7815797239733442],"hsluv":[271.638748742297366,81.974423252689391,25.7815797239733442]},"#4422aa":{"lch":[27.5046927955253,84.5952413694672885,270.370058715866037],"luv":[27.5046927955253,0.546375125789773097,-84.5934769150692176],"rgb":[0.266666666666666663,0.133333333333333331,0.66666666666666663],"xyz":[0.102107718178234566,0.0527514438508495317,0.385116905177469382],"hpluv":[270.370058715866037,390.281946032504152,27.5046927955253],"hsluv":[270.370058715866037,84.9950544768410765,27.5046927955253]},"#4422bb":{"lch":[29.3129652277151251,94.666070770970677,269.4687873747244],"luv":[29.3129652277151251,-0.87767531850734,-94.6620020982533],"rgb":[0.266666666666666663,0.133333333333333331,0.733333333333333282],"xyz":[0.119245310285571213,0.0596064806937842903,0.475374890276111128],"hpluv":[269.4687873747244,409.801860030343846,29.3129652277151251],"hsluv":[269.4687873747244,87.3984435941311517,29.3129652277151251]},"#4422cc":{"lch":[31.1896477872922873,104.586362634530047,268.806646243455475],"luv":[31.1896477872922873,-2.17816227055809408,-104.563678484665701],"rgb":[0.266666666666666663,0.133333333333333331,0.8],"xyz":[0.138537685729292953,0.0673234308712731,0.576981400946381284],"hpluv":[268.806646243455475,425.504262664631483,31.1896477872922873],"hsluv":[268.806646243455475,89.3235413687926325,31.1896477872922873]},"#4422dd":{"lch":[33.1206275871571,114.38069493574325,268.306702684458742],"luv":[33.1206275871571,-3.37987077956927,-114.330747603157818],"rgb":[0.266666666666666663,0.133333333333333331,0.866666666666666696],"xyz":[0.160056011279926497,0.0759307610915266329,0.690311248846387282],"hpluv":[268.306702684458742,438.22131720165,33.1206275871571],"hsluv":[268.306702684458742,90.877884626449017,33.1206275871571]},"#4422ee":{"lch":[35.0941942457284952,124.066768949832422,267.920557621455941],"luv":[35.0941942457284952,-4.50178121539094178,-123.985068147498538],"rgb":[0.266666666666666663,0.133333333333333331,0.933333333333333348],"xyz":[0.183868191546101234,0.0854556331979966499,0.815722064914910505],"hpluv":[267.920557621455941,448.600262181889605,35.0941942457284952],"hsluv":[267.920557621455941,93.3452679661598523,35.0941942457284952]},"#4422ff":{"lch":[37.1007304630435,133.656986375695226,267.616535799179189],"luv":[37.1007304630435,-5.55843332369103926,-133.54135623850334],"rgb":[0.266666666666666663,0.133333333333333331,1],"xyz":[0.210039239955932627,0.0959240525619293599,0.95355625320669235],"hpluv":[267.616535799179189,457.139270395610822,37.1007304630435],"hsluv":[267.616535799179189,99.999999999999531,37.1007304630435]},"#bbaa00":{"lch":[68.9787767407419,76.4078567958722346,76.7962953219783344],"luv":[68.9787767407419,17.4526104568015299,74.3879490803561652],"rgb":[0.733333333333333282,0.66666666666666663,0],"xyz":[0.348671553863065253,0.393149255751080451,0.0575197745907461769],"hpluv":[76.7962953219783344,140.560034871296551,68.9787767407419],"hsluv":[76.7962953219783344,100.000000000002245,68.9787767407419]},"#bbaa11":{"lch":[69.0079227935645747,75.1793224892161902,76.6760735029220797],"luv":[69.0079227935645747,17.325534429098667,73.1556996185784811],"rgb":[0.733333333333333282,0.66666666666666663,0.0666666666666666657],"xyz":[0.349683219362702358,0.393553921950935304,0.0628478795555018],"hpluv":[76.6760735029220797,138.241608756115426,69.0079227935645747],"hsluv":[76.6760735029220797,98.327691673723,69.0079227935645747]},"#bbaa22":{"lch":[69.0618990033698168,72.923722885125926,76.4446579961253718],"luv":[69.0618990033698168,17.0921879270318975,70.8923583420220496],"rgb":[0.733333333333333282,0.66666666666666663,0.133333333333333331],"xyz":[0.351558577501179415,0.394304065206326104,0.072724765751481],"hpluv":[76.4446579961253718,133.98915323660276,69.0618990033698168],"hsluv":[76.4446579961253718,95.2591470849694701,69.0618990033698168]},"#bbaa33":{"lch":[69.1506211183474448,69.2704933393546298,76.037430434814425],"luv":[69.1506211183474448,16.7141363744442764,67.2237970716773248],"rgb":[0.733333333333333282,0.66666666666666663,0.2],"xyz":[0.35464632823363712,0.395539165499309231,0.0889869196090921494],"hpluv":[76.037430434814425,127.113454601419591,69.1506211183474448],"hsluv":[76.037430434814425,90.2940538071316752,69.1506211183474448]},"#bbaa44":{"lch":[69.2783900215706439,64.125663575375043,75.3840533289293688],"luv":[69.2783900215706439,16.1813855024742246,62.0504914743025964],"rgb":[0.733333333333333282,0.66666666666666663,0.266666666666666663],"xyz":[0.359104323477856036,0.397322363596996797,0.112465694561978788],"hpluv":[75.3840533289293688,117.455514697890109,69.2783900215706439],"hsluv":[75.3840533289293688,83.3108908827552455,69.2783900215706439]},"#bbaa55":{"lch":[69.4486803199850158,57.4759826537307603,74.3632861967268752],"luv":[69.4486803199850158,15.4919003466967737,55.3487994961044762],"rgb":[0.733333333333333282,0.66666666666666663,0.333333333333333315],"xyz":[0.365066737517218,0.399707329212741658,0.143867741835952689],"hpluv":[74.3632861967268752,105.017514149864908,69.4486803199850158],"hsluv":[74.3632861967268752,74.2978448337225501,69.4486803199850158]},"#bbaa66":{"lch":[69.6643364030220766,49.3851711615203186,72.7428070953876],"luv":[69.6643364030220766,14.6506772614363818,47.1619845472377079],"rgb":[0.733333333333333282,0.66666666666666663,0.4],"xyz":[0.372651733290726206,0.402741327522145,0.183815386243096651],"hpluv":[72.7428070953876,89.9550160304510342,69.6643364030220766],"hsluv":[72.7428070953876,63.3404983901227254,69.6643364030220766]},"#bbaa77":{"lch":[69.927675331165787,39.998456174204172,70.017617272721],"luv":[69.927675331165787,13.6687200676018641,37.5904587366697314],"rgb":[0.733333333333333282,0.66666666666666663,0.466666666666666674],"xyz":[0.381965746310928111,0.406466932730225772,0.23286918814949456],"hpluv":[70.017617272721,72.5827577171275635,69.927675331165787],"hsluv":[70.017617272721,50.6076787731359303,69.927675331165787]},"#bbaa88":{"lch":[70.2405480333122,29.5797452752191568,64.8698942165899837],"luv":[70.2405480333122,12.5617839686329518,26.7798975739685403],"rgb":[0.733333333333333282,0.66666666666666663,0.533333333333333326],"xyz":[0.393106163412871912,0.41092309957100337,0.291542051553066728],"hpluv":[64.8698942165899837,53.4374671266607422,70.2405480333122],"hsluv":[64.8698942165899837,36.3337734813298923,70.2405480333122]},"#bbaa99":{"lch":[70.6043801086793,18.7359983934483161,52.7186742094296079],"luv":[70.6043801086793,11.3489394865138475,14.907689570511744],"rgb":[0.733333333333333282,0.66666666666666663,0.6],"xyz":[0.406163127521944611,0.416145885214632527,0.360308729194184663],"hpluv":[52.7186742094296079,33.6732102985619051,70.6043801086793],"hsluv":[52.7186742094296079,20.7983697782308,70.6043801086793]},"#bbaaaa":{"lch":[71.0202025015365876,10.2824341490213804,12.177050630064155],"luv":[71.0202025015365876,10.0510841141786607,2.16890759569567715],"rgb":[0.733333333333333282,0.66666666666666663,0.66666666666666663],"xyz":[0.421220820487197167,0.422168962400733649,0.439612578811183263],"hpluv":[12.177050630064155,18.3718697222702261,71.0202025015365876],"hsluv":[12.177050630064155,12.5020210815887047,71.0202025015365876]},"#bbaabb":{"lch":[71.4886774714552615,14.2047670368859897,307.715012949256788],"luv":[71.4886774714552615,8.68954378602241562,-11.236869464535129],"rgb":[0.733333333333333282,0.66666666666666663,0.733333333333333282],"xyz":[0.438358412594533842,0.429023999243668408,0.529870563909825],"hpluv":[307.715012949256788,25.2136766683934965,71.4886774714552615],"hsluv":[307.715012949256788,14.1682246563909,71.4886774714552615]},"#bbaacc":{"lch":[72.010122844957138,26.1519063744379174,286.174295641089373],"luv":[72.010122844957138,7.28488198445553525,-25.1167812724863673],"rgb":[0.733333333333333282,0.66666666666666663,0.8],"xyz":[0.45765078803825554,0.43674094942115721,0.631477074580095166],"hpluv":[286.174295641089373,46.0838895939184923,72.010122844957138],"hsluv":[286.174295641089373,33.6938059680335442,72.010122844957138]},"#bbaadd":{"lch":[72.5845361735228494,39.7272427931479,278.476565574149959],"luv":[72.5845361735228494,5.85598959517198825,-39.2932717625671799],"rgb":[0.733333333333333282,0.66666666666666663,0.866666666666666696],"xyz":[0.47916911358888914,0.445348279641410716,0.744806922480101163],"hpluv":[278.476565574149959,69.451822258827633,72.5845361735228494],"hsluv":[278.476565574149959,54.5084651382981775,72.5845361735228494]},"#bbaaee":{"lch":[73.2116196006959825,53.7916684525604,274.71268656160521],"luv":[73.2116196006959825,4.41947960396952144,-53.6098106221266093],"rgb":[0.733333333333333282,0.66666666666666663,0.933333333333333348],"xyz":[0.502981293855063849,0.454873151747880733,0.870217738548624387],"hpluv":[274.71268656160521,93.2340021292866084,73.2116196006959825],"hsluv":[274.71268656160521,76.5987468488048506,73.2116196006959825]},"#bbaaff":{"lch":[73.8908057188696574,67.9996555049746121,272.519622378571285],"luv":[73.8908057188696574,2.98936916429642707,-67.9339150998584671],"rgb":[0.733333333333333282,0.66666666666666663,1],"xyz":[0.52915234226489527,0.465341571111813457,1.00805192684040623],"hpluv":[272.519622378571285,116.776549017196231,73.8908057188696574],"hsluv":[272.519622378571285,99.9999999999974847,73.8908057188696574]},"#99bb00":{"lch":[71.0859361318702696,82.3913749493211327,101.26222245755217],"luv":[71.0859361318702696,-16.0909976916487061,80.8048170552163185],"rgb":[0.6,0.733333333333333282,0],"xyz":[0.309061217191489157,0.423126383737875533,0.0653895889393331653],"hpluv":[101.26222245755217,147.074503152999483,71.0859361318702696],"hsluv":[101.26222245755217,100.000000000002302,71.0859361318702696]},"#99bb11":{"lch":[71.1136894680978457,81.2167121813616291,101.442926834262664],"luv":[71.1136894680978457,-16.1127230849120338,79.6023523040561685],"rgb":[0.6,0.733333333333333282,0.0666666666666666657],"xyz":[0.310072882691126261,0.423531049937730386,0.0707176939040888],"hpluv":[101.442926834262664,144.921066000062638,71.1136894680978457],"hsluv":[101.442926834262664,98.4331733262411,71.1136894680978457]},"#99bb22":{"lch":[71.1650900316793837,79.0601549481488917,101.789083890819583],"luv":[71.1650900316793837,-16.1527448632600859,77.392486287802754],"rgb":[0.6,0.733333333333333282,0.133333333333333331],"xyz":[0.311948240829603318,0.424281193193121187,0.080594580100068],"hpluv":[101.789083890819583,140.971066242853169,71.1650900316793837],"hsluv":[101.789083890819583,95.5563304227746357,71.1650900316793837]},"#99bb33":{"lch":[71.2495884989653,75.5680342451554168,102.392870056849247],"luv":[71.2495884989653,-16.2179420391938294,73.807222923575253],"rgb":[0.6,0.733333333333333282,0.2],"xyz":[0.315035991562061,0.425516293486104313,0.0968567339576791309],"hpluv":[102.392870056849247,134.584514176993849,71.2495884989653],"hsluv":[102.392870056849247,90.8963478676004826,71.2495884989653]},"#99bb44":{"lch":[71.3712967033779648,70.652786516275043,103.347443045401377],"luv":[71.3712967033779648,-16.3105834167977157,68.7443169368786471],"rgb":[0.6,0.733333333333333282,0.266666666666666663],"xyz":[0.319493986806279939,0.427299491583791879,0.120335508910565769],"hpluv":[103.347443045401377,125.616021445862458,71.3712967033779648],"hsluv":[103.347443045401377,84.331672265085615,71.3712967033779648]},"#99bb55":{"lch":[71.5335490617920442,64.3081830776187502,104.804237401434776],"luv":[71.5335490617920442,-16.4318507493525949,62.1734404042074189],"rgb":[0.6,0.733333333333333282,0.333333333333333315],"xyz":[0.325456400845641924,0.42968445719953674,0.151737556184539685],"hpluv":[104.804237401434776,114.076396323867073,71.5335490617920442],"hsluv":[104.804237401434776,75.8403293762878263,71.5335490617920442]},"#99bb66":{"lch":[71.7390905918245494,56.6109161874071347,107.032342660002968],"luv":[71.7390905918245494,-16.5819871692753225,54.1279367156704367],"rgb":[0.6,0.733333333333333282,0.4],"xyz":[0.33304139661915011,0.432718455508940059,0.191685200591683647],"hpluv":[107.032342660002968,100.134479122606095,71.7390905918245494],"hsluv":[107.032342660002968,65.4891515707011,71.7390905918245494]},"#99bb77":{"lch":[71.9901757540345102,47.73532562127712,110.555323727161408],"luv":[71.9901757540345102,-16.7604289857032249,44.6961892378372099],"rgb":[0.6,0.733333333333333282,0.466666666666666674],"xyz":[0.342355409639352,0.436444060717020854,0.240739002498081556],"hpluv":[110.555323727161408,84.1406731320706,71.9901757540345102],"hsluv":[110.555323727161408,53.4218452589237,71.9901757540345102]},"#99bb88":{"lch":[72.2886271035685581,38.007890289968195,116.511646356383693],"luv":[72.2886271035685581,-16.9659512259030869,34.0111191126451473],"rgb":[0.6,0.733333333333333282,0.533333333333333326],"xyz":[0.353495826741295815,0.440900227557798452,0.299411865901653695],"hpluv":[116.511646356383693,66.7180145269523592,72.2886271035685581],"hsluv":[116.511646356383693,39.8440619041218724,72.2886271035685581]},"#99bb99":{"lch":[72.6358740128595315,28.1115962970155238,127.715012949234961],"luv":[72.6358740128595315,-17.1968288028560856,22.2380512970816788],"rgb":[0.6,0.733333333333333282,0.6],"xyz":[0.366552790850368515,0.44612301320142761,0.36817854354277163],"hpluv":[127.715012949234961,49.1104221429672094,72.6358740128595315],"hsluv":[127.715012949234961,25.0059581073328268,72.6358740128595315]},"#99bbaa":{"lch":[73.0329812495468929,19.8989345424194468,151.280397210880039],"luv":[73.0329812495468929,-17.4510036711552878,9.56190706882358654],"rgb":[0.6,0.733333333333333282,0.66666666666666663],"xyz":[0.381610483815621071,0.452146090387528732,0.447482393159770231],"hpluv":[151.280397210880039,34.5740392557976648,73.0329812495468929],"hsluv":[151.280397210880039,28.0327457551748473,73.0329812495468929]},"#99bbbb":{"lch":[73.4806726048520602,18.1342571597367979,192.177050630060279],"luv":[73.4806726048520602,-17.7262447217336288,-3.82511840348453136],"rgb":[0.6,0.733333333333333282,0.733333333333333282],"xyz":[0.398748075922957745,0.45900112723046349,0.537740378258412],"hpluv":[192.177050630060279,31.3159775944509384,73.4806726048520602],"hsluv":[192.177050630060279,31.1933976709334857,73.4806726048520602]},"#99bbcc":{"lch":[73.9793524714423,25.2831678504957686,224.541830016242],"luv":[73.9793524714423,-18.0202882726228886,-17.734367401402082],"rgb":[0.6,0.733333333333333282,0.8],"xyz":[0.418040451366679444,0.466718077407952292,0.639346888928682189],"hpluv":[224.541830016242,43.3670907410057183,73.9793524714423],"hsluv":[224.541830016242,34.4349286550277398,73.9793524714423]},"#99bbdd":{"lch":[74.5291269946933284,36.8692317824205347,240.185846709470951],"luv":[74.5291269946933284,-18.3309507682094441,-31.9893184697537762],"rgb":[0.6,0.733333333333333282,0.866666666666666696],"xyz":[0.439558776917313043,0.475325407628205798,0.752676736828688187],"hpluv":[240.185846709470951,62.7736499155611796,74.5291269946933284],"hsluv":[240.185846709470951,50.9371920612126914,74.5291269946933284]},"#99bbee":{"lch":[75.129825653719962,50.0395173115419851,248.109771752659725],"luv":[75.129825653719962,-18.6562099892881648,-46.4316607672792],"rgb":[0.6,0.733333333333333282,0.933333333333333348],"xyz":[0.463370957183487753,0.484850279734675815,0.87808755289721141],"hpluv":[248.109771752659725,84.5162185097210568,75.129825653719962],"hsluv":[248.109771752659725,74.708817528734329,75.129825653719962]},"#99bbff":{"lch":[75.7810236401202104,63.8171103470632701,252.684342225014],"luv":[75.7810236401202104,-18.9942553989637197,-60.9248868270445527],"rgb":[0.6,0.733333333333333282,1],"xyz":[0.489542005593319174,0.495318699098608539,1.01592174118899314],"hpluv":[252.684342225014,106.860202909060845,75.7810236401202104],"hsluv":[252.684342225014,99.9999999999971,75.7810236401202104]},"#443300":{"lch":[22.2907133772276609,26.4379209369795269,61.2454831359909],"luv":[22.2907133772276609,12.7181702882918319,23.1778300966244757],"rgb":[0.266666666666666663,0.2,0],"xyz":[0.0356761736431134499,0.0359671813792181508,0.00506334165336921362],"hpluv":[61.2454831359909,150.502134175174433,22.2907133772276609],"hsluv":[61.2454831359909,100.000000000002217,22.2907133772276609]},"#443311":{"lch":[22.433780901835803,22.5495741902090607,57.6291729330006959],"luv":[22.433780901835803,12.072970412625418,19.0453847841311372],"rgb":[0.266666666666666663,0.2,0.0666666666666666657],"xyz":[0.0366878391427505751,0.0363718475790730036,0.0103914466181248451],"hpluv":[57.6291729330006959,127.548453681164943,22.433780901835803],"hsluv":[57.6291729330006959,82.4396262904162853,22.433780901835803]},"#443322":{"lch":[22.6962080128251955,16.3034653251506185,47.6268315603120129],"luv":[22.6962080128251955,10.9878263584328284,12.044527949459761],"rgb":[0.266666666666666663,0.2,0.133333333333333331],"xyz":[0.0385631972812275903,0.037121990834463825,0.0202683328141040411],"hpluv":[47.6268315603120129,91.1519465603444,22.6962080128251955],"hsluv":[47.6268315603120129,53.1527363908354289,22.6962080128251955]},"#443333":{"lch":[23.1206934094119845,9.67437860897999613,12.1770506300626202],"luv":[23.1206934094119845,9.4567095438703852,2.04064844418642899],"rgb":[0.266666666666666663,0.2,0.2],"xyz":[0.0416509480136853308,0.0383570911274469378,0.0365304866717151844],"hpluv":[12.1770506300626202,53.0959690287213917,23.1206934094119845],"hsluv":[12.1770506300626202,12.4420312875371923,23.1206934094119845]},"#443344":{"lch":[23.7177668131648574,12.5269391023357528,307.715012949247694],"luv":[23.7177668131648574,7.66315882209806354,-9.90960141180911],"rgb":[0.266666666666666663,0.2,0.266666666666666663],"xyz":[0.0461089432579042113,0.0401402892251345109,0.0600092616246018229],"hpluv":[307.715012949247694,67.0209373905010608,23.7177668131648574],"hsluv":[307.715012949247694,23.1872031280306743,23.7177668131648574]},"#443355":{"lch":[24.4893027034144382,23.4497607107203301,284.299245815683662],"luv":[24.4893027034144382,5.79176863833153277,-22.7232632654309157],"rgb":[0.266666666666666663,0.2,0.333333333333333315],"xyz":[0.0520713572972662,0.0425252548408793438,0.0914113088985757383],"hpluv":[284.299245815683662,121.507006770462795,24.4893027034144382],"hsluv":[284.299245815683662,34.0172562824217479,24.4893027034144382]},"#443366":{"lch":[25.4301832846655458,35.8361728283181407,276.366541048647719],"luv":[25.4301832846655458,3.97382245046802396,-35.6151655634680964],"rgb":[0.266666666666666663,0.2,0.4],"xyz":[0.0596563530707743817,0.0455592531502826553,0.1313589533057197],"hpluv":[276.366541048647719,178.818092823782393,25.4301832846655458],"hsluv":[276.366541048647719,44.0521665839457555,25.4301832846655458]},"#443377":{"lch":[26.5300434901181958,48.2102429207408818,272.708376965990851],"luv":[26.5300434901181958,2.27805419202829862,-48.1563909733176416],"rgb":[0.266666666666666663,0.2,0.466666666666666674],"xyz":[0.0689703660909762872,0.0492848583583634717,0.180412755212117609],"hpluv":[272.708376965990851,230.590114205629249,26.5300434901181958],"hsluv":[272.708376965990851,52.8563285469964583,26.5300434901181958]},"#443388":{"lch":[27.7750487339787355,60.1896827108213373,270.691543734184165],"luv":[27.7750487339787355,0.726454682878815761,-60.1852986070773568],"rgb":[0.266666666666666663,0.2,0.533333333333333326],"xyz":[0.0801107831929201153,0.0537410251991410626,0.239085618615689777],"hpluv":[270.691543734184165,274.983446475144433,27.7750487339787355],"hsluv":[270.691543734184165,60.324174233719404,27.7750487339787355]},"#443399":{"lch":[29.1495234429961272,71.6961686956082218,269.452076389218803],"luv":[29.1495234429961272,-0.685625105343165342,-71.6928903298230438],"rgb":[0.266666666666666663,0.2,0.6],"xyz":[0.0931677473019928426,0.058963810842770227,0.307852296256807656],"hpluv":[269.452076389218803,312.107220431461315,29.1495234429961272],"hsluv":[269.452076389218803,66.5368599437509,29.1495234429961272]},"#4433aa":{"lch":[30.6372824460415245,82.7612763398458924,268.632918119842316],"luv":[30.6372824460415245,-1.97450330946598829,-82.7377193188284821],"rgb":[0.266666666666666663,0.2,0.66666666666666663],"xyz":[0.108225440267245371,0.0649868880288713285,0.387156145873806257],"hpluv":[268.632918119842316,342.78062465137026,30.6372824460415245],"hsluv":[268.632918119842316,71.6553387322885698,30.6372824460415245]},"#4433bb":{"lch":[32.2226022397772525,93.4505902198726375,268.062492493372758],"luv":[32.2226022397772525,-3.15951219941267691,-93.3971642776391633],"rgb":[0.266666666666666663,0.2,0.733333333333333282],"xyz":[0.125363032374582017,0.0718419248718060871,0.477414130972448],"hpluv":[268.062492493372758,368.010970109266054,32.2226022397772525],"hsluv":[268.062492493372758,75.8581190135042789,32.2226022397772525]},"#4433cc":{"lch":[33.8908458580626331,103.832026214070311,267.649236367220567],"luv":[33.8908458580626331,-4.25888397543315911,-103.744646006447894],"rgb":[0.266666666666666663,0.2,0.8],"xyz":[0.144655407818303772,0.0795588750492948887,0.579020641642718159],"hpluv":[267.649236367220567,388.765974213008576,33.8908458580626331],"hsluv":[267.649236367220567,79.3114034284002,33.8908458580626331]},"#4433dd":{"lch":[35.628800942302739,113.96424557581804,267.340372831489958],"luv":[35.628800942302739,-5.28823530427115518,-113.841485571087048],"rgb":[0.266666666666666663,0.2,0.866666666666666696],"xyz":[0.166173733368937315,0.0881662052695484227,0.692350489542724157],"hpluv":[267.340372831489958,405.888493424646128,35.628800942302739],"hsluv":[267.340372831489958,85.5677988674314,35.628800942302739]},"#4433ee":{"lch":[37.4248062251042484,123.894025620863303,267.103630337901393],"luv":[37.4248062251042484,-6.26032296204841732,-123.73575853791813],"rgb":[0.266666666666666663,0.2,0.933333333333333348],"xyz":[0.189985913635112053,0.0976910773760184536,0.81776130561124738],"hpluv":[267.103630337901393,420.078186698807599,37.4248062251042484],"hsluv":[267.103630337901393,92.6566888343209,37.4248062251042484]},"#4433ff":{"lch":[39.2687372084732473,133.657198385904053,266.918330051954797],"luv":[39.2687372084732473,-7.18532525912719411,-133.4639193988003],"rgb":[0.266666666666666663,0.2,1],"xyz":[0.216156962044943446,0.10815949673995115,0.955595493903029225],"hpluv":[266.918330051954797,431.901531941155895,39.2687372084732473],"hsluv":[266.918330051954797,99.99999999999946,39.2687372084732473]},"#bbbb00":{"lch":[73.6141498101152223,81.1522849996882485,85.8743202181747591],"luv":[73.6141498101152223,5.83845950082822274,80.9419900380996],"rgb":[0.733333333333333282,0.733333333333333282,0],"xyz":[0.382626051771664,0.461058251568279,0.0688379405602788],"hpluv":[85.8743202181747591,139.887458074797564,73.6141498101152223],"hsluv":[85.8743202181747591,100.000000000002331,73.6141498101152223]},"#bbbb11":{"lch":[73.6403599567658205,80.0195247391518478,85.8743202181747449],"luv":[73.6403599567658205,5.75696364516240155,79.8121651696532695],"rgb":[0.733333333333333282,0.733333333333333282,0.0666666666666666657],"xyz":[0.383637717271301082,0.461462917768133862,0.0741660455250344325],"hpluv":[85.8743202181747449,137.885751829634614,73.6403599567658205],"hsluv":[85.8743202181747449,98.5690595334933732,73.6403599567658205]},"#bbbb22":{"lch":[73.6889060807276763,77.9361940700347873,85.8743202181746597],"luv":[73.6889060807276763,5.60707948923862176,77.7342331648256817],"rgb":[0.733333333333333282,0.733333333333333282,0.133333333333333331],"xyz":[0.385513075409778139,0.462213061023524663,0.0840429317210136251],"hpluv":[85.8743202181746597,134.207383902194948,73.6889060807276763],"hsluv":[85.8743202181746597,95.9395400768792541,73.6889060807276763]},"#bbbb33":{"lch":[73.768722281637082,74.5519121144895536,85.8743202181745318],"luv":[73.768722281637082,5.36359906059884217,74.3587211095223],"rgb":[0.733333333333333282,0.733333333333333282,0.2],"xyz":[0.388600826142235845,0.46344816131650779,0.100305085578624775],"hpluv":[85.8743202181745318,128.24069174643796,73.768722281637082],"hsluv":[85.8743202181745318,91.6741883163470419,73.768722281637082]},"#bbbb44":{"lch":[73.8837085661944144,69.7637661309282464,85.8743202181743328],"luv":[73.8837085661944144,5.01911835485944824,69.5829829463408629],"rgb":[0.733333333333333282,0.733333333333333282,0.266666666666666663],"xyz":[0.39305882138645476,0.465231359414195356,0.123783860531511414],"hpluv":[85.8743202181743328,119.817583791868643,73.8837085661944144],"hsluv":[85.8743202181743328,85.652842249664161,73.8837085661944144]},"#bbbb55":{"lch":[74.0370403615741,63.5337415760462747,85.8743202181740628],"luv":[74.0370403615741,4.57090243520957262,63.3691026414263376],"rgb":[0.733333333333333282,0.733333333333333282,0.333333333333333315],"xyz":[0.399021235425816745,0.467616325029940216,0.155185907805485301],"hpluv":[85.8743202181740628,108.891682763750694,74.0370403615741],"hsluv":[85.8743202181740628,77.8423486010655239,74.0370403615741]},"#bbbb66":{"lch":[74.2313474843288361,55.8815023675101799,85.8743202181735512],"luv":[74.2313474843288361,4.02036601211528843,55.7366931561128212],"rgb":[0.733333333333333282,0.733333333333333282,0.4],"xyz":[0.40660623119932493,0.470650323339343535,0.195133552212629291],"hpluv":[85.8743202181735512,95.5256619678334857,74.2313474843288361],"hsluv":[85.8743202181735512,68.2875100330713138,74.2313474843288361]},"#bbbb77":{"lch":[74.468808451125966,46.8772880877030289,85.8743202181728549],"luv":[74.468808451125966,3.37256243628739805,46.7558120565865849],"rgb":[0.733333333333333282,0.733333333333333282,0.466666666666666674],"xyz":[0.415920244219526836,0.47437592854742433,0.2441873541190272],"hpluv":[85.8743202181728549,79.8780401793102328,74.468808451125966],"hsluv":[85.8743202181728549,57.1016453359253688,74.468808451125966]},"#bbbb88":{"lch":[74.7512063572608128,36.6333476151433146,85.874320218171647],"luv":[74.7512063572608128,2.63556739569020726,36.5384173438683746],"rgb":[0.733333333333333282,0.733333333333333282,0.533333333333333326],"xyz":[0.427060661321470636,0.478832095388201928,0.30286021752259934],"hpluv":[85.874320218171647,62.1867310089120195,74.7512063572608128],"hsluv":[85.874320218171647,44.4548295213588744,74.7512063572608128]},"#bbbb99":{"lch":[75.079965438194165,25.2938928616919938,85.8743202181691316],"luv":[75.079965438194165,1.81975614231989979,25.2283472245258693],"rgb":[0.733333333333333282,0.733333333333333282,0.6],"xyz":[0.440117625430543336,0.484054881031831086,0.371626895163717275],"hpluv":[85.8743202181691316,42.7494899193068392,75.079965438194165],"hsluv":[85.8743202181691316,30.559916169503893,75.079965438194165]},"#bbbbaa":{"lch":[75.4561775549407372,13.0242335847304886,85.8743202181613583],"luv":[75.4561775549407372,0.937021801842234714,12.9904830784884187],"rgb":[0.733333333333333282,0.733333333333333282,0.66666666666666663],"xyz":[0.455175318395795891,0.490077958217932208,0.450930744780715875],"hpluv":[85.8743202181613583,21.9026519543336242,75.4561775549407372],"hsluv":[85.8743202181613583,15.6573378741524305,75.4561775549407372]},"#bbbbbb":{"lch":[75.8806235332097856,3.97454725928322e-12,0],"luv":[75.8806235332097856,3.75098259432623098e-12,1.31421287976393485e-12],"rgb":[0.733333333333333282,0.733333333333333282,0.733333333333333282],"xyz":[0.472312910503132566,0.496932995060866967,0.541188729879357622],"hpluv":[0,6.64654731741433278e-12,75.8806235332097856],"hsluv":[0,6.51507609526145538e-12,75.8806235332097856]},"#bbbbcc":{"lch":[76.3537921403793,13.6026726964261613,265.874320218192793],"luv":[76.3537921403793,-0.97863730689855577,-13.5674232449512715],"rgb":[0.733333333333333282,0.733333333333333282,0.8],"xyz":[0.491605285946854265,0.504649945238355713,0.642795240549627778],"hpluv":[265.874320218192793,23.0577392955455913,76.3537921403793],"hsluv":[265.874320218192793,22.3559583930985184,76.3537921403793]},"#bbbbdd":{"lch":[76.875898300454,27.6153317552162676,265.874320218184891],"luv":[76.875898300454,-1.98677087225565296,-27.543770429115412],"rgb":[0.733333333333333282,0.733333333333333282,0.866666666666666696],"xyz":[0.513123611497487864,0.51325727545860933,0.756125088449633775],"hpluv":[265.874320218184891,48.094692651754464,76.875898300454],"hsluv":[265.874320218184891,46.4508399898830717,76.875898300454]},"#bbbbee":{"lch":[77.4469014383288794,41.8833893600305487,265.874320218182334],"luv":[77.4469014383288794,-3.01327895494808,-41.7748543291725554],"rgb":[0.733333333333333282,0.733333333333333282,0.933333333333333348],"xyz":[0.536935791763662573,0.522782147565079347,0.881535904518157],"hpluv":[265.874320218182334,75.1781465494946,77.4469014383288794],"hsluv":[265.874320218182334,72.306149300046286,77.4469014383288794]},"#bbbbff":{"lch":[78.0665243938900915,56.270213901735211,265.874320218181083],"luv":[78.0665243938900915,-4.04833166396953814,-56.1243973979724444],"rgb":[0.733333333333333282,0.733333333333333282,1],"xyz":[0.563106840173494,0.533250566929012,1.01937009280993873],"hpluv":[265.874320218181083,104.437018855576454,78.0665243938900915],"hsluv":[265.874320218181083,99.9999999999968,78.0665243938900915]},"#99cc00":{"lch":[76.0430979526319,91.0941172293808,106.263360497649074],"luv":[76.0430979526319,-25.5111694560196547,87.4489475453331124],"rgb":[0.6,0.8,0],"xyz":[0.347284960501106077,0.499573870357110428,0.0781308367092051204],"hpluv":[106.263360497649074,152.00919412554731,76.0430979526319],"hsluv":[106.263360497649074,100.000000000002444,76.0430979526319]},"#99cc11":{"lch":[76.0679435797449202,90.0431717383104342,106.457693210299354],"luv":[76.0679435797449202,-25.5098862277023812,86.3540299079582496],"rgb":[0.6,0.8,0.0666666666666666657],"xyz":[0.348296626000743181,0.499978536556965281,0.083458941673960757],"hpluv":[106.457693210299354,150.416675371578,76.0679435797449202],"hsluv":[106.457693210299354,98.6698238814781377,76.0679435797449202]},"#99cc22":{"lch":[76.1139653123302224,88.1120975577654235,106.827460928226145],"luv":[76.1139653123302224,-25.5076232207001254,84.3392132620406301],"rgb":[0.6,0.8,0.133333333333333331],"xyz":[0.350171984139220238,0.500728679812356137,0.0933358278699399496],"hpluv":[106.827460928226145,147.536178080277807,76.1139653123302224],"hsluv":[106.827460928226145,96.2239688839219554,76.1139653123302224]},"#99cc33":{"lch":[76.1896394090333615,84.9806694979027668,107.464683868975555],"luv":[76.1896394090333615,-25.5042190273125513,81.0632407452271195],"rgb":[0.6,0.8,0.2],"xyz":[0.353259734871677944,0.501963780105339263,0.109597981727551086],"hpluv":[107.464683868975555,142.843382477451314,76.1896394090333615],"hsluv":[107.464683868975555,92.2523981769505497,76.1896394090333615]},"#99cc44":{"lch":[76.2986765643697566,80.5641186971074461,108.452476349375274],"luv":[76.2986765643697566,-25.4999909675489818,76.4220366262018445],"rgb":[0.6,0.8,0.266666666666666663],"xyz":[0.357717730115896859,0.503746978203026829,0.133076756680437724],"hpluv":[108.452476349375274,136.177549938509202,76.2986765643697566],"hsluv":[108.452476349375274,86.6370393323296,76.2986765643697566]},"#99cc55":{"lch":[76.4441084930992645,74.8483308647658276,109.915235611542258],"luv":[76.4441084930992645,-25.4955548836031696,70.3722197633315858],"rgb":[0.6,0.8,0.333333333333333315],"xyz":[0.363680144155258844,0.506131943818771579,0.16447880395441164],"hpluv":[109.915235611542258,127.465568679298812,76.4441084930992645],"hsluv":[109.915235611542258,79.3378797119037245,76.4441084930992645]},"#99cc66":{"lch":[76.6284587708723279,67.8919791104198111,112.053749389120497],"luv":[76.6284587708723279,-25.4918238993559072,62.9244606001029396],"rgb":[0.6,0.8,0.4],"xyz":[0.37126513992876703,0.509165942128174898,0.204426448361555602],"hpluv":[112.053749389120497,116.726185086844026,76.6284587708723279],"hsluv":[112.053749389120497,70.3850130172815796,76.6284587708723279]},"#99cc77":{"lch":[76.8538330837355801,59.8379910057359723,115.212918879407354],"luv":[76.8538330837355801,-25.4899847789994141,54.1372869986012262],"rgb":[0.6,0.8,0.466666666666666674],"xyz":[0.380579152948968935,0.512891547336255749,0.253480250267953511],"hpluv":[115.212918879407354,104.093311342856381,76.8538330837355801],"hsluv":[115.212918879407354,59.8707914454029577,76.8538330837355801]},"#99cc88":{"lch":[77.1219726780439885,50.9458531819172649,120.024060615406185],"luv":[77.1219726780439885,-25.4914521322680621,44.1097021597488919],"rgb":[0.6,0.8,0.533333333333333326],"xyz":[0.391719570050912735,0.517347714177033291,0.31215311367152565],"hpluv":[120.024060615406185,89.8814395273866324,77.1219726780439885],"hsluv":[120.024060615406185,47.9401368886289845,77.1219726780439885]},"#99cc99":{"lch":[77.4342891130262103,41.681173098632776,127.715012949236964],"luv":[77.4342891130262103,-25.4978049096247332,32.9724450969124447],"rgb":[0.6,0.8,0.6],"xyz":[0.40477653415998549,0.522570499820662504,0.380919791312643585],"hpluv":[127.715012949236964,74.7648437658604337,77.4342891130262103],"hsluv":[127.715012949236964,34.7788947556027495,77.4342891130262103]},"#99ccaa":{"lch":[77.7918890721377352,32.9651751214879525,140.702563314804109],"luv":[77.7918890721377352,-25.5107121176450882,20.8783701002018844],"rgb":[0.6,0.8,0.66666666666666663],"xyz":[0.419834227125238,0.528593577006763571,0.460223640929642186],"hpluv":[140.702563314804109,60.2770963674260756,77.7918890721377352],"hsluv":[140.702563314804109,37.0803100068772622,77.7918890721377352]},"#99ccbb":{"lch":[78.1955939192693421,26.7536671513630395,162.617393192268167],"luv":[78.1955939192693421,-25.5318556358660231,7.9926875226808507],"rgb":[0.6,0.8,0.733333333333333282],"xyz":[0.436971819232574665,0.535448613849698329,0.550481626028283877],"hpluv":[162.617393192268167,50.006554278151107,78.1955939192693421],"hsluv":[162.617393192268167,39.5096284608221353,78.1955939192693421]},"#99cccc":{"lch":[78.6459566685868481,26.1512486118356264,192.177050630060364],"luv":[78.6459566685868481,-25.562857556775878,-5.51616873291790277],"rgb":[0.6,0.8,0.8],"xyz":[0.45626419467629642,0.543165564027187187,0.652088136698554],"hpluv":[192.177050630060364,50.1138147500145,78.6459566685868481],"hsluv":[192.177050630060364,42.0292910605185952,78.6459566685868481]},"#99ccdd":{"lch":[79.1432779300782,32.1756084020034763,217.269502822152816],"luv":[79.1432779300782,-25.6052179328205156,-19.4844191766612091],"rgb":[0.6,0.8,0.866666666666666696],"xyz":[0.477782520226929908,0.551772894247440693,0.76541798459856],"hpluv":[217.269502822152816,63.4104034428488532,79.1432779300782],"hsluv":[217.269502822152816,44.6030324020319142,79.1432779300782]},"#99ccee":{"lch":[79.6876217339600146,42.4043636674930298,232.761609201673764],"luv":[79.6876217339600146,-25.6602666815912279,-33.7591583407321],"rgb":[0.6,0.8,0.933333333333333348],"xyz":[0.501594700493104728,0.56129776635391071,0.890828800667083254],"hpluv":[232.761609201673764,86.2263034184575901,79.6876217339600146],"hsluv":[232.761609201673764,69.2463215394111842,79.6876217339600146]},"#99ccff":{"lch":[80.278831719152322,54.6396736698167231,241.908088190648726],"luv":[80.278831719152322,-25.7291311718118969,-48.2027566419988105],"rgb":[0.6,0.8,1],"xyz":[0.527765748902936,0.571766185717843434,1.02866298895886521],"hpluv":[241.908088190648726,115.039816302159181,80.278831719152322],"hsluv":[241.908088190648726,99.9999999999963762,80.278831719152322]},"#444400":{"lch":[27.7455139749470092,30.5866720374503593,85.8743202181747307],"luv":[27.7455139749470092,2.20054242411605072,30.5074108925390952],"rgb":[0.266666666666666663,0.266666666666666663,0],"xyz":[0.044508744126079483,0.0536323223451504599,0.00800753181435780864],"hpluv":[85.8743202181747307,139.887458074797593,27.7455139749470092],"hsluv":[85.8743202181747307,100.000000000002331,27.7455139749470092]},"#444411":{"lch":[27.8552611903384602,27.0161424908788135,85.8743202181744],"luv":[27.8552611903384602,1.9436625081132386,26.9461338811715763],"rgb":[0.266666666666666663,0.266666666666666663,0.0666666666666666657],"xyz":[0.0455204096257166,0.0540369885450053128,0.0133356367791134401],"hpluv":[85.8743202181744,123.070915058641674,27.8552611903384602],"hsluv":[85.8743202181744,87.9785198418851451,27.8552611903384602]},"#444422":{"lch":[28.0572627170229296,20.802612285424587,85.8743202181735086],"luv":[28.0572627170229296,1.49663326596887214,20.7487051828516122],"rgb":[0.266666666666666663,0.266666666666666663,0.133333333333333331],"xyz":[0.0473957677641936234,0.0547871318003961341,0.0232125229750926379],"hpluv":[85.8743202181735086,94.0831614915658463,28.0572627170229296],"hsluv":[85.8743202181735086,67.2563236092702539,28.0572627170229296]},"#444433":{"lch":[28.3858756417530103,11.5666907278610811,85.8743202181704],"luv":[28.3858756417530103,0.832159628943940688,11.5367172430437677],"rgb":[0.266666666666666663,0.266666666666666663,0.2],"xyz":[0.0504835184966513639,0.056022232093379247,0.0394746768327037811],"hpluv":[85.8743202181704,51.7066205750809758,28.3858756417530103],"hsluv":[85.8743202181704,36.9630139018145201,28.3858756417530103]},"#444444":{"lch":[28.8519023983998864,1.56211738287899238e-12,0],"luv":[28.8519023983998864,1.45745810878583046e-12,5.6216241338882039e-13],"rgb":[0.266666666666666663,0.266666666666666663,0.266666666666666663],"xyz":[0.0549415137408702445,0.05780543019106682,0.0629534517855904197],"hpluv":[0,6.87034486140541504e-12,28.8519023983998864],"hsluv":[0,1.96712204652458306e-12,28.8519023983998864]},"#444455":{"lch":[29.4604491554767947,12.996237632929807,265.874320218183527],"luv":[29.4604491554767947,-0.935007647451096213,-12.9625596743385874],"rgb":[0.266666666666666663,0.266666666666666663,0.333333333333333315],"xyz":[0.0609039277802322365,0.0601903958068116529,0.094355499059564335],"hpluv":[265.874320218183527,55.9780294653588157,29.4604491554767947],"hsluv":[265.874320218183527,10.903125265393685,29.4604491554767947]},"#444466":{"lch":[30.2117995944983235,26.5936989313503034,265.874320218180401],"luv":[30.2117995944983235,-1.9132700229980284,-26.52478502590359],"rgb":[0.266666666666666663,0.266666666666666663,0.4],"xyz":[0.0684889235537404079,0.0632243941162149714,0.134303143466708297],"hpluv":[265.874320218180401,111.69699235114156,30.2117995944983235],"hsluv":[265.874320218180401,21.7557908165695544,30.2117995944983235]},"#444477":{"lch":[31.1022350000615333,40.188693881548005,265.874320218179378],"luv":[31.1022350000615333,-2.89135495838767076,-40.084550420447286],"rgb":[0.266666666666666663,0.266666666666666663,0.466666666666666674],"xyz":[0.0778029365739423273,0.0669499993242957808,0.183356945373106206],"hpluv":[265.874320218179378,163.965176201048621,31.1022350000615333],"hsluv":[265.874320218179378,31.9363305989270607,31.1022350000615333]},"#444488":{"lch":[32.1249060438116132,53.4239352836437,265.874320218178923],"luv":[32.1249060438116132,-3.84355760936744639,-53.2854945186250859],"rgb":[0.266666666666666663,0.266666666666666663,0.533333333333333326],"xyz":[0.0889433536758861554,0.0714061661650733787,0.242029808776678373],"hpluv":[265.874320218178923,211.024721596932807,32.1249060438116132],"hsluv":[265.874320218178923,41.1023574005893479,32.1249060438116132]},"#444499":{"lch":[33.2707247827276404,66.1374776044503818,265.874320218178639],"luv":[33.2707247827276404,-4.75822688765494473,-65.9660914467787336],"rgb":[0.266666666666666663,0.266666666666666663,0.6],"xyz":[0.102000317784958869,0.0766289518087025362,0.31079648641779628],"hpluv":[265.874320218178639,252.246234683596128,33.2707247827276404],"hsluv":[265.874320218178639,50.2337582903708224,33.2707247827276404]},"#4444aa":{"lch":[34.5292085317775772,78.2936422443982707,265.874320218178468],"luv":[34.5292085317775772,-5.63279591471267516,-78.090755061511743],"rgb":[0.266666666666666663,0.266666666666666663,0.66666666666666663],"xyz":[0.117058010750211411,0.0826520289948036446,0.390100336034794881],"hpluv":[265.874320218178468,287.726060771882089,34.5292085317775772],"hsluv":[265.874320218178468,59.0260968416557645,34.5292085317775772]},"#4444bb":{"lch":[35.8892144652077647,89.9250819913669801,265.874320218178354],"luv":[35.8892144652077647,-6.46961387860876,-89.6920535355044],"rgb":[0.266666666666666663,0.266666666666666663,0.733333333333333282],"xyz":[0.134195602857548058,0.0895070658377384,0.480358321133436628],"hpluv":[265.874320218178354,317.948086985701252,35.8892144652077647],"hsluv":[265.874320218178354,67.4283717547759807,35.8892144652077647]},"#4444cc":{"lch":[37.3395287853000397,101.093816173965237,265.874320218178298],"luv":[37.3395287853000397,-7.27314272811459173,-100.831845482823283],"rgb":[0.266666666666666663,0.266666666666666663,0.8],"xyz":[0.153487978301269812,0.0972240160152272,0.581964831803706728],"hpluv":[265.874320218178298,343.55405942077391,37.3395287853000397],"hsluv":[265.874320218178298,75.5808548987534294,37.3395287853000397]},"#4444dd":{"lch":[38.8693012328948697,111.868746538356049,265.874320218178241],"luv":[38.8693012328948697,-8.04833956400084105,-111.578854100252741],"rgb":[0.266666666666666663,0.266666666666666663,0.866666666666666696],"xyz":[0.175006303851903355,0.105831346235480739,0.695294679703712726],"hpluv":[265.874320218178241,365.208910634554,38.8693012328948697],"hsluv":[265.874320218178241,83.6313726076760702,38.8693012328948697]},"#4444ee":{"lch":[40.4683363226646691,122.314460404417545,265.874320218178127],"luv":[40.4683363226646691,-8.799851087852959,-121.997499338533331],"rgb":[0.266666666666666663,0.266666666666666663,0.933333333333333348],"xyz":[0.198818484118078065,0.115356218341950756,0.820705495772236],"hpluv":[265.874320218178127,383.532154053589807,40.4683363226646691],"hsluv":[265.874320218178127,91.7249319236633625,40.4683363226646691]},"#4444ff":{"lch":[42.1272645151277203,132.4867415013303,265.874320218178127],"luv":[42.1272645151277203,-9.53169063144130568,-132.143420370999962],"rgb":[0.266666666666666663,0.266666666666666663,1],"xyz":[0.224989532527909486,0.12582463770588348,0.958539684064017794],"hpluv":[265.874320218178127,399.069452944254863,42.1272645151277203],"hsluv":[265.874320218178127,99.9999999999994458,42.1272645151277203]},"#bbcc00":{"lch":[78.3160688649495711,87.6272661942945916,93.3039767998847651],"luv":[78.3160688649495711,-5.05025027162958828,87.4816137990130471],"rgb":[0.733333333333333282,0.8,0],"xyz":[0.420849795081280953,0.537505738187513904,0.081579188330150737],"hpluv":[93.3039767998847651,164.876849582678972,78.3160688649495711],"hsluv":[93.3039767998847651,100.000000000002302,78.3160688649495711]},"#bbcc11":{"lch":[78.3397318378619332,86.5943586896397193,93.3754549086192],"luv":[78.3397318378619332,-5.09856582429126703,86.4441298377475249],"rgb":[0.733333333333333282,0.8,0.0666666666666666657],"xyz":[0.421861460580918057,0.537910404387368812,0.0869072932949063737],"hpluv":[93.3754549086192,163.146061131239662,78.3397318378619332],"hsluv":[93.3754549086192,98.7690619278293,78.3397318378619332]},"#bbcc22":{"lch":[78.3835653101130134,84.6929692802742125,93.5116381573829329],"luv":[78.3835653101130134,-5.18755307791811582,84.5339478468458481],"rgb":[0.733333333333333282,0.8,0.133333333333333331],"xyz":[0.423736818719395114,0.538660547642759613,0.0967841794908855663],"hpluv":[93.5116381573829329,159.95035726483485,78.3835653101130134],"hsluv":[93.5116381573829329,96.5043106774720343,78.3835653101130134]},"#bbcc33":{"lch":[78.4556479267243,81.5996211754986405,93.7468972468941644],"luv":[78.4556479267243,-5.33246113691784,81.4251990123951],"rgb":[0.733333333333333282,0.8,0.2],"xyz":[0.42682456945185282,0.53989564793574274,0.113046333348496703],"hpluv":[93.7468972468941644,154.72407311273281,78.4556479267243],"hsluv":[93.7468972468941644,92.8230308779070157,78.4556479267243]},"#bbcc44":{"lch":[78.5595248117047475,77.2136355312914873,94.1131309849175],"luv":[78.5595248117047475,-5.53822791342104281,77.0147618547127877],"rgb":[0.733333333333333282,0.8,0.266666666666666663],"xyz":[0.431282564696071735,0.541678846033430306,0.136525108301383341],"hpluv":[94.1131309849175,147.254264694427633,78.5595248117047475],"hsluv":[94.1131309849175,87.6101015600037556,78.5595248117047475]},"#bbcc55":{"lch":[78.6981007967589079,71.4912273296626921,94.6593076474989488],"luv":[78.6981007967589079,-5.80727962831129307,71.2549723768110823],"rgb":[0.733333333333333282,0.8,0.333333333333333315],"xyz":[0.43724497873543372,0.544063811649175,0.167927155575357256],"hpluv":[94.6593076474989488,137.398731222980217,78.6981007967589079],"hsluv":[94.6593076474989488,80.8199795518833639,78.6981007967589079]},"#bbcc66":{"lch":[78.8738041161037273,64.440755538040392,95.4673459440295176],"luv":[78.8738041161037273,-6.13981465986491681,64.1475927081912403],"rgb":[0.733333333333333282,0.8,0.4],"xyz":[0.444829974508941905,0.547097809958578374,0.207874799982501218],"hpluv":[95.4673459440295176,125.075317361724217,78.8738041161037273],"hsluv":[95.4673459440295176,72.4696955468646848,78.8738041161037273]},"#bbcc77":{"lch":[79.0886730863018244,56.1202023011108153,96.6860819525870454],"luv":[79.0886730863018244,-6.5340457953894715,55.7385266387743386],"rgb":[0.733333333333333282,0.8,0.466666666666666674],"xyz":[0.454143987529143811,0.550823415166659225,0.2569286018888991],"hpluv":[96.6860819525870454,110.256785788709905,79.0886730863018244],"hsluv":[96.6860819525870454,62.6323703341884,79.0886730863018244]},"#bbcc88":{"lch":[79.3444074564468451,46.6379090458556931,98.6154841820407],"luv":[79.3444074564468451,-6.9864776714612713,46.1116437563841473],"rgb":[0.733333333333333282,0.8,0.533333333333333326],"xyz":[0.465284404631087611,0.555279582007436767,0.315601465292471295],"hpluv":[98.6154841820407,92.9740665461038702,79.3444074564468451],"hsluv":[98.6154841820407,51.4293340198482483,79.3444074564468451]},"#bbcc99":{"lch":[79.6424016540563,36.1659853952486898,101.956116252097843],"luv":[79.6424016540563,-7.49223418159530397,35.3814206410296137],"rgb":[0.733333333333333282,0.8,0.6],"xyz":[0.478341368740160311,0.560502367651066,0.38436814293358923],"hpluv":[101.956116252097843,73.3480812445522616,79.6424016540563],"hsluv":[101.956116252097843,39.0205672484538439,79.6424016540563]},"#bbccaa":{"lch":[79.9837682606211899,25.01387761080953,108.762036830266098],"luv":[79.9837682606211899,-8.04542335958215382,23.6847046866463593],"rgb":[0.733333333333333282,0.8,0.66666666666666663],"xyz":[0.493399061705412867,0.566525444837167,0.463671992550587775],"hpluv":[108.762036830266098,51.7527419020047645,79.9837682606211899],"hsluv":[108.762036830266098,25.5939208298632828,79.9837682606211899]},"#bbccbb":{"lch":[80.3693561861161356,14.1229851396422195,127.715012949226079],"luv":[80.3693561861161356,-8.63951499109438892,11.1721748094634776],"rgb":[0.733333333333333282,0.8,0.733333333333333282],"xyz":[0.510536653812749486,0.573380481680101806,0.553929977649229577],"hpluv":[127.715012949226079,29.8960175179438359,80.3693561861161356],"hsluv":[127.715012949226079,11.3539027840963094,80.3693561861161356]},"#bbcccc":{"lch":[80.7997661027856537,9.48102181692548207,192.177050630058517],"luv":[80.7997661027856537,-9.26770319062559622,-1.99986306118322021],"rgb":[0.733333333333333282,0.8,0.8],"xyz":[0.52982902925647124,0.581097431857590663,0.655536488319499733],"hpluv":[192.177050630058517,20.5979746439306091,80.7997661027856537],"hsluv":[192.177050630058517,14.8313634310922779,80.7997661027856537]},"#bbccdd":{"lch":[81.2753646562375138,18.5534915910332536,237.666646406054781],"luv":[81.2753646562375138,-9.9232294288842251,-15.6767843616051454],"rgb":[0.733333333333333282,0.8,0.866666666666666696],"xyz":[0.551347354807104839,0.589704762077844169,0.76886633621950573],"hpluv":[237.666646406054781,41.5059211719903089,81.2753646562375138],"hsluv":[237.666646406054781,34.6395739712995834,81.2753646562375138]},"#bbccee":{"lch":[81.7962983545147466,31.5457627715974915,250.366116177600304],"luv":[81.7962983545147466,-10.5996485000078611,-29.7116576534899401],"rgb":[0.733333333333333282,0.8,0.933333333333333348],"xyz":[0.575159535073279549,0.599229634184314186,0.894277152288029],"hpluv":[250.366116177600304,72.9233806917818725,81.7962983545147466],"hsluv":[250.366116177600304,65.9765826509477478,81.7962983545147466]},"#bbccff":{"lch":[82.3625076456434329,45.3963265868234203,255.598148289110497],"luv":[82.3625076456434329,-11.2910283768039683,-43.9697526234994669],"rgb":[0.733333333333333282,0.8,1],"xyz":[0.601330583483111,0.60969805354824691,1.0321113405798108],"hpluv":[255.598148289110497,108.847942718229262,82.3625076456434329],"hsluv":[255.598148289110497,99.9999999999958789,82.3625076456434329]},"#99dd00":{"lch":[81.0072374435841738,100.100388992767378,110.059278565234735],"luv":[81.0072374435841738,-34.3336498242400623,94.028125400062109],"rgb":[0.6,0.866666666666666696,0],"xyz":[0.389918951048281226,0.584841851451462,0.0923421668915964389],"hpluv":[110.059278565234735,220.251619684458433,81.0072374435841738],"hsluv":[110.059278565234735,100.000000000002245,81.0072374435841738]},"#99dd11":{"lch":[81.0296061686003,99.1554895677318626,110.248463134872608],"luv":[81.0296061686003,-34.3169109383134483,93.0277417498051733],"rgb":[0.6,0.866666666666666696,0.0666666666666666657],"xyz":[0.39093061654791833,0.585246517651316855,0.0976702718563520755],"hpluv":[110.248463134872608,218.472914234601802,81.0296061686003],"hsluv":[110.248463134872608,98.8616036668283,81.0296061686003]},"#99dd22":{"lch":[81.0710445633976,97.4178442494470431,110.606606003803336],"luv":[81.0710445633976,-34.2861684396920552,91.184949591117217],"rgb":[0.6,0.866666666666666696,0.133333333333333331],"xyz":[0.392805974686395387,0.585996660906707656,0.107547158052331268],"hpluv":[110.606606003803336,215.192819254761019,81.0710445633976],"hsluv":[110.606606003803336,96.7659338960775131,81.0710445633976]},"#99dd33":{"lch":[81.1391953168863154,94.5961335984436857,111.218234049095599],"luv":[81.1391953168863154,-34.2363517117206513,88.1833358024404106],"rgb":[0.6,0.866666666666666696,0.2],"xyz":[0.395893725418853093,0.587231761199690783,0.123809311909942404],"hpluv":[111.218234049095599,209.840835623165077,81.1391953168863154],"hsluv":[111.218234049095599,93.3562182204636599,81.1391953168863154]},"#99dd44":{"lch":[81.2374208116197565,90.6080011845065343,112.152709421166279],"luv":[81.2374208116197565,-34.1661449288095653,83.9195115533635487],"rgb":[0.6,0.866666666666666696,0.266666666666666663],"xyz":[0.400351720663072,0.589014959297378349,0.147288086862829043],"hpluv":[112.152709421166279,202.22119953609328,81.2374208116197565],"hsluv":[112.152709421166279,88.5208972681928827,81.2374208116197565]},"#99dd55":{"lch":[81.3684846041416421,85.4315699411036604,113.506988965296216],"luv":[81.3684846041416421,-34.0753153837539244,78.3417259453695607],"rgb":[0.6,0.866666666666666696,0.333333333333333315],"xyz":[0.406314134702434,0.591399924913123098,0.178690134136802958],"hpluv":[113.506988965296216,192.231211336261111,81.3684846041416421],"hsluv":[113.506988965296216,82.2103932307851579,81.3684846041416421]},"#99dd66":{"lch":[81.5347071887187695,79.1067404569191837,115.426438711198742],"luv":[81.5347071887187695,-33.9646313013793,71.4442454385217758],"rgb":[0.6,0.866666666666666696,0.4],"xyz":[0.413899130475942179,0.594433923222526417,0.21863777854394692],"hpluv":[115.426438711198742,179.864586291563711,81.5347071887187695],"hsluv":[115.426438711198742,74.4308834765056,81.5347071887187695]},"#99dd77":{"lch":[81.7380487099571,71.7428264562351217,118.139890255285593],"luv":[81.7380487099571,-33.8357763954940651,63.2627329764024324],"rgb":[0.6,0.866666666666666696,0.466666666666666674],"xyz":[0.423213143496144084,0.598159528430607268,0.267691580450344802],"hpluv":[118.139890255285593,165.232292085670224,81.7380487099571],"hsluv":[118.139890255285593,65.2389156719347,81.7380487099571]},"#99dd88":{"lch":[81.9801580086414248,63.5371271244577898,122.023063704989269],"luv":[81.9801580086414248,-33.6912346765093815,53.8689820694792942],"rgb":[0.6,0.866666666666666696,0.533333333333333326],"xyz":[0.434353560598087884,0.60261569527138481,0.326364443853917],"hpluv":[122.023063704989269,148.614644251947254,81.9801580086414248],"hsluv":[122.023063704989269,54.7350081565161943,81.9801580086414248]},"#99dd99":{"lch":[82.2624042681600827,54.8181455895933,127.715012949238044],"luv":[82.2624042681600827,-33.5341421039979721,43.3646215160552],"rgb":[0.6,0.866666666666666696,0.6],"xyz":[0.447410524707160584,0.607838480915014,0.395131121495034932],"hpluv":[127.715012949238044,130.58293025992694,82.2624042681600827],"hsluv":[127.715012949238044,43.0558433261763724,82.2624042681600827]},"#99ddaa":{"lch":[82.5858991321833855,46.1452119261310898,136.311935434488049],"luv":[82.5858991321833855,-33.3681126370237138,31.8739649675161907],"rgb":[0.6,0.866666666666666696,0.66666666666666663],"xyz":[0.46246821767241314,0.61386155810111509,0.474434971112033477],"hpluv":[136.311935434488049,112.281381223378744,82.5858991321833855],"hsluv":[136.311935434488049,44.8180878493830122,82.5858991321833855]},"#99ddbb":{"lch":[82.9515135213076,38.5190468703316,149.523212457301526],"luv":[82.9515135213076,-33.1970516149390349,19.536446347119437],"rgb":[0.6,0.866666666666666696,0.733333333333333282],"xyz":[0.479605809779749814,0.620716594944049849,0.564692956210675279],"hpluv":[149.523212457301526,96.0401150933983416,82.9515135213076],"hsluv":[149.523212457301526,46.6955526922259807,82.9515135213076]},"#99ddcc":{"lch":[83.3598915829196585,33.6584009809739158,168.866706644517421],"luv":[83.3598915829196585,-33.0249710093605202,6.49917274942921],"rgb":[0.6,0.866666666666666696,0.8],"xyz":[0.498898185223471513,0.628433545121538706,0.666299466880945435],"hpluv":[168.866706644517421,86.2854242091523,83.3598915829196585],"hsluv":[168.866706644517421,48.6618587245334879,83.3598915829196585]},"#99dddd":{"lch":[83.811463234187741,33.6120761253887,192.17705063006062],"luv":[83.811463234187741,-32.85581988586,-7.08990557672323529],"rgb":[0.6,0.866666666666666696,0.866666666666666696],"xyz":[0.520416510774105112,0.637040875341792212,0.779629314780951432],"hpluv":[192.17705063006062,88.9162454401141,83.811463234187741],"hsluv":[192.17705063006062,50.6906605199231777,83.811463234187741]},"#99ddee":{"lch":[84.3064561843391402,38.9043785470910208,212.822778279485817],"luv":[84.3064561843391402,-32.6933403312743565,-21.0878203738277712],"rgb":[0.6,0.866666666666666696,0.933333333333333348],"xyz":[0.544228691040279822,0.646565747448262229,0.905040130849474656],"hpluv":[212.822778279485817,106.615167592423816,84.3064561843391402],"hsluv":[212.822778279485817,60.6575363344623781,84.3064561843391402]},"#99ddff":{"lch":[84.8449079615810575,48.055447414973429,227.378328123916845],"luv":[84.8449079615810575,-32.5409551013358396,-35.3611689193969099],"rgb":[0.6,0.866666666666666696,1],"xyz":[0.570399739450111243,0.657034166812195,1.04287431914125639],"hpluv":[227.378328123916845,137.001856984753886,84.8449079615810575],"hsluv":[227.378328123916845,99.999999999994813,84.8449079615810575]},"#445500":{"lch":[33.4053570608210535,38.7644311760376397,101.469350612776353],"luv":[33.4053570608210535,-7.7080633936099785,37.9903525006263791],"rgb":[0.266666666666666663,0.333333333333333315,0],"xyz":[0.0563220008404254485,0.0772588357738427239,0.0119452840524730177],"hpluv":[101.469350612776353,147.25044771073371,33.4053570608210535],"hsluv":[101.469350612776353,100.000000000002245,33.4053570608210535]},"#445511":{"lch":[33.4914653280992525,35.8039831739898275,102.524785035338],"luv":[33.4914653280992525,-7.76452054412734,34.9519303021045076],"rgb":[0.266666666666666663,0.333333333333333315,0.0666666666666666657],"xyz":[0.0573336663400625668,0.0776635019736975768,0.0172733890172286492],"hpluv":[102.524785035338,135.655223597469387,33.4914653280992525],"hsluv":[102.524785035338,91.5452633494882093,33.4914653280992525]},"#445522":{"lch":[33.6502992474903806,30.5965852313305291,104.897478349629381],"luv":[33.6502992474903806,-7.86608410210478493,29.5681543001366229],"rgb":[0.266666666666666663,0.333333333333333315,0.133333333333333331],"xyz":[0.0592090244785395889,0.0784136452290883912,0.0271502752132078452],"hpluv":[104.897478349629381,115.378092601865731,33.6502992474903806],"hsluv":[104.897478349629381,76.6558497494370243,33.6502992474903806]},"#445533":{"lch":[33.9096245159150911,22.79863905315759,110.61032755328398],"luv":[33.9096245159150911,-8.02535730567797501,21.3394372651287],"rgb":[0.266666666666666663,0.333333333333333315,0.2],"xyz":[0.0622967752109973294,0.0796487455220715,0.0434124290708189919],"hpluv":[110.61032755328398,85.3149751467856419,33.9096245159150911],"hsluv":[110.61032755328398,54.1403397653178331,33.9096245159150911]},"#445544":{"lch":[34.2793424585633204,13.4702363502677187,127.715012949235046],"luv":[34.2793424585633204,-8.24020614134090401,10.6558092175245633],"rgb":[0.266666666666666663,0.333333333333333315,0.266666666666666663],"xyz":[0.0667547704552162,0.081431943619759084,0.0668912040237056305],"hpluv":[127.715012949235046,49.8634197051089814,34.2793424585633204],"hsluv":[127.715012949235046,25.3893680776039865,34.2793424585633204]},"#445555":{"lch":[34.7654846399243738,8.70030094248716424,192.177050630060222],"luv":[34.7654846399243738,-8.50454817645784544,-1.83518304377262664],"rgb":[0.266666666666666663,0.333333333333333315,0.333333333333333315],"xyz":[0.0727171844945782,0.0838169092355039169,0.098293251297679532],"hpluv":[192.177050630060222,31.7559649298661668,34.7654846399243738],"hsluv":[192.177050630060222,31.6316627668381969,34.7654846399243738]},"#445566":{"lch":[35.3707740335649916,17.7582093223154978,240.254504050727519],"luv":[35.3707740335649916,-8.81070452432763318,-15.4183489427423961],"rgb":[0.266666666666666663,0.333333333333333315,0.4],"xyz":[0.0803021802680863733,0.0868509075449072354,0.138240895704823508],"hpluv":[240.254504050727519,63.7079944588343352,35.3707740335649916],"hsluv":[240.254504050727519,38.2083413049732812,35.3707740335649916]},"#445577":{"lch":[36.0950574442792913,30.8488081821149329,252.743594747999822],"luv":[36.0950574442792913,-9.15124765847803623,-29.4602042177260124],"rgb":[0.266666666666666663,0.333333333333333315,0.466666666666666674],"xyz":[0.0896161932882882928,0.0905765127529880448,0.187294697611221417],"hpluv":[252.743594747999822,108.450105614435046,36.0950574442792913],"hsluv":[252.743594747999822,44.7362415879762878,36.0950574442792913]},"#445588":{"lch":[36.935739068143242,44.5159055243500319,257.651563208142],"luv":[36.935739068143242,-9.5200062368872409,-43.4860359874579245],"rgb":[0.266666666666666663,0.333333333333333315,0.533333333333333326],"xyz":[0.100756610390232121,0.0950326795937656427,0.245967561014793584],"hpluv":[257.651563208142,152.935302017774575,36.935739068143242],"hsluv":[257.651563208142,50.9359550606187952,36.935739068143242]},"#445599":{"lch":[37.8882410462664865,58.0440865604997711,260.167284745959819],"luv":[37.8882410462664865,-9.91231220062277885,-57.1914508600732674],"rgb":[0.266666666666666663,0.333333333333333315,0.6],"xyz":[0.113813574499304834,0.1002554652373948,0.314734238655911491],"hpluv":[260.167284745959819,194.398479571090235,37.8882410462664865],"hsluv":[260.167284745959819,56.6374271499956805,37.8882410462664865]},"#4455aa":{"lch":[38.9464770503006932,71.1678309986128141,261.658277796723496],"luv":[38.9464770503006932,-10.3247958657557941,-70.4149043837850144],"rgb":[0.266666666666666663,0.333333333333333315,0.66666666666666663],"xyz":[0.128871267464557376,0.106278542423495909,0.394038088272910092],"hpluv":[261.658277796723496,231.875507383352442,38.9464770503006932],"hsluv":[261.658277796723496,61.7617646139185652,38.9464770503006932]},"#4455bb":{"lch":[40.1033117689144,83.7900384834958,262.625350778636744],"luv":[40.1033117689144,-10.7550224317659584,-83.0969316013408417],"rgb":[0.266666666666666663,0.333333333333333315,0.733333333333333282],"xyz":[0.146008859571894023,0.113133579266430667,0.484296073371551838],"hpluv":[262.625350778636744,265.125486140416797,40.1033117689144],"hsluv":[262.625350778636744,66.2950009745661,40.1033117689144]},"#4455cc":{"lch":[41.3509797710146,95.8983760986006075,263.292411358069444],"luv":[41.3509797710146,-11.2011488171863753,-95.24196975873555],"rgb":[0.266666666666666663,0.333333333333333315,0.8],"xyz":[0.165301235015615777,0.120850529443919469,0.585902584041821939],"hpluv":[263.292411358069444,294.28272942652967,41.3509797710146],"hsluv":[263.292411358069444,71.9850161095278906,41.3509797710146]},"#4455dd":{"lch":[42.6814446156526657,107.523441304607104,263.773623462042394],"luv":[42.6814446156526657,-11.661670844638417,-106.88917561239117],"rgb":[0.266666666666666663,0.333333333333333315,0.866666666666666696],"xyz":[0.186819560566249321,0.129457859664173,0.699232431941827937],"hpluv":[263.773623462042394,319.67109728436958,42.6814446156526657],"hsluv":[263.773623462042394,81.2732363837730247,42.6814446156526657]},"#4455ee":{"lch":[44.0866885883675,118.714724855013472,264.132858108854521],"luv":[44.0866885883675,-12.1352655753704255,-118.092850024109339],"rgb":[0.266666666666666663,0.333333333333333315,0.933333333333333348],"xyz":[0.21063174083242403,0.13898273177064302,0.82464324801035116],"hpluv":[264.132858108854521,341.693279595385377,44.0866885883675],"hsluv":[264.132858108854521,90.5684283810677186,44.0866885883675]},"#4455ff":{"lch":[45.5589321196955765,129.526958246416882,264.408404412275218],"luv":[45.5589321196955765,-12.6207071057408875,-128.910630534181024],"rgb":[0.266666666666666663,0.333333333333333315,1],"xyz":[0.236802789242255451,0.149451151134575744,0.962477436302133],"hpluv":[264.408404412275218,360.766296003954039,45.5589321196955765],"hsluv":[264.408404412275218,99.9999999999992752,45.5589321196955765]},"#bbdd00":{"lch":[83.0607051195576673,95.2176030862527796,99.223939245402],"luv":[83.0607051195576673,-15.2627740644400269,93.9863802119702427],"rgb":[0.733333333333333282,0.866666666666666696,0],"xyz":[0.463483785628456102,0.622773719281865423,0.0957905185125420555],"hpluv":[99.223939245402,239.164338292747971,83.0607051195576673],"hsluv":[99.223939245402,100.00000000000216,83.0607051195576673]},"#bbdd11":{"lch":[83.082156377860457,94.2793845093074765,99.3314951275217481],"luv":[83.082156377860457,-15.2870500651298524,93.0317604034238457],"rgb":[0.733333333333333282,0.866666666666666696,0.0666666666666666657],"xyz":[0.464495451128093206,0.623178385481720332,0.101118623477297692],"hpluv":[99.3314951275217481,237.15213625798873,83.082156377860457],"hsluv":[99.3314951275217481,98.93507934353417,83.082156377860457]},"#bbdd22":{"lch":[83.1218967422411765,92.5513012339483794,99.5354402549794486],"luv":[83.1218967422411765,-15.3318301742674485,91.2725497814347],"rgb":[0.733333333333333282,0.866666666666666696,0.133333333333333331],"xyz":[0.466370809266570263,0.623928528737111132,0.110995509673276885],"hpluv":[99.5354402549794486,233.433860498438293,83.1218967422411765],"hsluv":[99.5354402549794486,96.9737920722735538,83.1218967422411765]},"#bbdd33":{"lch":[83.1872593514570298,89.7372330308786,99.8847694763800718],"luv":[83.1872593514570298,-15.4049421957575614,88.4050832700449263],"rgb":[0.733333333333333282,0.866666666666666696,0.2],"xyz":[0.469458559999027969,0.625163629030094259,0.127257663530888021],"hpluv":[99.8847694763800718,227.34486653748678,83.1872593514570298],"hsluv":[99.8847694763800718,93.7802848880547373,83.1872593514570298]},"#bbdd44":{"lch":[83.2814760883348697,85.7419087717973,100.421139587323779],"luv":[83.2814760883348697,-15.5091702542505097,84.3275788686944452],"rgb":[0.733333333333333282,0.866666666666666696,0.266666666666666663],"xyz":[0.473916555243246884,0.626946827127781825,0.15073643848377466],"hpluv":[100.421139587323779,218.62539011377612,83.2814760883348697],"hsluv":[100.421139587323779,89.2463889616074511,83.2814760883348697]},"#bbdd55":{"lch":[83.4072088624658,80.5207963453540572,101.204557559233223],"luv":[83.4072088624658,-15.6461875861262687,78.9860459708531835],"rgb":[0.733333333333333282,0.866666666666666696,0.333333333333333315],"xyz":[0.479878969282608869,0.629331792743526575,0.182138485757748575],"hpluv":[101.204557559233223,207.093501481883948,83.4072088624658],"hsluv":[101.204557559233223,83.3201121340644448,83.4072088624658]},"#bbdd66":{"lch":[83.5666996797624364,74.0772937371066149,102.328486133362119],"luv":[83.5666996797624364,-15.816696660053216,72.3690372616455164],"rgb":[0.733333333333333282,0.866666666666666696,0.4],"xyz":[0.487463965056117055,0.632365791052929893,0.222086130164892537],"hpluv":[102.328486133362119,192.635686460640301,83.5666996797624364],"hsluv":[102.328486133362119,75.9999631534792854,83.5666996797624364]},"#bbdd77":{"lch":[83.7618505003220122,66.4632811318093388,103.948126608074304],"luv":[83.7618505003220122,-16.0205304866066705,64.5035684418593149],"rgb":[0.733333333333333282,0.866666666666666696,0.466666666666666674],"xyz":[0.49677797807631896,0.636091396261010744,0.271139932071290446],"hpluv":[103.948126608074304,175.207590447676779,83.7618505003220122],"hsluv":[103.948126608074304,67.3303268013154,83.7618505003220122]},"#bbdd88":{"lch":[83.9942706402616,57.7845188457632091,106.339844930601203],"luv":[83.9942706402616,-16.2567564016803381,55.4505950331715454],"rgb":[0.733333333333333282,0.866666666666666696,0.533333333333333326],"xyz":[0.50791839517826276,0.640547563101788286,0.329812795474862641],"hpluv":[106.339844930601203,154.850612540446264,83.9942706402616],"hsluv":[106.339844930601203,57.39610210967858,83.9942706402616]},"#bbdd99":{"lch":[84.2653073070245711,48.2191913160874819,110.040291826115165],"luv":[84.2653073070245711,-16.5237946272095257,45.2996095159246153],"rgb":[0.733333333333333282,0.866666666666666696,0.6],"xyz":[0.520975359287335515,0.6457703487454175,0.39857947311598052],"hpluv":[110.040291826115165,131.749772406416298,84.2653073070245711],"hsluv":[110.040291826115165,46.3161497548768466,84.2653073070245711]},"#bbddaa":{"lch":[84.5760668100806328,38.0784660246866622,116.212889721452115],"luv":[84.5760668100806328,-16.8195514991441222,34.1624393473425059],"rgb":[0.733333333333333282,0.866666666666666696,0.66666666666666663],"xyz":[0.536033052252588,0.651793425931518566,0.477883322732979121],"hpluv":[116.212889721452115,106.421399158629868,84.5760668100806328],"hsluv":[116.212889721452115,34.2356923349747433,84.5760668100806328]},"#bbddbb":{"lch":[84.9274305013996553,28.0212505683590543,127.715012949233824],"luv":[84.9274305013996553,-17.1415612181778,22.1665821095230058],"rgb":[0.733333333333333282,0.866666666666666696,0.733333333333333282],"xyz":[0.55317064435992469,0.658648462774453325,0.568141307831620868],"hpluv":[127.715012949233824,80.3800713533813109,84.9274305013996553],"hsluv":[127.715012949233824,21.3181094477761164,84.9274305013996553]},"#bbddcc":{"lch":[85.3200677868051,19.876471170849122,151.617083508593169],"luv":[85.3200677868051,-17.4871274790593141,9.44851727715650291],"rgb":[0.733333333333333282,0.866666666666666696,0.8],"xyz":[0.572463019803646445,0.666365412951942182,0.669747818501891],"hpluv":[151.617083508593169,58.7374284962306703,85.3200677868051],"hsluv":[151.617083508593169,24.0698773292010699,85.3200677868051]},"#bbdddd":{"lch":[85.7544476215988,18.2643967282432129,192.177050630059739],"luv":[85.7544476215988,-17.8534562098583329,-3.85256916996079246],"rgb":[0.733333333333333282,0.866666666666666696,0.866666666666666696],"xyz":[0.593981345354279933,0.674972743172195688,0.783077666401897],"hpluv":[192.177050630059739,55.8245506661868234,85.7544476215988],"hsluv":[192.177050630059739,26.9205986284609722,85.7544476215988]},"#bbddee":{"lch":[86.2308493598319359,25.3453434934362818,223.980933900351914],"luv":[86.2308493598319359,-18.2377721186398958,-17.6002870700688909],"rgb":[0.733333333333333282,0.866666666666666696,0.933333333333333348],"xyz":[0.617793525620454753,0.684497615278665705,0.908488482470420244],"hpluv":[223.980933900351914,80.4705047412629142,86.2308493598319359],"hsluv":[223.980933900351914,55.5800524236117397,86.2308493598319359]},"#bbddff":{"lch":[86.7493734858622076,36.743147173338194,239.520163688183],"luv":[86.7493734858622076,-18.6374141011141354,-31.6655279416778761],"rgb":[0.733333333333333282,0.866666666666666696,1],"xyz":[0.643964574030286063,0.694966034642598429,1.0463226707622022],"hpluv":[239.520163688183,121.752323062157373,86.7493734858622076],"hsluv":[239.520163688183,99.9999999999938325,86.7493734858622076]},"#99ee00":{"lch":[85.9664003491010646,109.204546268980621,112.979852313128234],"luv":[85.9664003491010646,-42.6342645949387915,100.538313136150634],"rgb":[0.6,0.933333333333333348,0],"xyz":[0.437097727388796042,0.679199404132492912,0.108068425671767623],"hpluv":[112.979852313128234,339.428934639809256,85.9664003491010646],"hsluv":[112.979852313128234,100.000000000002444,85.9664003491010646]},"#99ee11":{"lch":[85.9866468155118326,108.350123359521945,113.156064955940181],"luv":[85.9866468155118326,-42.6072764400583495,99.6211284135251702],"rgb":[0.6,0.933333333333333348,0.0666666666666666657],"xyz":[0.438109392888433147,0.67960407033234782,0.11339653063652326],"hpluv":[113.156064955940181,337.317445797395,85.9866468155118326],"hsluv":[113.156064955940181,99.0182391276988,85.9866468155118326]},"#99ee22":{"lch":[86.0241571186350455,106.77763062148405,113.488368653358094],"luv":[86.0241571186350455,-42.5576013317541353,97.9301433166804287],"rgb":[0.6,0.933333333333333348,0.133333333333333331],"xyz":[0.439984751026910204,0.680354213587738621,0.123273416832502453],"hpluv":[113.488368653358094,333.419677856626379,86.0241571186350455],"hsluv":[113.488368653358094,97.2091916908085238,86.0241571186350455]},"#99ee33":{"lch":[86.0858572784747906,104.220652596579697,114.05202992935186],"luv":[86.0858572784747906,-42.476800751453851,95.1717701084636],"rgb":[0.6,0.933333333333333348,0.2],"xyz":[0.443072501759367909,0.681589313880721748,0.139535570690113603],"hpluv":[114.05202992935186,327.048640581280779,86.0858572784747906],"hsluv":[114.05202992935186,94.2610252844147709,86.0858572784747906]},"#99ee44":{"lch":[86.1748066309051239,100.599171066032113,114.904029942881266],"luv":[86.1748066309051239,-42.3622716989010186,91.2448966007484756],"rgb":[0.6,0.933333333333333348,0.266666666666666663],"xyz":[0.447530497003586825,0.683372511978409314,0.163014345643000241],"hpluv":[114.904029942881266,317.953677409096201,86.1748066309051239],"hsluv":[114.904029942881266,90.0700159696272777,86.1748066309051239]},"#99ee55":{"lch":[86.2935317577421586,95.884762204841536,116.119599614249481],"luv":[86.2935317577421586,-42.2129155656731854,86.0927254913233355],"rgb":[0.6,0.933333333333333348,0.333333333333333315],"xyz":[0.45349291104294881,0.685757477594154063,0.194416392916974157],"hpluv":[116.119599614249481,305.984138616458665,86.2935317577421586],"hsluv":[116.119599614249481,84.5822993375075924,86.2935317577421586]},"#99ee66":{"lch":[86.4441689863048879,90.1009507230509143,117.805124209421223],"luv":[86.4441689863048879,-42.0290075887870955,79.6978283411745565],"rgb":[0.6,0.933333333333333348,0.4],"xyz":[0.461077906816457,0.688791475903557382,0.234364037324118091],"hpluv":[117.805124209421223,291.090686380889622,86.4441689863048879],"hsluv":[117.805124209421223,77.7887546135139587,86.4441689863048879]},"#99ee77":{"lch":[86.6285404402691199,83.3280712532883712,120.117619079442107],"luv":[86.6285404402691199,-41.8120893585486826,72.0785449510868261],"rgb":[0.6,0.933333333333333348,0.466666666666666674],"xyz":[0.470391919836658901,0.692517081111638233,0.283417839230516],"hpluv":[120.117619079442107,273.344218704658658,86.6285404402691199],"hsluv":[120.117619079442107,69.7211272565473,86.6285404402691199]},"#99ee88":{"lch":[86.8481992617441563,75.7142340291470646,123.296374810060541],"luv":[86.8481992617441563,-41.5648380664255939,63.2851441582641],"rgb":[0.6,0.933333333333333348,0.533333333333333326],"xyz":[0.481532336938602701,0.696973247952415775,0.342090702634088195],"hpluv":[123.296374810060541,252.981665625798911,86.8481992617441563],"hsluv":[123.296374810060541,60.4476982156994964,86.8481992617441563]},"#99ee99":{"lch":[87.1044587056640864,67.4980907628946483,127.715012949238613],"luv":[87.1044587056640864,-41.2908999939099388,53.3952604107227131],"rgb":[0.6,0.933333333333333348,0.6],"xyz":[0.4945893010476754,0.702196033596045,0.410857380275206074],"hpluv":[127.715012949238613,230.504268403717248,87.1044587056640864],"hsluv":[127.715012949238613,50.0680020008431583,87.1044587056640864]},"#99eeaa":{"lch":[87.3984122167822477,59.0554460818204134,133.961345837807],"luv":[87.3984122167822477,-40.9946911699179566,42.5085992218733182],"rgb":[0.6,0.933333333333333348,0.66666666666666663],"xyz":[0.509646994012928,0.708219110782146,0.490161229892204675],"hpluv":[133.961345837807,206.883546406693341,87.3984122167822477],"hsluv":[133.961345837807,51.4281429353489514,87.3984122167822477]},"#99eebb":{"lch":[87.7309483141988409,50.9899623050450046,142.923108379062683],"luv":[87.7309483141988409,-40.6811762109167603,30.7411476358032338],"rgb":[0.6,0.933333333333333348,0.733333333333333282],"xyz":[0.526784586120264575,0.715074147625080814,0.580419214990846477],"hpluv":[142.923108379062683,183.977628608542716,87.7309483141988409],"hsluv":[142.923108379062683,52.8887094272277523,87.7309483141988409]},"#99eecc":{"lch":[88.1027624984453581,44.2777406304916781,155.702396707036257],"luv":[88.1027624984453581,-40.3556400464907483,18.219237958245273],"rgb":[0.6,0.933333333333333348,0.8],"xyz":[0.546076961563986329,0.722791097802569671,0.682025725661116633],"hpluv":[155.702396707036257,165.259943503195302,88.1027624984453581],"hsluv":[155.702396707036257,54.4312604691531305,88.1027624984453581]},"#99eedd":{"lch":[88.514367527899708,40.3437945821223494,172.775068456479858],"luv":[88.514367527899708,-40.023467685182176,5.07383442158517628],"rgb":[0.6,0.933333333333333348,0.866666666666666696],"xyz":[0.567595287114619929,0.731398428022823177,0.795355573561122631],"hpluv":[172.775068456479858,156.503534311163719,88.514367527899708],"hsluv":[172.775068456479858,56.0368199873083199,88.514367527899708]},"#99eeee":{"lch":[88.9661029048661476,40.6035054290346196,192.177050630060762],"luv":[88.9661029048661476,-39.6899452486728,-8.56463071492281891],"rgb":[0.6,0.933333333333333348,0.933333333333333348],"xyz":[0.591407467380794638,0.740923300129293194,0.920766389629645854],"hpluv":[192.177050630060762,164.568757380081195,88.9661029048661476],"hsluv":[192.177050630060762,57.6866071933722324,88.9661029048661476]},"#99eeff":{"lch":[89.4581440962481338,45.3723498615675496,209.831659516829347],"luv":[89.4581440962481338,-39.3600920674606272,-22.5706287994267498],"rgb":[0.6,0.933333333333333348,1],"xyz":[0.617578515790626059,0.751391719493225918,1.05860057792142759],"hpluv":[209.831659516829347,193.255751503994162,89.4581440962481338],"hsluv":[209.831659516829347,99.9999999999917293,89.4581440962481338]},"#446600":{"lch":[39.1245088935371612,48.4489514943966242,110.29724752770484],"luv":[39.1245088935371612,-16.806485623906017,45.4405429311736668],"rgb":[0.266666666666666663,0.4,0],"xyz":[0.0713500585462719106,0.107314951185536064,0.0169546366210883669],"hpluv":[110.29724752770484,157.13568029472475,39.1245088935371612],"hsluv":[110.29724752770484,100.000000000002302,39.1245088935371612]},"#446611":{"lch":[39.1937103273453289,46.0071342898824156,111.370502443062165],"luv":[39.1937103273453289,-16.7648801632844737,42.843846683952],"rgb":[0.266666666666666663,0.4,0.0666666666666666657],"xyz":[0.0723617240459090288,0.107719617385390917,0.022282741585844],"hpluv":[111.370502443062165,148.9526145018813,39.1937103273453289],"hsluv":[111.370502443062165,93.861989786091,39.1937103273453289]},"#446622":{"lch":[39.3215343087732165,41.6757739733598,113.610346420587263],"luv":[39.3215343087732165,-16.6917518579939177,38.1871124358693947],"rgb":[0.266666666666666663,0.4,0.133333333333333331],"xyz":[0.0742370821843860579,0.108469760640781732,0.0321596277818231926],"hpluv":[113.610346420587263,134.490790122462073,39.3215343087732165],"hsluv":[113.610346420587263,82.9003633409612,39.3215343087732165]},"#446633":{"lch":[39.530716823468623,35.0960892868442684,118.194686061271412],"luv":[39.530716823468623,-16.5818151114938139,30.931842668007679],"rgb":[0.266666666666666663,0.4,0.2],"xyz":[0.0773248329168437915,0.109704860933764844,0.0484217816394343359],"hpluv":[118.194686061271412,112.658344014206364,39.530716823468623],"hsluv":[118.194686061271412,65.945418212904,39.530716823468623]},"#446644":{"lch":[39.8299759493166761,26.8801274380109838,127.715012949238059],"luv":[39.8299759493166761,-16.4434970133495142,21.2638815143349724],"rgb":[0.266666666666666663,0.4,0.266666666666666663],"xyz":[0.0817828281610626651,0.111488059031452424,0.0719005565923209744],"hpluv":[127.715012949238059,85.6368345314009,39.8299759493166761],"hsluv":[127.715012949238059,43.6044123282566858,39.8299759493166761]},"#446655":{"lch":[40.2252775564066809,18.9132283301115756,149.466153210293243],"luv":[40.2252775564066809,-16.2905155992652197,9.6088140463343148],"rgb":[0.266666666666666663,0.4,0.333333333333333315],"xyz":[0.087745242200424664,0.113873024647197257,0.10330260386629489],"hpluv":[149.466153210293243,59.6631175613842473,40.2252775564066809],"hsluv":[149.466153210293243,47.2452022491104273,40.2252775564066809]},"#446666":{"lch":[40.7202569602655728,16.510473073285187,192.177050630060847],"luv":[40.7202569602655728,-16.1389950297194247,-3.48260829470770128],"rgb":[0.266666666666666663,0.4,0.4],"xyz":[0.0953302379739328354,0.116907022956600576,0.143250248273438852],"hpluv":[192.177050630060847,51.4503500463259655,40.7202569602655728],"hsluv":[192.177050630060847,51.2489582821824214,40.7202569602655728]},"#446677":{"lch":[41.3164898648363632,23.6752994583974647,227.46784435344162],"luv":[41.3164898648363632,-16.0045942322577233,-17.4462823519963166],"rgb":[0.266666666666666663,0.4,0.466666666666666674],"xyz":[0.104644250994134755,0.120632628164681385,0.192304050179836761],"hpluv":[227.46784435344162,72.7128872034151783,41.3164898648363632],"hsluv":[227.46784435344162,55.4049423234493261,41.3164898648363632]},"#446688":{"lch":[42.0137303768536654,35.5424939627414,243.425378218088099],"luv":[42.0137303768536654,-15.9003964812462133,-31.7875175002811758],"rgb":[0.266666666666666663,0.4,0.533333333333333326],"xyz":[0.115784668096078583,0.125088795005458969,0.2509769135834089],"hpluv":[243.425378218088099,107.348500116853913,42.0137303768536654],"hsluv":[243.425378218088099,59.5313600522085409,42.0137303768536654]},"#446699":{"lch":[42.8101553746289696,48.7666560663799089,251.050944767945737],"luv":[42.8101553746289696,-15.8358652521886238,-46.1238779333558782],"rgb":[0.266666666666666663,0.4,0.6],"xyz":[0.128841632205151296,0.130311580649088155,0.319743591224526835],"hpluv":[251.050944767945737,144.549135771893674,42.8101553746289696],"hsluv":[251.050944767945737,63.4907652576423231,42.8101553746289696]},"#4466aa":{"lch":[43.7026231888915078,62.2363741998113298,255.27738032783347],"luv":[43.7026231888915078,-15.8167390859625119,-60.1929982491778404],"rgb":[0.266666666666666663,0.4,0.66666666666666663],"xyz":[0.143899325170403825,0.136334657835189249,0.399047440841525436],"hpluv":[255.27738032783347,180.707469421570693,43.7026231888915078],"hsluv":[255.27738032783347,67.1924648453768896,43.7026231888915078]},"#4466bb":{"lch":[44.6869405362706402,75.5191451090451409,257.888120209084718],"luv":[44.6869405362706402,-15.8455247037125186,-73.83807029483539],"rgb":[0.266666666666666663,0.4,0.733333333333333282],"xyz":[0.161036917277740499,0.143189694678124,0.489305425940167182],"hpluv":[257.888120209084718,214.444923406304468,44.6869405362706402],"hsluv":[257.888120209084718,70.5866413561882098,44.6869405362706402]},"#4466cc":{"lch":[45.7581261645645299,88.428992560325014,259.626929599743789],"luv":[45.7581261645645299,-15.9222446749778896,-86.983727499712],"rgb":[0.266666666666666663,0.4,0.8],"xyz":[0.180329292721462225,0.150906644855612809,0.590911936610437283],"hpluv":[259.626929599743789,245.225581131482073,45.7581261645645299],"hsluv":[259.626929599743789,73.6549291646736179,45.7581261645645299]},"#4466dd":{"lch":[46.9106590907269165,100.895184366494064,260.849495088158733],"luv":[46.9106590907269165,-16.0451985527389489,-99.6111933055317422],"rgb":[0.266666666666666663,0.4,0.866666666666666696],"xyz":[0.201847618272095769,0.159513975075866343,0.704241784510443281],"hpluv":[260.849495088158733,272.92180192815988,46.9106590907269165],"hsluv":[260.849495088158733,78.541907894368677,46.9106590907269165]},"#4466ee":{"lch":[48.1387014995781897,112.90717489320852,261.744736192665698],"luv":[48.1387014995781897,-16.2116120228509466,-111.737253313235385],"rgb":[0.266666666666666663,0.4,0.933333333333333348],"xyz":[0.225659798538270506,0.16903884718233636,0.829652600578966504],"hpluv":[261.744736192665698,297.623004098842955,48.1387014995781897],"hsluv":[261.744736192665698,89.2025828989012126,48.1387014995781897]},"#4466ff":{"lch":[49.4362898036433194,124.485902067172418,262.421323096893047],"luv":[49.4362898036433194,-16.4181334215125325,-123.398479360286501],"rgb":[0.266666666666666663,0.4,1],"xyz":[0.251830846948101872,0.179507266546269084,0.967486788870748349],"hpluv":[262.421323096893047,319.531462910383539,49.4362898036433194],"hsluv":[262.421323096893047,99.9999999999992,49.4362898036433194]},"#bbee00":{"lch":[87.830324097455545,103.474670767003104,103.901308289378321],"luv":[87.830324097455545,-24.8598111448325625,100.444000717728017],"rgb":[0.733333333333333282,0.933333333333333348,0],"xyz":[0.510662561968970863,0.717131271962896388,0.111516777292713254],"hpluv":[103.901308289378321,376.707439149390723,87.830324097455545],"hsluv":[103.901308289378321,100.000000000002331,87.830324097455545]},"#bbee11":{"lch":[87.8498503793181413,102.621932764236291,104.023160127863235],"luv":[87.8498503793181413,-24.8667401733108697,99.5635792718425705],"rgb":[0.733333333333333282,0.933333333333333348,0.0666666666666666657],"xyz":[0.511674227468608,0.717535938162751297,0.116844882257468891],"hpluv":[104.023160127863235,374.263941750279344,87.8498503793181413],"hsluv":[104.023160127863235,99.0733759990956315,87.8498503793181413]},"#bbee22":{"lch":[87.8860274909110757,101.050540606732312,104.253301125000391],"luv":[87.8860274909110757,-24.8795662288424886,97.9398741125263],"rgb":[0.733333333333333282,0.933333333333333348,0.133333333333333331],"xyz":[0.513549585607085,0.718286081418142097,0.126721768453448069],"hpluv":[104.253301125000391,369.744422226518111,87.8860274909110757],"hsluv":[104.253301125000391,97.3653524759520224,87.8860274909110757]},"#bbee33":{"lch":[87.9455377581158899,98.4895893313188111,104.644745385959411],"luv":[87.9455377581158899,-24.9006321902472507,95.2898615970127878],"rgb":[0.733333333333333282,0.933333333333333348,0.2],"xyz":[0.516637336339542785,0.719521181711125224,0.142983922311059219],"hpluv":[104.644745385959411,362.331462484484575,87.9455377581158899],"hsluv":[104.644745385959411,94.5802259429375454,87.9455377581158899]},"#bbee44":{"lch":[88.03133674845418,94.8494424101932339,105.239087045756335],"luv":[88.03133674845418,-24.9309340294718567,91.5142898892991781],"rgb":[0.733333333333333282,0.933333333333333348,0.266666666666666663],"xyz":[0.521095331583761645,0.72130437980881279,0.166462697263945858],"hpluv":[105.239087045756335,351.690778632920285,88.03133674845418],"hsluv":[105.239087045756335,90.61757843521751,88.03133674845418]},"#bbee55":{"lch":[88.145869167101,90.085489786575252,106.092871571181419],"luv":[88.145869167101,-24.9712578135623886,86.5553681367929499],"rgb":[0.733333333333333282,0.933333333333333348,0.333333333333333315],"xyz":[0.527057745623123575,0.72368934542455754,0.197864744537919773],"hpluv":[106.092871571181419,337.573290416608245,88.145869167101],"hsluv":[106.092871571181419,85.422816781051381,88.145869167101]},"#bbee66":{"lch":[88.2912067804751786,84.1961694748550116,107.288882190620882],"luv":[88.2912067804751786,-25.0222263001917433,80.3920589686599527],"rgb":[0.733333333333333282,0.933333333333333348,0.4],"xyz":[0.534642741396631815,0.726723343733960858,0.237812388945063735],"hpluv":[107.288882190620882,319.804166688067426,88.2912067804751786],"hsluv":[107.288882190620882,78.9823949944632631,88.2912067804751786]},"#bbee77":{"lch":[88.4691221578712828,77.2243366572971439,108.954917992899311],"luv":[88.4691221578712828,-25.0843250262429365,73.0368044901840534],"rgb":[0.733333333333333282,0.933333333333333348,0.466666666666666674],"xyz":[0.543956754416833665,0.730448948942041709,0.286866190851461644],"hpluv":[108.954917992899311,298.285685525501094,88.4691221578712828],"hsluv":[108.954917992899311,71.3203705839542,88.4691221578712828]},"#bbee88":{"lch":[88.6811325759484106,69.2626802552854599,111.298371855766348],"luv":[88.6811325759484106,-25.1579200624522237,64.5321465184381822],"rgb":[0.733333333333333282,0.933333333333333348,0.533333333333333326],"xyz":[0.555097171518777577,0.734905115782819252,0.34553905425503384],"hpluv":[111.298371855766348,273.019747479454225,88.6811325759484106],"hsluv":[111.298371855766348,62.4946759175697224,88.6811325759484106]},"#bbee99":{"lch":[88.9285282571087095,60.4678989000773228,114.674688063820184],"luv":[88.9285282571087095,-25.2432722518949362,54.9467378777547069],"rgb":[0.733333333333333282,0.933333333333333348,0.6],"xyz":[0.568154135627850221,0.740127901426448465,0.414305731896151719],"hpluv":[114.674688063820184,244.173567048365754,88.9285282571087095],"hsluv":[114.674688063820184,52.5925914284503548,88.9285282571087095]},"#bbeeaa":{"lch":[89.2123917942545148,51.0969811847688931,119.731125412935242],"luv":[89.2123917942545148,-25.3405499711494109,44.3706886734509212],"rgb":[0.733333333333333282,0.933333333333333348,0.66666666666666663],"xyz":[0.583211828593102832,0.746150978612549531,0.493609581513150319],"hpluv":[119.731125412935242,212.254877789093854,89.2123917942545148],"hsluv":[119.731125412935242,41.7253920748903084,89.2123917942545148]},"#bbeebb":{"lch":[89.5336124490095,41.6027669810227181,127.715012949236097],"luv":[89.5336124490095,-25.4498411950279184,32.9104208971130276],"rgb":[0.733333333333333282,0.933333333333333348,0.733333333333333282],"xyz":[0.600349420700439396,0.75300601545548429,0.583867566611792066],"hpluv":[127.715012949236097,178.587287563939924,89.5336124490095],"hsluv":[127.715012949236097,37.7465419844818,89.5336124490095]},"#bbeecc":{"lch":[89.8928974614309766,32.8889663829363883,141.03222670888556],"luv":[89.8928974614309766,-25.571165029146556,20.6833176446640721],"rgb":[0.733333333333333282,0.933333333333333348,0.8],"xyz":[0.61964179614416115,0.760722965632973147,0.685474077282062222],"hpluv":[141.03222670888556,146.627829178506289,89.8928974614309766],"hsluv":[141.03222670888556,37.1073685119788,89.8928974614309766]},"#bbeedd":{"lch":[90.290781675649967,26.8655052232995288,163.094148385079734],"luv":[90.290781675649967,-25.704482585445124,7.81248653872008436],"rgb":[0.733333333333333282,0.933333333333333348,0.866666666666666696],"xyz":[0.641160121694794749,0.769330295853226653,0.79880392518206822],"hpluv":[163.094148385079734,125.084011642469022,90.290781675649967],"hsluv":[163.094148385079734,36.2429238875219255,90.290781675649967]},"#bbeeee":{"lch":[90.7276363011350782,26.4447005646089579,192.177050630060336],"luv":[90.7276363011350782,-25.8497069757021904,-5.5780675168164624],"rgb":[0.733333333333333282,0.933333333333333348,0.933333333333333348],"xyz":[0.664972301960969459,0.77885516795969667,0.924214741250591443],"hpluv":[192.177050630060336,129.38009793870765,90.7276363011350782],"hsluv":[192.177050630060336,36.8413123479339077,90.7276363011350782]},"#bbeeff":{"lch":[91.2036773284388289,32.4261328799939648,216.675663960190036],"luv":[91.2036773284388289,-26.0067122100428421,-19.367627980086624],"rgb":[0.733333333333333282,0.933333333333333348,1],"xyz":[0.69114335037080088,0.789323587323629394,1.06204892954237318],"hpluv":[216.675663960190036,167.86892764061264,91.2036773284388289],"hsluv":[216.675663960190036,99.9999999999901235,91.2036773284388289]},"#99ff00":{"lch":[90.9122626200542214,118.290950299530564,115.261698016578393],"luv":[90.9122626200542214,-50.4810643573161286,106.978554225220847],"rgb":[0.6,1,0],"xyz":[0.48895009981846993,0.782904148991842,0.125352549814991721],"hpluv":[115.261698016578393,591.369219456757151,90.9122626200542214],"hsluv":[115.261698016578393,100.000000000002402,90.9122626200542214]},"#99ff11":{"lch":[90.9306796583728,117.513960007406183,115.422432906031332],"luv":[90.9306796583728,-50.4474247175277384,106.134764031356056],"rgb":[0.6,1,0.0666666666666666657],"xyz":[0.489961765318107034,0.783308815191696928,0.130680654779747357],"hpluv":[115.422432906031332,588.764777700997797,90.9306796583728],"hsluv":[115.422432906031332,99.9999999999905356,90.9306796583728]},"#99ff22":{"lch":[90.9648031673089577,116.082935310332914,115.724658723180369],"luv":[90.9648031673089577,-50.3854319755480944,104.577990585497247],"rgb":[0.6,1,0.133333333333333331],"xyz":[0.491837123456584091,0.784058958447087728,0.140557540975726536],"hpluv":[115.724658723180369,583.951350293788323,90.9648031673089577],"hsluv":[115.724658723180369,99.9999999999904219,90.9648031673089577]},"#99ff33":{"lch":[91.0209396556716399,113.753057852482627,116.234667099004312],"luv":[91.0209396556716399,-50.2843870930134642,102.035477092383132],"rgb":[0.6,1,0.2],"xyz":[0.494924874189041797,0.785294058740070855,0.156819694833337686],"hpluv":[116.234667099004312,576.067585056329449,91.0209396556716399],"hsluv":[116.234667099004312,99.9999999999905924,91.0209396556716399]},"#99ff44":{"lch":[91.1018839706868562,110.446777199697451,116.999375135233294],"luv":[91.1018839706868562,-50.1407143313292565,98.409345898362929],"rgb":[0.6,1,0.266666666666666663],"xyz":[0.499382869433260712,0.787077256837758421,0.180298469786224325],"hpluv":[116.999375135233294,564.777897061868,91.1018839706868562],"hsluv":[116.999375135233294,99.9999999999903793,91.1018839706868562]},"#99ff55":{"lch":[91.2099533036034558,106.130684884370282,118.07780645420398],"luv":[91.2099533036034558,-49.9525457622324112,93.6400846106921279],"rgb":[0.6,1,0.333333333333333315],"xyz":[0.505345283472622642,0.789462222453503171,0.21170051706019824],"hpluv":[118.07780645420398,549.854625367801646,91.2099533036034558],"hsluv":[118.07780645420398,99.9999999999901377,91.2099533036034558]},"#99ff66":{"lch":[91.3471179899501351,100.815112661229691,119.549522622156928],"luv":[91.3471179899501351,-49.7195590247369807,87.7020660605103899],"rgb":[0.6,1,0.4],"xyz":[0.512930279246130882,0.792496220762906489,0.251648161467342202],"hpluv":[119.549522622156928,531.176396965461777,91.3471179899501351],"hsluv":[119.549522622156928,99.9999999999902656,91.3471179899501351]},"#99ff77":{"lch":[91.5150716426202,94.5571579863012488,121.52621580287979],"luv":[91.5150716426202,-49.442863485124569,80.6006164792656534],"rgb":[0.6,1,0.466666666666666674],"xyz":[0.522244292266332732,0.79622182597098734,0.300701963373740111],"hpluv":[121.52621580287979,508.746904082031563,91.5150716426202],"hsluv":[121.52621580287979,99.9999999999900098,91.5150716426202]},"#99ff88":{"lch":[91.7152730008064481,87.4673964918121385,124.169042550433474],"luv":[91.7152730008064481,-49.1248751175299461,72.3691377159004077],"rgb":[0.6,1,0.533333333333333326],"xyz":[0.533384709368276644,0.800677992811764883,0.359374826777312251],"hpluv":[124.169042550433474,482.74240688111388,91.7152730008064481],"hsluv":[124.169042550433474,99.999999999989754,91.7152730008064481]},"#99ff99":{"lch":[91.9489728509177,79.7227767672504,127.715012949239039],"luv":[91.9489728509177,-48.7691602166467675,63.0657604984184559],"rgb":[0.6,1,0.6],"xyz":[0.546441673477349288,0.805900778455394096,0.428141504418430185],"hpluv":[127.715012949239039,453.611771943482722,91.9489728509177],"hsluv":[127.715012949239039,99.9999999999896119,91.9489728509177]},"#99ffaa":{"lch":[92.2172324754492365,71.5909188251234525,132.515331265000469],"luv":[92.2172324754492365,-48.380245540777544,52.769418223432119],"rgb":[0.6,1,0.66666666666666663],"xyz":[0.561499366442601899,0.811923855641495162,0.507445354035428786],"hpluv":[132.515331265000469,422.278899597361089,92.2172324754492365],"hsluv":[132.515331265000469,99.999999999989285,92.2172324754492365]},"#99ffbb":{"lch":[92.5209371039878334,63.4744472180726902,139.080731133451],"luv":[92.5209371039878334,-47.9634018094000325,41.5754439123617558],"rgb":[0.6,1,0.733333333333333282],"xyz":[0.578636958549938463,0.818778892484429921,0.597703339134070477],"hpluv":[139.080731133451,390.542311531215887,92.5209371039878334],"hsluv":[139.080731133451,99.9999999999889866,92.5209371039878334]},"#99ffcc":{"lch":[92.8608063839845,55.9838497302527216,148.091690615728766],"luv":[92.8608063839845,-47.524412431304512,29.5909049148346774],"rgb":[0.6,1,0.8],"xyz":[0.597929333993660217,0.826495842661918778,0.699309849804340633],"hpluv":[148.091690615728766,361.818313682118117,92.8608063839845],"hsluv":[148.091690615728766,99.999999999988475,92.8608063839845]},"#99ffdd":{"lch":[93.237403107538583,50.0214511206169306,160.217319691395858],"luv":[93.237403107538583,-47.0693412211659066,16.9299347080170577],"rgb":[0.6,1,0.866666666666666696],"xyz":[0.619447659544293816,0.835103172882172284,0.812639697704346631],"hpluv":[160.217319691395858,342.295010089686684,93.237403107538583],"hsluv":[160.217319691395858,99.999999999988,93.237403107538583]},"#99ffee":{"lch":[93.6511409780710267,46.7516947594382444,175.449324589633676],"luv":[93.6511409780710267,-46.6043124006013088,3.70931645277729727],"rgb":[0.6,1,0.933333333333333348],"xyz":[0.643259839810468526,0.844628044988642301,0.938050513772869854],"hpluv":[175.449324589633676,341.869484566500148,93.6511409780710267],"hsluv":[175.449324589633676,99.9999999999875,93.6511409780710267]},"#99ffff":{"lch":[94.102291921527609,47.1972299789563579,192.177050630060847],"luv":[94.102291921527609,-46.1353140316371437,-9.95546668362271703],"rgb":[0.6,1,1],"xyz":[0.6694308882203,0.855096464352575,1.07588470206465181],"hpluv":[192.177050630060847,372.830957625984183,94.102291921527609],"hsluv":[192.177050630060847,99.999999999986585,94.102291921527609]},"#447700":{"lch":[44.83248944102629,58.4741115144389809,115.479055163134589],"luv":[44.83248944102629,-25.1544589141716,52.7870714677211339],"rgb":[0.266666666666666663,0.466666666666666674,0],"xyz":[0.0898037965996895393,0.144222427292371835,0.0231058826388940708],"hpluv":[115.479055163134589,165.50461307776385,44.83248944102629],"hsluv":[115.479055163134589,100.00000000000216,44.83248944102629]},"#447711":{"lch":[44.8893318820142468,56.4264635629906337,116.3750363045054],"luv":[44.8893318820142468,-25.0671673404006405,50.5527735317644158],"rgb":[0.266666666666666663,0.466666666666666674,0.0666666666666666657],"xyz":[0.0908154620993266576,0.144627093492226688,0.0284339876036497],"hpluv":[116.3750363045054,159.506732057184706,44.8893318820142468],"hsluv":[116.3750363045054,95.4073228169634433,44.8893318820142468]},"#447722":{"lch":[44.9944227930058389,52.7636609180533824,118.171656995978211],"luv":[44.9944227930058389,-24.9105023189221484,46.5131248971114388],"rgb":[0.266666666666666663,0.466666666666666674,0.133333333333333331],"xyz":[0.0926908202378036866,0.145377236747617516,0.0383108737996289],"hpluv":[118.171656995978211,148.804327803607492,44.9944227930058389],"hsluv":[118.171656995978211,87.128369469673089,44.9944227930058389]},"#447733":{"lch":[45.1666686690004795,47.1090234718488,121.574089601592789],"luv":[45.1666686690004795,-24.6663168629185812,40.1351828809748881],"rgb":[0.266666666666666663,0.466666666666666674,0.2],"xyz":[0.0957785709702614202,0.146612337040600615,0.0545730276572400433],"hpluv":[121.574089601592789,132.350433634303585,45.1666686690004795],"hsluv":[121.574089601592789,74.1245535442141232,45.1666686690004795]},"#447744":{"lch":[45.4136534494367368,39.7908238780444137,127.715012949239082],"luv":[45.4136534494367368,-24.3414133770851677,31.4770592606648769],"rgb":[0.266666666666666663,0.466666666666666674,0.266666666666666663],"xyz":[0.100236566214480294,0.148395535138288209,0.0780518026101266749],"hpluv":[127.715012949239082,111.18234158710581,45.4136534494367368],"hsluv":[127.715012949239082,56.6116285441109,45.4136534494367368]},"#447755":{"lch":[45.7409133262359902,31.7219583115713704,139.030718806592802],"luv":[45.7409133262359902,-23.9520203549447466,20.798638417872084],"rgb":[0.266666666666666663,0.466666666666666674,0.333333333333333315],"xyz":[0.106198980253842293,0.150780500754033042,0.10945384988410059],"hpluv":[139.030718806592802,88.0023935360314766,45.7409133262359902],"hsluv":[139.030718806592802,58.7992252631310066,45.7409133262359902]},"#447766":{"lch":[46.1522822994750328,25.0075472636366349,160.141849635166039],"luv":[46.1522822994750328,-23.5205108300662609,8.49488024846472],"rgb":[0.266666666666666663,0.466666666666666674,0.4],"xyz":[0.113783976027350464,0.153814499063436333,0.149401494291244552],"hpluv":[160.141849635166039,68.7570511480334,46.1522822994750328],"hsluv":[160.141849635166039,61.2825519214888672,46.1522822994750328]},"#447777":{"lch":[46.650089933282672,23.6026970305602966,192.177050630060933],"luv":[46.650089933282672,-23.0716472128555,-4.97859438013953248],"rgb":[0.266666666666666663,0.466666666666666674,0.466666666666666674],"xyz":[0.123097989047552384,0.157540104271517156,0.198455296197642461],"hpluv":[192.177050630060933,64.2019875277067,46.650089933282672],"hsluv":[192.177050630060933,63.9506821134950414,46.650089933282672]},"#447788":{"lch":[47.2353114433284134,29.6592888392359697,220.273189901853613],"luv":[47.2353114433284134,-22.6291741496980734,-19.1727382434503575],"rgb":[0.266666666666666663,0.466666666666666674,0.533333333333333326],"xyz":[0.134238406149496226,0.161996271112294754,0.257128159601214601],"hpluv":[220.273189901853613,79.6770556088496,47.2353114433284134],"hsluv":[220.273189901853613,66.6958169909158585,47.2353114433284134]},"#447799":{"lch":[47.9077085122244526,40.3569508451274856,236.603980798736757],"luv":[47.9077085122244526,-22.2133832668581981,-33.6934576046404],"rgb":[0.266666666666666663,0.466666666666666674,0.6],"xyz":[0.147295370258568925,0.167219056755923912,0.325894837242332536],"hpluv":[236.603980798736757,106.893740352524901,47.9077085122244526],"hsluv":[236.603980798736757,69.4246608010291197,47.9077085122244526]},"#4477aa":{"lch":[48.6659751090485,52.9419227285019574,245.636459716194196],"luv":[48.6659751090485,-21.8398581964299439,-48.2272513849846476],"rgb":[0.266666666666666663,0.466666666666666674,0.66666666666666663],"xyz":[0.162353063223821481,0.173242133942025,0.405198686859331136],"hpluv":[245.636459716194196,138.042751347741245,48.6659751090485],"hsluv":[245.636459716194196,72.0643617009564,48.6659751090485]},"#4477bb":{"lch":[49.5078912458612,66.145388752002,251.014275727268966],"luv":[49.5078912458612,-21.5192486824625604,-62.5470573991759125],"rgb":[0.266666666666666663,0.466666666666666674,0.733333333333333282],"xyz":[0.1794906553311581,0.180097170784959765,0.495456671957972883],"hpluv":[251.014275727268966,169.536991245322184,49.5078912458612],"hsluv":[251.014275727268966,74.5637193650047578,49.5078912458612]},"#4477cc":{"lch":[50.4304819457797606,79.4031370336833,254.471410742848605],"luv":[50.4304819457797606,-21.2577420931439356,-76.5046833330565761],"rgb":[0.266666666666666663,0.466666666666666674,0.8],"xyz":[0.198783030774879854,0.187814120962448566,0.597063182628243094],"hpluv":[254.471410742848605,199.794656417231295,50.4304819457797606],"hsluv":[254.471410742848605,76.8911855438839638,50.4304819457797606]},"#4477dd":{"lch":[51.4301761714764183,92.4467030892661654,256.833353640671476],"luv":[51.4301761714764183,-21.0578873175855144,-90.0164334652001514],"rgb":[0.266666666666666663,0.466666666666666674,0.866666666666666696],"xyz":[0.220301356325513398,0.1964214511827021,0.710393030528249092],"hpluv":[256.833353640671476,228.093412194404408,51.4301761714764183],"hsluv":[256.833353640671476,79.0312420746427904,51.4301761714764183]},"#4477ee":{"lch":[52.5029598761355913,105.148975578657073,258.524369979875587],"luv":[52.5029598761355913,-20.9195063280493,-103.046985983248078],"rgb":[0.266666666666666663,0.466666666666666674,0.933333333333333348],"xyz":[0.244113536591688135,0.205946323289172145,0.835803846596772315],"hpluv":[258.524369979875587,254.132720010738154,52.5029598761355913],"hsluv":[258.524369979875587,87.6254974090696,52.5029598761355913]},"#4477ff":{"lch":[53.6445179522116,117.458222301342076,259.779939364455799],"luv":[53.6445179522116,-20.8405325230258285,-115.594576820663164],"rgb":[0.266666666666666663,0.466666666666666674,1],"xyz":[0.270284585001519528,0.216414742653104841,0.973638034888554],"hpluv":[259.779939364455799,277.841684308431127,53.6445179522116],"hsluv":[259.779939364455799,99.999999999999,53.6445179522116]},"#bbff00":{"lch":[92.6117448358007778,112.09772632761252,107.605046807390437],"luv":[92.6117448358007778,-33.9043888880720843,106.847520616749406],"rgb":[0.733333333333333282,1,0],"xyz":[0.56251493439864475,0.820836016822245496,0.128800901435937365],"hpluv":[107.605046807390437,698.685604225905081,92.6117448358007778],"hsluv":[107.605046807390437,100.000000000002302,92.6117448358007778]},"#bbff11":{"lch":[92.6295901709342,111.320425805292416,107.729052066712285],"luv":[92.6295901709342,-33.8988588935206678,106.033506813595423],"rgb":[0.733333333333333282,1,0.0666666666666666657],"xyz":[0.56352659989828191,0.821240683022100404,0.134129006400693],"hpluv":[107.729052066712285,695.618439183936061,92.6295901709342],"hsluv":[107.729052066712285,99.9999999999893703,92.6295901709342]},"#bbff22":{"lch":[92.6626551654141,109.887399193340656,107.962519071076329],"luv":[92.6626551654141,-33.888700280085942,104.531318248662245],"rgb":[0.733333333333333282,1,0.133333333333333331],"xyz":[0.565401958036758856,0.821990826277491204,0.14400589259667218],"hpluv":[107.962519071076329,689.937572971075,92.6626551654141],"hsluv":[107.962519071076329,99.9999999999891713,92.6626551654141]},"#bbff33":{"lch":[92.7170524122382318,107.550157892444602,108.357408717671873],"luv":[92.7170524122382318,-33.8722333827189388,102.076972272674624],"rgb":[0.733333333333333282,1,0.2],"xyz":[0.568489708769216673,0.823225926570474331,0.160268046454283331],"hpluv":[108.357408717671873,680.59767216104342,92.7170524122382318],"hsluv":[108.357408717671873,99.9999999999894271,92.7170524122382318]},"#bbff44":{"lch":[92.7954935084343475,104.224206838295117,108.951712424811362],"luv":[92.7954935084343475,-33.8490183743317,98.5744857768270464],"rgb":[0.733333333333333282,1,0.266666666666666663],"xyz":[0.572947704013435533,0.825009124668161897,0.183746821407169969],"hpluv":[108.951712424811362,667.142517523628385,92.7954935084343475],"hsluv":[108.951712424811362,99.9999999999890576,92.7954935084343475]},"#bbff55":{"lch":[92.9002292713318809,99.8647848732016,109.794505003516988],"luv":[92.9002292713318809,-33.8189779888925628,93.9640994505754605],"rgb":[0.733333333333333282,1,0.333333333333333315],"xyz":[0.578910118052797462,0.827394090283906647,0.215148868681143884],"hpluv":[109.794505003516988,649.201221057988732,92.9002292713318809],"hsluv":[109.794505003516988,99.9999999999888445,92.9002292713318809]},"#bbff66":{"lch":[93.0331768315467826,94.4651128464689691,110.953951756581517],"luv":[93.0331768315467826,-33.7823795150753,88.2179595059619146],"rgb":[0.733333333333333282,1,0.4],"xyz":[0.586495113826305703,0.83042808859331,0.255096513088287846],"hpluv":[110.953951756581517,626.470359589551208,93.0331768315467826],"hsluv":[110.953951756581517,99.9999999999888871,93.0331768315467826]},"#bbff77":{"lch":[93.1959878807374196,88.0576290523864742,112.529317332402641],"luv":[93.1959878807374196,-33.7398191848892566,81.3373876867131571],"rgb":[0.733333333333333282,1,0.466666666666666674],"xyz":[0.595809126846507553,0.834153693801390816,0.304150314994685755],"hpluv":[112.529317332402641,598.713569857690459,93.1959878807374196],"hsluv":[112.529317332402641,99.9999999999886455,93.1959878807374196]},"#bbff88":{"lch":[93.3900894470196334,80.7182094219550805,114.670873894576516],"luv":[93.3900894470196334,-33.6921989698203319,73.3502901212028888],"rgb":[0.733333333333333282,1,0.533333333333333326],"xyz":[0.606949543948451464,0.838609860642168359,0.362823178398257951],"hpluv":[114.670873894576516,565.785048639302204,93.3900894470196334],"hsluv":[114.670873894576516,99.9999999999880913,93.3900894470196334]},"#bbff99":{"lch":[93.6167101348934239,72.575742292483838,117.61482369288214],"luv":[93.6167101348934239,-33.6406927329059684,64.3081811417119411],"rgb":[0.733333333333333282,1,0.6],"xyz":[0.620006508057524108,0.843832646285797572,0.43158985603937583],"hpluv":[117.61482369288214,527.702623330867254,93.6167101348934239],"hsluv":[117.61482369288214,99.9999999999881,93.6167101348934239]},"#bbffaa":{"lch":[93.8768980816178384,63.8331941826517948,121.746607961207644],"luv":[93.8768980816178384,-33.5867019719833948,54.2826872050868303],"rgb":[0.733333333333333282,1,0.66666666666666663],"xyz":[0.63506420102277672,0.849855723471898639,0.510893705656374486],"hpluv":[121.746607961207644,484.836572610502856,93.8768980816178384],"hsluv":[121.746607961207644,99.9999999999878781,93.8768980816178384]},"#bbffbb":{"lch":[94.1715339943383,54.8143223318485937,127.715012949237362],"luv":[94.1715339943383,-33.5318032859449531,43.3615970772812602],"rgb":[0.733333333333333282,1,0.733333333333333282],"xyz":[0.652201793130113283,0.856710760314833397,0.601151690755016177],"hpluv":[127.715012949237362,438.38038704048256,94.1715339943383],"hsluv":[127.715012949237362,99.999999999986926,94.1715339943383]},"#bbffcc":{"lch":[94.5013412228876888,46.0666753200389323,136.612331153023604],"luv":[94.5013412228876888,-33.4776907719138919,31.6446329670924698],"rgb":[0.733333333333333282,1,0.8],"xyz":[0.671494168573835,0.864427710492322254,0.702758201425286333],"hpluv":[136.612331153023604,391.513584290668746,94.5013412228876888],"hsluv":[136.612331153023604,99.9999999999865707,94.5013412228876888]},"#bbffdd":{"lch":[94.8668940681869515,38.5674836948257322,150.076437256866],"luv":[94.8668940681869515,-33.4261169986321818,19.2391658068743077],"rgb":[0.733333333333333282,1,0.866666666666666696],"xyz":[0.693012494124468637,0.873035040712575761,0.816088049325292331],"hpluv":[150.076437256866,352.109825744613431,94.8668940681869515],"hsluv":[150.076437256866,99.9999999999853628,94.8668940681869515]},"#bbffee":{"lch":[95.2686250900245568,33.9600576278843675,169.384373669661102],"luv":[95.2686250900245568,-33.3788361105619771,6.25610214058809699],"rgb":[0.733333333333333282,1,0.933333333333333348],"xyz":[0.716824674390643346,0.882559912819045778,0.941498865393815554],"hpluv":[169.384373669661102,337.406400875084444,95.2686250900245568],"hsluv":[169.384373669661102,99.9999999999845,95.2686250900245568]},"#bbffff":{"lch":[95.7068319095003,34.1048965933827191,192.177050630060478],"luv":[95.7068319095003,-33.3375521201936849,-7.19385781613020914],"rgb":[0.733333333333333282,1,1],"xyz":[0.742995722800474767,0.893028332182978501,1.0793330536855974],"hpluv":[192.177050630060478,374.679972152143307,95.7068319095003],"hsluv":[192.177050630060478,99.9999999999829186,95.7068319095003]},"#448800":{"lch":[50.4956227619448157,68.4221216779621244,118.715311426014551],"luv":[50.4956227619448157,-32.873947818662586,60.0074186224478723],"rgb":[0.266666666666666663,0.533333333333333326,0],"xyz":[0.111876166324659992,0.18836716674231338,0.0304633392138840171],"hpluv":[118.715311426014551,171.942062028892252,50.4956227619448157],"hsluv":[118.715311426014551,100.000000000002373,50.4956227619448157]},"#448811":{"lch":[50.543205868460916,66.6756511812714763,119.435612575278299],"luv":[50.543205868460916,-32.7674265649617098,58.0683925794095899],"rgb":[0.266666666666666663,0.533333333333333326,0.0666666666666666657],"xyz":[0.112887831824297111,0.188771832942168233,0.0357914441786396503],"hpluv":[119.435612575278299,167.395510973175305,50.543205868460916],"hsluv":[119.435612575278299,96.4702491056824272,50.543205868460916]},"#448822":{"lch":[50.6312327062127565,63.5295563644356918,120.846986072134357],"luv":[50.6312327062127565,-32.5745953261955492,54.5426463530750425],"rgb":[0.266666666666666663,0.533333333333333326,0.133333333333333331],"xyz":[0.11476318996277414,0.189521976197559061,0.0456683303746188429],"hpluv":[120.846986072134357,159.219643782083125,50.6312327062127565],"hsluv":[120.846986072134357,90.0662104861249,50.6312327062127565]},"#448833":{"lch":[50.775662969350762,58.6076690216783831,123.408487274566809],"luv":[50.775662969350762,-32.2696404838739213,48.9237076599487182],"rgb":[0.266666666666666663,0.533333333333333326,0.2],"xyz":[0.117850940695231873,0.19075707649054216,0.0619304842322299931],"hpluv":[123.408487274566809,146.466455796741883,50.775662969350762],"hsluv":[123.408487274566809,79.8990388198805732,50.775662969350762]},"#448844":{"lch":[50.9830910358637652,52.0733509329185,127.715012949239537],"luv":[50.9830910358637652,-31.855056956676961,41.1933152789351382],"rgb":[0.266666666666666663,0.533333333333333326,0.266666666666666663],"xyz":[0.122308935939450747,0.192540274588229754,0.0854092591851166316],"hpluv":[127.715012949239537,129.607069016793787,50.9830910358637652],"hsluv":[127.715012949239537,65.9930987522981241,50.9830910358637652]},"#448855":{"lch":[51.2585265038955384,44.4350179761376651,134.860489600104756],"luv":[51.2585265038955384,-31.3437036744621551,31.4967151066136601],"rgb":[0.266666666666666663,0.533333333333333326,0.333333333333333315],"xyz":[0.128271349978812732,0.194925240203974587,0.116811306459090533],"hpluv":[134.860489600104756,110.001490313735033,51.2585265038955384],"hsluv":[134.860489600104756,67.3517725464548676,51.2585265038955384]},"#448866":{"lch":[51.6056896491522537,36.7437212642011914,146.829747927558799],"luv":[51.6056896491522537,-30.7562765884277063,20.1035445321824895],"rgb":[0.266666666666666663,0.533333333333333326,0.4],"xyz":[0.135856345752320917,0.197959238513377878,0.156758950866234509],"hpluv":[146.829747927558799,90.3493178961374781,51.6056896491522537],"hsluv":[146.829747927558799,68.9308752248562797,51.6056896491522537]},"#448877":{"lch":[52.0271709342862039,31.0045548915217921,166.266503182991642],"luv":[52.0271709342862039,-30.1181499011556575,7.36067052332227245],"rgb":[0.266666666666666663,0.533333333333333326,0.466666666666666674],"xyz":[0.145170358772522823,0.201684843721458701,0.205812752772632418],"hpluv":[166.266503182991642,75.6196418937204555,52.0271709342862039],"hsluv":[166.266503182991642,70.6726995402934506,52.0271709342862039]},"#448888":{"lch":[52.5245390493459041,30.1341009641634088,192.177050630061],"luv":[52.5245390493459041,-29.456097564679137,-6.35628485662009179],"rgb":[0.266666666666666663,0.533333333333333326,0.533333333333333326],"xyz":[0.156310775874466679,0.206141010562236299,0.264485616176204585],"hpluv":[192.177050630061,72.8006598676027181,52.5245390493459041],"hsluv":[192.177050630061,72.5156967272479847,52.5245390493459041]},"#448899":{"lch":[53.0984315279962118,35.4547108695225,215.690916113393854],"luv":[53.0984315279962118,-28.7954664423823949,-20.6847198484066084],"rgb":[0.266666666666666663,0.533333333333333326,0.6],"xyz":[0.169367739983539378,0.211363796205865456,0.333252293817322465],"hpluv":[215.690916113393854,84.7289026839812,53.0984315279962118],"hsluv":[215.690916113393854,74.4011420122721319,53.0984315279962118]},"#4488aa":{"lch":[53.7486427971268625,45.1587425535104146,231.425064236121358],"luv":[53.7486427971268625,-28.1581765792043193,-35.3048030832715654],"rgb":[0.266666666666666663,0.533333333333333326,0.66666666666666663],"xyz":[0.184425432948791934,0.217386873391966551,0.412556143434321065],"hpluv":[231.425064236121358,106.613859301848393,53.7486427971268625],"hsluv":[231.425064236121358,76.2778611087785,53.7486427971268625]},"#4488bb":{"lch":[54.4742155909258514,57.0545505189943469,241.113543257937238],"luv":[54.4742155909258514,-27.5616516575745152,-49.9557513488787208],"rgb":[0.266666666666666663,0.533333333333333326,0.733333333333333282],"xyz":[0.201563025056128553,0.224241910234901309,0.502814128532962812],"hpluv":[241.113543257937238,132.904176722924205,54.4742155909258514],"hsluv":[241.113543257937238,78.1047803623200707,54.4742155909258514]},"#4488cc":{"lch":[55.273536978614473,69.875332030770025,247.25266296501286],"luv":[55.273536978614473,-27.0185618464256976,-64.4403549195783398],"rgb":[0.266666666666666663,0.533333333333333326,0.8],"xyz":[0.220855400499850307,0.231958860412390111,0.604420639203233],"hpluv":[247.25266296501286,160.415361718249983,55.273536978614473],"hsluv":[247.25266296501286,79.8515774594708603,55.273536978614473]},"#4488dd":{"lch":[56.1444377207636194,82.97891177410213,251.348812353132246],"luv":[56.1444377207636194,-26.53714651812043,-78.6211145551246631],"rgb":[0.266666666666666663,0.533333333333333326,0.866666666666666696],"xyz":[0.242373726050483851,0.240566190632643645,0.717750487103239],"hpluv":[251.348812353132246,187.542769341675751,56.1444377207636194],"hsluv":[251.348812353132246,81.4979766670821,56.1444377207636194]},"#4488ee":{"lch":[57.0842924141545609,96.0325607902411775,254.216059778839536],"luv":[57.0842924141545609,-26.1218678035424112,-92.4115834426919776],"rgb":[0.266666666666666663,0.533333333333333326,0.933333333333333348],"xyz":[0.266185906316658616,0.25009106273911369,0.843161303171762189],"hpluv":[254.216059778839536,213.472145126724115,57.0842924141545609],"hsluv":[254.216059778839536,85.8050168900109469,57.0842924141545609]},"#4488ff":{"lch":[58.090117466996233,108.861046277687535,256.304473865935392],"luv":[58.090117466996233,-25.7741898685227575,-105.765866579412872],"rgb":[0.266666666666666663,0.533333333333333326,1],"xyz":[0.29235695472649,0.260559482103046358,0.980995491463544],"hpluv":[256.304473865935392,237.798754650411269,58.090117466996233],"hsluv":[256.304473865935392,99.9999999999988631,58.090117466996233]},"#449900":{"lch":[56.0984423000037538,78.159424491283,120.852962610827774],"luv":[56.0984423000037538,-40.0830169860907191,67.0987882610508279],"rgb":[0.266666666666666663,0.6,0],"xyz":[0.137745766777127493,0.240106367647249075,0.0390865393647062687],"hpluv":[120.852962610827774,176.794958777624345,56.0984423000037538],"hsluv":[120.852962610827774,100.000000000002416,56.0984423000037538]},"#449911":{"lch":[56.1389235634784143,76.6482268999804859,121.431666795625887],"luv":[56.1389235634784143,-39.9706170908808929,65.4010738159938256],"rgb":[0.266666666666666663,0.6,0.0666666666666666657],"xyz":[0.138757432276764625,0.240511033847103928,0.0444146443294619],"hpluv":[121.431666795625887,173.251641588156104,56.1389235634784143],"hsluv":[121.431666795625887,97.2234127009916,56.1389235634784143]},"#449922":{"lch":[56.21384509356389,73.9109075723002746,122.549403254372123],"luv":[56.21384509356389,-39.7660359546788555,62.3015621201611793],"rgb":[0.266666666666666663,0.6,0.133333333333333331],"xyz":[0.140632790415241626,0.241261177102494756,0.0542915305254411],"hpluv":[122.549403254372123,166.841685682494415,56.21384509356389],"hsluv":[122.549403254372123,92.1627352690631,56.21384509356389]},"#449933":{"lch":[56.3368647095541064,69.5846668696270143,124.526315047954697],"luv":[56.3368647095541064,-39.4395235157555177,57.3284383897480296],"rgb":[0.266666666666666663,0.6,0.2],"xyz":[0.143720541147699388,0.242496277395477855,0.0705536843830522342],"hpluv":[124.526315047954697,156.73291295139785,56.3368647095541064],"hsluv":[124.526315047954697,84.0665441712718859,56.3368647095541064]},"#449944":{"lch":[56.5137417426914368,63.7361451042890153,127.715012949239735],"luv":[56.5137417426914368,-38.9895886498958575,50.4193233757345922],"rgb":[0.266666666666666663,0.6,0.266666666666666663],"xyz":[0.148178536391918247,0.244279475493165449,0.0940324593359388727],"hpluv":[127.715012949239735,143.110354253444,56.5137417426914368],"hsluv":[127.715012949239735,72.8686777069245,56.5137417426914368]},"#449955":{"lch":[56.7489681974646629,56.6620380577650309,132.698160989074609],"luv":[56.7489681974646629,-38.4245724364924328,41.642992086692793],"rgb":[0.266666666666666663,0.6,0.333333333333333315],"xyz":[0.154140950431280233,0.246664441108910282,0.125434506609912788],"hpluv":[132.698160989074609,126.69910537289924,56.7489681974646629],"hsluv":[132.698160989074609,73.7405349232989664,56.7489681974646629]},"#449966":{"lch":[57.0460268500437166,48.9673458777373511,140.456743036678859],"luv":[57.0460268500437166,-37.7608817984154683,31.1755796757022061],"rgb":[0.266666666666666663,0.6,0.4],"xyz":[0.161725946204788418,0.249698439418313572,0.16538215101705675],"hpluv":[140.456743036678859,108.923224533285605,57.0460268500437166],"hsluv":[140.456743036678859,74.7718537787272766,57.0460268500437166]},"#449977":{"lch":[57.4075272841014481,41.7361359201695734,152.500832231763781],"luv":[57.4075272841014481,-37.0206846158697,19.2710651526888199],"rgb":[0.266666666666666663,0.6,0.466666666666666674],"xyz":[0.171039959224990323,0.253424044626394396,0.214435952923454659],"hpluv":[152.500832231763781,92.2534727828265915,57.4075272841014481],"hsluv":[152.500832231763781,75.9325502249844817,57.4075272841014481]},"#449988":{"lch":[57.8352917232380861,36.7607331244742284,170.245603374965924],"luv":[57.8352917232380861,-36.2292854489646174,6.22819200942437323],"rgb":[0.266666666666666663,0.6,0.533333333333333326],"xyz":[0.182180376326934179,0.257880211467172,0.273108816327026827],"hpluv":[170.245603374965924,80.6548633994409414,57.8352917232380861],"hsluv":[170.245603374965924,77.1878957355486222,57.8352917232380861]},"#449999":{"lch":[58.3304201548299517,36.2276744984656105,192.17705063006116],"luv":[58.3304201548299517,-35.4125684996312486,-7.64162232943372643],"rgb":[0.266666666666666663,0.6,0.6],"xyz":[0.195237340436006879,0.263102997110801151,0.341875493968144761],"hpluv":[192.17705063006116,78.8106081595615251,58.3304201548299517],"hsluv":[192.17705063006116,78.5021203184449803,58.3304201548299517]},"#4499aa":{"lch":[58.8933484328044585,41.0197173156303379,212.502133513081617],"luv":[58.8933484328044585,-34.5948579745346478,-22.041166266239177],"rgb":[0.266666666666666663,0.6,0.66666666666666663],"xyz":[0.210295033401259435,0.269126074296902273,0.421179343585143307],"hpluv":[212.502133513081617,88.3823902117899536,58.8933484328044585],"hsluv":[212.502133513081617,79.8414276244135692,58.8933484328044585]},"#4499bb":{"lch":[59.523905851944221,49.8962585520308082,227.36281958486083],"luv":[59.523905851944221,-33.7974051546762055,-36.7065664738854878],"rgb":[0.266666666666666663,0.6,0.733333333333333282],"xyz":[0.227432625508596054,0.275981111139837032,0.511437328683785108],"hpluv":[227.36281958486083,106.36919851968392,59.523905851944221],"hsluv":[227.36281958486083,81.1761313086710885,59.523905851944221]},"#4499cc":{"lch":[60.2213749252976385,61.1171242450200438,237.278146949597897],"luv":[60.2213749252976385,-33.0375484580145766,-51.4181219791773],"rgb":[0.266666666666666663,0.6,0.8],"xyz":[0.246725000952317808,0.283698061317325834,0.613043839354055264],"hpluv":[237.278146949597897,128.780934100622716,60.2213749252976385],"hsluv":[237.278146949597897,82.4818489079811741,60.2213749252976385]},"#4499dd":{"lch":[60.9845539619455508,73.4958381074912,243.904542785491344],"luv":[60.9845539619455508,-32.3284648877968195,-66.0038527445257728],"rgb":[0.266666666666666663,0.6,0.866666666666666696],"xyz":[0.268243326502951351,0.29230539153757934,0.726373687254061262],"hpluv":[243.904542785491344,152.926314240713424,60.9845539619455508],"hsluv":[243.904542785491344,83.7398679369964469,60.9845539619455508]},"#4499ee":{"lch":[61.8118218103912653,86.3580647779335351,248.479300934605874],"luv":[61.8118218103912653,-31.6793620640961606,-80.3376211460214193],"rgb":[0.266666666666666663,0.6,0.933333333333333348],"xyz":[0.292055506769126061,0.301830263644049357,0.851784503322584485],"hpluv":[248.479300934605874,177.284466220706,61.8118218103912653],"hsluv":[248.479300934605874,84.9368954206658344,61.8118218103912653]},"#4499ff":{"lch":[62.7012034705467585,99.3269113509348,251.755860244601337],"luv":[62.7012034705467585,-31.0959452870692914,-94.3338619225358173],"rgb":[0.266666666666666663,0.6,1],"xyz":[0.318226555178957482,0.312298683007982081,0.98961869161436633],"hpluv":[251.755860244601337,201.015886170810859,62.7012034705467585],"hsluv":[251.755860244601337,99.9999999999986073,62.7012034705467585]},"#330000":{"lch":[6.35863201887414942,21.3842798011123882,12.1770506300617836],"luv":[6.35863201887414942,20.9031433498234946,4.51065635013277699],"rgb":[0.2,0,0],"xyz":[0.0136521011456799905,0.00703936465324139522,0.000639942241203736136],"hpluv":[12.1770506300617836,426.746789183125031,6.35863201887414942],"hsluv":[12.1770506300617836,100.000000000002217,6.35863201887414942]},"#330011":{"lch":[6.72416549840036915,18.2596394021459751,358.956333183931122],"luv":[6.72416549840036915,18.2566101970553,-0.332588648601129133],"rgb":[0.2,0,0.0666666666666666657],"xyz":[0.0146637666453171122,0.00744403085309625,0.00596804720595936738],"hpluv":[358.956333183931122,344.582429927088697,6.72416549840036915],"hsluv":[358.956333183931122,99.9999999999970868,6.72416549840036915]},"#330022":{"lch":[7.4017671226143058,16.6083885778583671,334.642609555635659],"luv":[7.4017671226143058,15.0082373074967617,-7.11276205668364714],"rgb":[0.2,0,0.133333333333333331],"xyz":[0.0165391247837941326,0.00819417410848706854,0.0158449334019385643],"hpluv":[334.642609555635659,284.728805881674077,7.4017671226143058],"hsluv":[334.642609555635659,99.999999999998,7.4017671226143058]},"#330033":{"lch":[8.50665746950019,19.3767863388894384,307.715012949243601],"luv":[8.50665746950019,11.8534455994177517,-15.3282639670843448],"rgb":[0.2,0,0.2],"xyz":[0.0196268755162518696,0.00942927440147018139,0.0321070872595497075],"hpluv":[307.715012949243601,289.042783730483279,8.50665746950019],"hsluv":[307.715012949243601,99.9999999999987921,8.50665746950019]},"#330044":{"lch":[9.96321399083228343,25.9151774110163871,290.632214162589],"luv":[9.96321399083228343,9.13167627644372,-24.2530185467023678],"rgb":[0.2,0,0.266666666666666663],"xyz":[0.0240848707604707502,0.0112124724991577579,0.0555858622124363461],"hpluv":[290.632214162589,330.060881015257678,9.96321399083228343],"hsluv":[290.632214162589,99.9999999999994,9.96321399083228343]},"#330055":{"lch":[11.6870713271151807,34.2775786608295405,281.502617436257196],"luv":[11.6870713271151807,6.83538450996046,-33.589133919325],"rgb":[0.2,0,0.333333333333333315],"xyz":[0.0300472847998327422,0.0135974381149025891,0.0869879094864102614],"hpluv":[281.502617436257196,372.172061509357604,11.6870713271151807],"hsluv":[281.502617436257196,99.9999999999999289,11.6870713271151807]},"#330066":{"lch":[13.6097387714237676,43.4818398400869768,276.434806151814087],"luv":[13.6097387714237676,4.87312317733106592,-43.2079051375733059],"rgb":[0.2,0,0.4],"xyz":[0.0376322805733409205,0.0166314364243059024,0.126935553893554209],"hpluv":[276.434806151814087,405.412793254212261,13.6097387714237676],"hsluv":[276.434806151814087,100.00000000000027,13.6097387714237676]},"#330077":{"lch":[15.6735112457106673,53.108485659557914,273.408523183706109],"luv":[15.6735112457106673,3.15755804167271537,-53.0145364618510655],"rgb":[0.2,0,0.466666666666666674],"xyz":[0.046946293593542833,0.0203570416323867187,0.175989355799952119],"hpluv":[273.408523183706109,429.968801903614121,15.6735112457106673],"hsluv":[273.408523183706109,100.000000000000313,15.6735112457106673]},"#330088":{"lch":[17.8339183845063687,62.9511834901283365,271.47985970994057],"luv":[17.8339183845063687,1.62574911173865799,-62.9301870538574448],"rgb":[0.2,0,0.533333333333333326],"xyz":[0.058086710695486661,0.0248132084731643096,0.234662219203524286],"hpluv":[271.47985970994057,447.91587095992594,17.8339183845063687],"hsluv":[271.47985970994057,100.000000000000441,17.8339183845063687]},"#330099":{"lch":[20.0583065104412341,72.8932825114363,270.184356583024851],"luv":[20.0583065104412341,0.234543162084408924,-72.8929051746271313],"rgb":[0.2,0,0.6],"xyz":[0.0711436748045593814,0.0300359941167934706,0.303428896844642193],"hpluv":[270.184356583024851,461.139761646516433,20.0583065104412341],"hsluv":[270.184356583024851,100.000000000000625,20.0583065104412341]},"#3300aa":{"lch":[22.3232943619689834,82.8637729479105474,269.276671227287579],"luv":[22.3232943619689834,-1.04608331699459467,-82.8571697371855578],"rgb":[0.2,0,0.66666666666666663],"xyz":[0.0862013677698119235,0.0360590713028945756,0.382732746461640794],"hpluv":[269.276671227287579,471.026936966419044,22.3232943619689834],"hsluv":[269.276671227287579,100.000000000000554,22.3232943619689834]},"#3300bb":{"lch":[24.6123405885396807,92.8181896970849,268.61855571411644],"luv":[24.6123405885396807,-2.23769945956788,-92.7912120826788538],"rgb":[0.2,0,0.733333333333333282],"xyz":[0.10333895987714857,0.0429141081458293341,0.47299073156028254],"hpluv":[268.61855571411644,478.541387025058441,24.6123405885396807],"hsluv":[268.61855571411644,100.000000000000625,24.6123405885396807]},"#3300cc":{"lch":[26.9138017967000778,102.728605647013808,268.127719933063759],"luv":[26.9138017967000778,-3.35631165306985224,-102.673762910819349],"rgb":[0.2,0,0.8],"xyz":[0.122631335320870311,0.0506310583233181358,0.574597242230552752],"hpluv":[268.127719933063759,484.345947247320225,26.9138017967000778],"hsluv":[268.127719933063759,100.000000000000881,26.9138017967000778]},"#3300dd":{"lch":[29.2194977691074271,112.577730384171886,267.752877980499],"luv":[29.2194977691074271,-4.41413050162269105,-112.49115889867052],"rgb":[0.2,0,0.866666666666666696],"xyz":[0.144149660871503854,0.0592383885435716698,0.687927090130558749],"hpluv":[267.752877980499,488.89890937186334,29.2194977691074271],"hsluv":[267.752877980499,100.000000000000753,29.2194977691074271]},"#3300ee":{"lch":[31.5236887929336334,122.355215968494591,267.460804758990776],"luv":[31.5236887929336334,-5.42068013199621,-122.235081304851008],"rgb":[0.2,0,0.933333333333333348],"xyz":[0.167961841137678591,0.0687632606500417,0.813337906199082],"hpluv":[267.460804758990776,492.52103452607281,31.5236887929336334],"hsluv":[267.460804758990776,100.000000000000824,31.5236887929336334]},"#3300ff":{"lch":[33.8223579343154,132.055276159319874,267.229255072945307],"luv":[33.8223579343154,-6.38352242786170443,-131.900896899631505],"rgb":[0.2,0,1],"xyz":[0.194132889547509985,0.0792316800139744,0.951172094490863818],"hpluv":[267.229255072945307,495.440155164142311,33.8223579343154],"hsluv":[267.229255072945307,100.000000000000881,33.8223579343154]},"#331100":{"lch":[9.83576796362177319,19.9321083570360571,25.9770166386959609],"luv":[9.83576796362177319,17.918363864654,8.73047421223431108],"rgb":[0.2,0.0666666666666666657,0],"xyz":[0.0156565014066084,0.0110481651750982679,0.00130807566151318702],"hpluv":[25.9770166386959609,257.148675223584291,9.83576796362177319],"hsluv":[25.9770166386959609,100.000000000002302,9.83576796362177319]},"#331111":{"lch":[10.1474261289244687,16.4836545456174051,12.1770506300618813],"luv":[10.1474261289244687,16.1127799065782149,3.4769513746129066],"rgb":[0.2,0.0666666666666666657,0.0666666666666666657],"xyz":[0.0166681669062455212,0.0114528313749531225,0.00663618062626881826],"hpluv":[12.1770506300618813,206.127972902374523,10.1474261289244687],"hsluv":[12.1770506300618813,48.3021731216650707,10.1474261289244687]},"#331122":{"lch":[10.7062693823806221,14.2435433110065777,342.375847990242676],"luv":[10.7062693823806221,13.5749958919169824,-4.31254131423193],"rgb":[0.2,0.0666666666666666657,0.133333333333333331],"xyz":[0.0185435250447225398,0.0122029746303439404,0.0165130668222480161],"hpluv":[342.375847990242676,168.818174775843545,10.7062693823806221],"hsluv":[342.375847990242676,57.1044970617697913,10.7062693823806221]},"#331133":{"lch":[11.5784810016780177,17.5377888786733784,307.715012949244169],"luv":[11.5784810016780177,10.7284677021084427,-13.8735006223280077],"rgb":[0.2,0.0666666666666666657,0.2],"xyz":[0.0216312757771802804,0.0134380749233270532,0.0327752206798591628],"hpluv":[307.715012949244169,192.204068690519591,11.5784810016780177],"hsluv":[307.715012949244169,66.4967539441281,11.5784810016780177]},"#331144":{"lch":[12.7480449023252049,25.2894553184220108,288.641508688419037],"luv":[12.7480449023252049,8.08366941467993172,-23.9626968243691536],"rgb":[0.2,0.0666666666666666657,0.266666666666666663],"xyz":[0.0260892710213991574,0.0152212730210146297,0.0562539956327458],"hpluv":[288.641508688419037,251.73014018207067,12.7480449023252049],"hsluv":[288.641508688419037,74.5439781366083309,12.7480449023252049]},"#331155":{"lch":[14.1772863520069095,34.570642435857458,279.659572498507771],"luv":[14.1772863520069095,5.80074057604611415,-34.0805036230000695],"rgb":[0.2,0.0666666666666666657,0.333333333333333315],"xyz":[0.0320516850607611564,0.0176062386367594609,0.0876560429067197],"hpluv":[279.659572498507771,309.423764447612427,14.1772863520069095],"hsluv":[279.659572498507771,80.733364837348816,14.1772863520069095]},"#331166":{"lch":[15.8197098676790517,44.2946391552180785,274.993838621827194],"luv":[15.8197098676790517,3.85578699555013271,-44.1264995726595686],"rgb":[0.2,0.0666666666666666657,0.4],"xyz":[0.0396366808342693278,0.0206402369461627724,0.127603687313863678],"hpluv":[274.993838621827194,355.297359803625511,15.8197098676790517],"hsluv":[274.993838621827194,85.2848648605675095,15.8197098676790517]},"#331177":{"lch":[17.6293493428787755,54.1580116435351115,272.303494486185969],"luv":[17.6293493428787755,2.17675853502087469,-54.1142490242773135],"rgb":[0.2,0.0666666666666666657,0.466666666666666674],"xyz":[0.0489506938544712472,0.0243658421542435888,0.176657489220261588],"hpluv":[272.303494486185969,389.821469213037517,17.6293493428787755],"hsluv":[272.303494486185969,88.5936990192462588,17.6293493428787755]},"#331188":{"lch":[19.5658128626021437,64.0679547566568,270.623065923527406],"luv":[19.5658128626021437,0.696696562564985133,-64.064166587888522],"rgb":[0.2,0.0666666666666666657,0.533333333333333326],"xyz":[0.0600911109564150753,0.0288220089950211832,0.235330352623833755],"hpluv":[270.623065923527406,415.51077593183,19.5658128626021437],"hsluv":[270.623065923527406,91.0112456871911348,19.5658128626021437]},"#331199":{"lch":[21.5959931816331263,73.9854871429769645,269.508319412823],"luv":[21.5959931816331263,-0.634894604710849,-73.9827629696574576],"rgb":[0.2,0.0666666666666666657,0.6],"xyz":[0.0731480750654877887,0.0340447946386503442,0.304097030264951662],"hpluv":[269.508319412823,434.723064450461493,21.5959931816331263],"hsluv":[269.508319412823,92.7998436287799,21.5959931816331263]},"#3311aa":{"lch":[23.6938673935249824,83.8866252842298792,268.733700318675346],"luv":[23.6938673935249824,-1.85383566080119344,-83.8661385478044821],"rgb":[0.2,0.0666666666666666657,0.66666666666666663],"xyz":[0.0882057680307403308,0.0400678718247514457,0.383400879881950263],"hpluv":[268.733700318675346,449.258286440651602,23.6938673935249824],"hsluv":[268.733700318675346,94.1436997610677,23.6938673935249824]},"#3311bb":{"lch":[25.8394818705352094,93.7535423490500079,268.175268957576],"luv":[25.8394818705352094,-2.98531729009247,-93.7060007879569525],"rgb":[0.2,0.0666666666666666657,0.733333333333333282],"xyz":[0.105343360138076977,0.0469229086676862042,0.473658864980592],"hpluv":[268.175268957576,460.408371224539451,25.8394818705352094],"hsluv":[268.175268957576,95.1697562295976525,25.8394818705352094]},"#3311cc":{"lch":[28.017750605254669,103.572636018550753,267.760492630427507],"luv":[28.017750605254669,-4.04728980779695124,-103.493528189171812],"rgb":[0.2,0.0666666666666666657,0.8],"xyz":[0.124635735581798718,0.0546398588451750059,0.57526537565086211],"hpluv":[267.760492630427507,469.084508820223505,28.017750605254669],"hsluv":[267.760492630427507,95.9655004656031423,28.017750605254669]},"#3311dd":{"lch":[30.2173526676312889,113.33386550323506,267.444704079349265],"luv":[30.2173526676312889,-5.05282540459801588,-113.221173043455181],"rgb":[0.2,0.0666666666666666657,0.866666666666666696],"xyz":[0.146154061132432261,0.0632471890654285329,0.688595223550868107],"hpluv":[267.444704079349265,475.929488946899937,30.2173526676312889],"hsluv":[267.444704079349265,96.591763702558211,30.2173526676312889]},"#3311ee":{"lch":[32.429822932533412,123.030197380053124,267.199217974228532],"luv":[32.429822932533412,-6.01167404447580456,-122.883234180085807],"rgb":[0.2,0.0666666666666666657,0.933333333333333348],"xyz":[0.169966241398607,0.0727720611718985777,0.814006039619391331],"hpluv":[267.199217974228532,481.400425551936735,32.429822932533412],"hsluv":[267.199217974228532,97.0913881744298095,32.429822932533412]},"#3311ff":{"lch":[34.6488414224811834,132.657034918193688,267.004954598207064],"luv":[34.6488414224811834,-6.93127707868383425,-132.475832933200962],"rgb":[0.2,0.0666666666666666657,1],"xyz":[0.196137289808438392,0.0832404805358312738,0.951840227911173176],"hpluv":[267.004954598207064,485.826158631145177,34.6488414224811834],"hsluv":[267.004954598207064,99.999999999999531,34.6488414224811834]},"#88aa00":{"lch":[64.9493872277699467,75.8454165204624502,102.522158340464031],"luv":[64.9493872277699467,-16.4445883060260414,74.0412231301438624],"rgb":[0.533333333333333326,0.66666666666666663,0],"xyz":[0.245272120749672057,0.339833923051985953,0.0526729261635559762],"hpluv":[102.522158340464031,148.181371186867864,64.9493872277699467],"hsluv":[102.522158340464031,100.000000000002217,64.9493872277699467]},"#88aa11":{"lch":[64.9815053546997206,74.514883993558044,102.764001416735823],"luv":[64.9815053546997206,-16.4630035423646639,72.6734989589568414],"rgb":[0.533333333333333326,0.66666666666666663,0.0666666666666666657],"xyz":[0.246283786249309189,0.340238589251840806,0.0580010311283116059],"hpluv":[102.764001416735823,145.509915409181133,64.9815053546997206],"hsluv":[102.764001416735823,98.0498740713468635,64.9815053546997206]},"#88aa22":{"lch":[65.040976504183746,72.0784265262596762,103.230826782560158],"luv":[65.040976504183746,-16.4969246852166869,70.1651697527462801],"rgb":[0.533333333333333326,0.66666666666666663,0.133333333333333331],"xyz":[0.24815914438778619,0.340988732507231607,0.0678779173242908],"hpluv":[103.230826782560158,140.623392494363173,65.040976504183746],"hsluv":[103.230826782560158,94.4776072436414296,65.040976504183746]},"#88aa33":{"lch":[65.138705174337673,68.1506383708936596,104.056367163177015],"luv":[65.138705174337673,-16.5521781693680836,66.1100212389152],"rgb":[0.533333333333333326,0.66666666666666663,0.2],"xyz":[0.251246895120243952,0.342223832800214733,0.0841400711819019487],"hpluv":[104.056367163177015,132.760883332008575,65.138705174337673],"hsluv":[104.056367163177015,88.7139905695652544,65.138705174337673]},"#88aa44":{"lch":[65.2793887406011,62.6606585185119442,105.391240881396499],"luv":[65.2793887406011,-16.6306856640551395,60.4133960336360687],"rgb":[0.533333333333333326,0.66666666666666663,0.266666666666666663],"xyz":[0.255704890364462811,0.344007030897902299,0.107618846134788587],"hpluv":[105.391240881396499,121.803060858356815,65.2793887406011],"hsluv":[105.391240881396499,80.6421361820775,65.2793887406011]},"#88aa55":{"lch":[65.4667902277309821,55.6467221212728731,107.50018297907917],"luv":[65.4667902277309821,-16.7334615527701551,53.0711687011330397],"rgb":[0.533333333333333326,0.66666666666666663,0.333333333333333315],"xyz":[0.261667304403824796,0.34639199651364716,0.139020893408762503],"hpluv":[107.50018297907917,107.859366541167589,65.4667902277309821],"hsluv":[107.50018297907917,70.2829236383929157,65.4667902277309821]},"#88aa66":{"lch":[65.7039511656785606,47.2674293485405386,110.898270106627507],"luv":[65.7039511656785606,-16.8607549547505542,44.1579530727492582],"rgb":[0.533333333333333326,0.66666666666666663,0.4],"xyz":[0.269252300177333,0.349425994823050479,0.178968537815906464],"hpluv":[110.898270106627507,91.2871867148882075,65.7039511656785606],"hsluv":[110.898270106627507,57.7776943224234358,65.7039511656785606]},"#88aa77":{"lch":[65.993303036365262,37.8517489546572605,116.707912668539493],"luv":[65.993303036365262,-17.0121797895697142,33.8133204186420073],"rgb":[0.533333333333333326,0.66666666666666663,0.466666666666666674],"xyz":[0.278566313197534887,0.353151600031131274,0.228022339722304374],"hpluv":[116.707912668539493,72.782239014817236,65.993303036365262],"hsluv":[116.707912668539493,43.3670204896631262,65.993303036365262]},"#88aa88":{"lch":[66.3367341259492,28.0952907790087707,127.715012949235486],"luv":[66.3367341259492,-17.1868541575625393,22.2251526006848934],"rgb":[0.533333333333333326,0.66666666666666663,0.533333333333333326],"xyz":[0.289706730299478743,0.357607766871908872,0.286695203125876541],"hpluv":[127.715012949235486,53.7426121206727316,66.3367341259492],"hsluv":[127.715012949235486,27.3645684281827677,66.3367341259492]},"#88aa99":{"lch":[66.7356352778598705,19.8636867466165334,151.061783220075199],"luv":[66.7356352778598705,-17.3835461247401071,9.6113669837720046],"rgb":[0.533333333333333326,0.66666666666666663,0.6],"xyz":[0.302763694408551443,0.36283055251553803,0.35546188076699442],"hpluv":[151.061783220075199,37.7695130125235536,66.7356352778598705],"hsluv":[151.061783220075199,30.5390729913306274,66.7356352778598705]},"#88aaaa":{"lch":[67.1909358184889811,18.0059400546344968,192.177050630060364],"luv":[67.1909358184889811,-17.6008146924254447,-3.79805205519771905],"rgb":[0.533333333333333326,0.66666666666666663,0.66666666666666663],"xyz":[0.317821387373804,0.368853629701639152,0.434765730383993],"hpluv":[192.177050630060364,34.0051297749840913,67.1909358184889811],"hsluv":[192.177050630060364,33.872023720911649,67.1909358184889811]},"#88aabb":{"lch":[67.7031355134684674,25.1829477340388976,224.903065382651],"luv":[67.7031355134684674,-17.8371340556046292,-17.7768812016541453],"rgb":[0.533333333333333326,0.66666666666666663,0.733333333333333282],"xyz":[0.334958979481140617,0.37570866654457391,0.525023715482634823],"hpluv":[224.903065382651,47.1994684953027459,67.7031355134684674],"hsluv":[224.903065382651,37.296330310174362,67.7031355134684674]},"#88aacc":{"lch":[68.2723356589922901,36.8600300209604939,240.606662797769701],"luv":[68.2723356589922901,-18.0909926283411373,-32.1150712106857341],"rgb":[0.533333333333333326,0.66666666666666663,0.8],"xyz":[0.354251354924862372,0.383425616722062712,0.626630226152905],"hpluv":[240.606662797769701,68.5094136262693,68.2723356589922901],"hsluv":[240.606662797769701,40.7502319604911136,68.2723356589922901]},"#88aadd":{"lch":[68.8982708583434,50.1120766914241216,248.506358436024811],"luv":[68.8982708583434,-18.3609632112572676,-46.6271944285953168],"rgb":[0.533333333333333326,0.66666666666666663,0.866666666666666696],"xyz":[0.375769680475495915,0.392032946942316218,0.739960074052911],"hpluv":[248.506358436024811,92.2939864083951278,68.8982708583434],"hsluv":[248.506358436024811,59.5109742880650217,68.8982708583434]},"#88aaee":{"lch":[69.5803420919898,63.9362726255054454,253.044423586561948],"luv":[69.5803420919898,-18.6457452648911577,-61.1570367231747554],"rgb":[0.533333333333333326,0.66666666666666663,0.933333333333333348],"xyz":[0.39958186074167068,0.401557819048786235,0.8653708901214342],"hpluv":[253.044423586561948,116.600410917186778,69.5803420919898],"hsluv":[253.044423586561948,79.2673662112875093,69.5803420919898]},"#88aaff":{"lch":[70.3176511000829549,77.916964899147743,255.928474825822],"luv":[70.3176511000829549,-18.9441834980668631,-75.578907974954177],"rgb":[0.533333333333333326,0.66666666666666663,1],"xyz":[0.425752909151502046,0.412026238412718959,1.00320507841321604],"hpluv":[255.928474825822,140.607018245256825,70.3176511000829549],"hsluv":[255.928474825822,99.9999999999979394,70.3176511000829549]},"#332200":{"lch":[14.6681357538016819,18.4720509904151484,54.0318728094203635],"luv":[14.6681357538016819,10.8492842291989344,14.9502407842332925],"rgb":[0.2,0.133333333333333331,0],"xyz":[0.0193721251413763347,0.0184794126446342424,0.00254661690643579732],"hpluv":[54.0318728094203635,159.801011716648361,14.6681357538016819],"hsluv":[54.0318728094203635,100.000000000002359,14.6681357538016819]},"#332211":{"lch":[14.8903804788128475,14.003495227987683,44.8263438888978243],"luv":[14.8903804788128475,9.93193249146711,9.87190941941900668],"rgb":[0.2,0.133333333333333331,0.0666666666666666657],"xyz":[0.0203837906410134564,0.0188840788444890953,0.00787472187119143],"hpluv":[44.8263438888978243,119.33558852926538,14.8903804788128475],"hsluv":[44.8263438888978243,67.0844803779226595,14.8903804788128475]},"#332222":{"lch":[15.2941064614028619,8.70381909014442101,12.1770506300622809],"luv":[15.2941064614028619,8.50798716741232397,1.83592513820952408],"rgb":[0.2,0.133333333333333331,0.133333333333333331],"xyz":[0.0222591487794904751,0.0196342220998799166,0.0177516080671706253],"hpluv":[12.1770506300622809,72.2146104972558476,15.2941064614028619],"hsluv":[12.1770506300622809,16.9221215783466867,15.2941064614028619]},"#332233":{"lch":[15.9369990430381634,10.9638268591401484,307.7150129492465],"luv":[15.9369990430381634,6.70694938589646661,-8.67308072902737],"rgb":[0.2,0.133333333333333331,0.2],"xyz":[0.0253468995119482156,0.0208693223928630295,0.0340137619247817685],"hpluv":[307.7150129492465,87.2961214462547,15.9369990430381634],"hsluv":[307.7150129492465,30.2017993044426838,15.9369990430381634]},"#332244":{"lch":[16.8218835175385664,20.7382675483863608,283.478697838556343],"luv":[16.8218835175385664,4.83375477674434428,-20.1670661145035197],"rgb":[0.2,0.133333333333333331,0.266666666666666663],"xyz":[0.0298048947561670927,0.0226525204905506025,0.057492536877668407],"hpluv":[283.478697838556343,156.436171283708973,16.8218835175385664],"hsluv":[283.478697838556343,43.2894908809756558,16.8218835175385664]},"#332255":{"lch":[17.9355503164319856,31.8518286021958055,275.537546938931484],"luv":[17.9355503164319856,3.0736387963894658,-31.7031816992078603],"rgb":[0.2,0.133333333333333331,0.333333333333333315],"xyz":[0.0357673087955290847,0.0250374861062954354,0.0888945841516423224],"hpluv":[275.537546938931484,225.350740722061715,17.9355503164319856],"hsluv":[275.537546938931484,54.6600619512456092,17.9355503164319856]},"#332266":{"lch":[19.2543827660255502,42.9346801988288,271.988815040461645],"luv":[19.2543827660255502,1.49002234071320738,-42.9088172430781114],"rgb":[0.2,0.133333333333333331,0.4],"xyz":[0.043352304569037263,0.028071484415698747,0.12884222855878627],"hpluv":[271.988815040461645,282.955381276792764,19.2543827660255502],"hsluv":[271.988815040461645,63.8744485302889515,19.2543827660255502]},"#332277":{"lch":[20.7496984269819,53.7295137018198687,270.083996688769219],"luv":[20.7496984269819,0.0787684479011579453,-53.7294559637975908],"rgb":[0.2,0.133333333333333331,0.466666666666666674],"xyz":[0.0526663175892391755,0.0317970896237795633,0.17789603046518418],"hpluv":[270.083996688769219,328.579487011522247,20.7496984269819],"hsluv":[270.083996688769219,71.0892762838988546,20.7496984269819]},"#332288":{"lch":[22.3919640579388926,64.2366699579867,268.940142222195846],"luv":[22.3919640579388926,-1.18818265954209568,-64.2256801385464087],"rgb":[0.2,0.133333333333333331,0.533333333333333326],"xyz":[0.063806734691183,0.0362532564645571542,0.236568893868756347],"hpluv":[268.940142222195846,364.024117005976393,22.3919640579388926],"hsluv":[268.940142222195846,76.6637840765232426,22.3919640579388926]},"#332299":{"lch":[24.1535324867621668,74.5121507797046689,268.199285594367666],"luv":[24.1535324867621668,-2.34141182983712737,-74.4753543426316469],"rgb":[0.2,0.133333333333333331,0.6],"xyz":[0.076863698800255717,0.0414760421081863187,0.305335571509874282],"hpluv":[268.199285594367666,391.458538227207669,24.1535324867621668],"hsluv":[268.199285594367666,80.9654036049547301,24.1535324867621668]},"#3322aa":{"lch":[26.0100477302332607,84.6098540849434926,267.692459882235937],"luv":[26.0100477302332607,-3.40667075751279169,-84.541244387726735],"rgb":[0.2,0.133333333333333331,0.66666666666666663],"xyz":[0.0919213917655082591,0.0474991192942874202,0.384639421126872882],"hpluv":[267.692459882235937,412.780453116303818,26.0100477302332607],"hsluv":[267.692459882235937,84.3023702715129,26.0100477302332607]},"#3322bb":{"lch":[27.9408960039881222,94.5690254119923281,267.330995248517297],"luv":[27.9408960039881222,-4.40370835341661504,-94.4664380619492761],"rgb":[0.2,0.133333333333333331,0.733333333333333282],"xyz":[0.109058983872844906,0.0543541561372221788,0.474897406225514629],"hpluv":[267.330995248517297,429.484911570580266,27.9408960039881222],"hsluv":[267.330995248517297,86.9134730370406743,27.9408960039881222]},"#3322cc":{"lch":[29.9290875828623939,104.415306333233346,267.064581258752071],"luv":[29.9290875828623939,-5.34714045276937444,-104.278302084572317],"rgb":[0.2,0.133333333333333331,0.8],"xyz":[0.12835135931656666,0.0620711063147109804,0.576503916895784729],"hpluv":[267.064581258752071,442.700503900749,29.9290875828623939],"hsluv":[267.064581258752071,88.9774620844202389,29.9290875828623939]},"#3322dd":{"lch":[31.9608605817263296,114.164622106097937,266.862904678446171],"luv":[31.9608605817263296,-6.2476920173399213,-113.993540541052639],"rgb":[0.2,0.133333333333333331,0.866666666666666696],"xyz":[0.149869684867200204,0.0706784365349645144,0.689833764795790727],"hpluv":[266.862904678446171,453.265229710644405,31.9608605817263296],"hsluv":[266.862904678446171,90.6264253960307826,31.9608605817263296]},"#3322ee":{"lch":[34.0251904593745635,123.826689560879501,266.706806867468629],"luv":[34.0251904593745635,-7.11327635006579229,-123.622208147136817],"rgb":[0.2,0.133333333333333331,0.933333333333333348],"xyz":[0.173681865133374941,0.0802033086414345453,0.815244580864314],"hpluv":[266.706806867468629,461.799038215803307,34.0251904593745635],"hsluv":[266.706806867468629,93.6430785136650741,34.0251904593745635]},"#3322ff":{"lch":[36.1133053940478774,133.407509730883817,266.583697157343806],"luv":[36.1133053940478774,-7.94980801741223875,-133.170432923686747],"rgb":[0.2,0.133333333333333331,1],"xyz":[0.199852913543206334,0.0906717280053672414,0.953078769156095795],"hpluv":[266.583697157343806,468.761962088723578,36.1133053940478774],"hsluv":[266.583697157343806,99.999999999999531,36.1133053940478774]},"#aaaa00":{"lch":[67.4983691984715506,74.4102446110960472,85.8743202181747449],"luv":[67.4983691984715506,5.35340686476390193,74.217420717938225],"rgb":[0.66666666666666663,0.66666666666666663,0],"xyz":[0.309512896760441802,0.372958073182539818,0.0556842125390607443],"hpluv":[85.8743202181747449,139.887458074797593,67.4983691984715506],"hsluv":[85.8743202181747449,100.000000000002373,67.4983691984715506]},"#aaaa11":{"lch":[67.528557359020084,73.1276023311446863,85.8743202181746881],"luv":[67.528557359020084,5.26112782412359792,72.9381022286724345],"rgb":[0.66666666666666663,0.66666666666666663,0.0666666666666666657],"xyz":[0.310524562260078907,0.373362739382394671,0.061012317503816374],"hpluv":[85.8743202181746881,137.414698385368666,67.528557359020084],"hsluv":[85.8743202181746881,98.2323220941626118,67.528557359020084]},"#aaaa22":{"lch":[67.5844605157977,70.7729399531690575,85.8743202181746],"luv":[67.5844605157977,5.09172284764045369,70.589541633712912],"rgb":[0.66666666666666663,0.66666666666666663,0.133333333333333331],"xyz":[0.312399920398555964,0.374112882637785471,0.0708892036997955666],"hpluv":[85.8743202181746,132.880028295953878,67.5844605157977],"hsluv":[85.8743202181746,94.9906661574379854,67.5844605157977]},"#aaaa33":{"lch":[67.6763416895574181,66.9597491826677924,85.8743202181744607],"luv":[67.6763416895574181,4.81738479440415723,66.7862322215321882],"rgb":[0.66666666666666663,0.66666666666666663,0.2],"xyz":[0.315487671131013669,0.375347982930768598,0.0871513575574067167],"hpluv":[85.8743202181744607,125.549870841925909,67.6763416895574181],"hsluv":[85.8743202181744607,89.7506270896691376,67.6763416895574181]},"#aaaa44":{"lch":[67.8086418759902898,61.5895608625658824,85.8743202181741623],"luv":[67.8086418759902898,4.43102935143870269,61.429960004304057],"rgb":[0.66666666666666663,0.66666666666666663,0.266666666666666663],"xyz":[0.319945666375232585,0.377131181028456164,0.110630132510293355],"hpluv":[85.8743202181741623,115.255428047766188,67.8086418759902898],"hsluv":[85.8743202181741623,82.3915379076671854,67.8086418759902898]},"#aaaa55":{"lch":[67.9849384953625844,54.6449851984581514,85.8743202181737786],"luv":[67.9849384953625844,3.93140541890911,54.5033802508787772],"rgb":[0.66666666666666663,0.66666666666666663,0.333333333333333315],"xyz":[0.32590808041459457,0.379516146644201,0.142032179784267271],"hpluv":[85.8743202181737786,101.994541545207838,67.9849384953625844],"hsluv":[85.8743202181737786,72.9118556794948631,67.9849384953625844]},"#aaaa66":{"lch":[68.2081473948541515,46.1798212544818156,85.8743202181731675],"luv":[68.2081473948541515,3.32238354287766668,46.0601526125338268],"rgb":[0.66666666666666663,0.66666666666666663,0.4],"xyz":[0.333493076188102755,0.382550144953604343,0.181979824191411232],"hpluv":[85.8743202181731675,85.9122949373369806,68.2081473948541515],"hsluv":[85.8743202181731675,61.415294923296095,68.2081473948541515]},"#aaaa77":{"lch":[68.4806287458147551,36.3079853189649668,85.874320218171988],"luv":[68.4806287458147551,2.61215937225179973,36.2138981792368284],"rgb":[0.66666666666666663,0.66666666666666663,0.466666666666666674],"xyz":[0.342807089208304661,0.386275750161685139,0.231033626097809142],"hpluv":[85.874320218171988,67.2781031791916604,68.4806287458147551],"hsluv":[85.874320218171988,48.0944497134402909,68.4806287458147551]},"#aaaa88":{"lch":[68.804250183835336,25.1900382005990835,85.8743202181696574],"luv":[68.804250183835336,1.81228437202058101,25.1247616884732103],"rgb":[0.66666666666666663,0.66666666666666663,0.533333333333333326],"xyz":[0.353947506310248461,0.390731917002462736,0.289706489501381281],"hpluv":[85.8743202181696574,46.4571845078746506,68.804250183835336],"hsluv":[85.8743202181696574,33.210400093935057,68.804250183835336]},"#aaaa99":{"lch":[69.1804292601881485,13.0180161266067085,85.8743202181625236],"luv":[69.1804292601881485,0.936574490007753058,12.9842817320504498],"rgb":[0.66666666666666663,0.66666666666666663,0.6],"xyz":[0.36700447041932116,0.395954702646091894,0.358473167142499216],"hpluv":[85.8743202181625236,23.8781611725121081,69.1804292601881485],"hsluv":[85.8743202181625236,17.0695511242654057,69.1804292601881485]},"#aaaaaa":{"lch":[69.6101658300367916,3.6866289517569387e-12,0],"luv":[69.6101658300367916,3.46613397703382525e-12,1.25584564385283521e-12],"rgb":[0.66666666666666663,0.66666666666666663,0.66666666666666663],"xyz":[0.382062163384573716,0.401977779832193,0.437777016759497817],"hpluv":[0,6.72041492281092149e-12,69.6101658300367916],"hsluv":[0,4.48262290109626775e-12,69.6101658300367916]},"#aaaabb":{"lch":[70.0940699613229441,13.6540669730780309,265.874320218191428],"luv":[70.0940699613229441,-0.982334841759501587,-13.618684340418703],"rgb":[0.66666666666666663,0.66666666666666663,0.733333333333333282],"xyz":[0.399199755491910391,0.408832816675127775,0.528035001858139563],"hpluv":[265.874320218191428,24.7183841606301087,70.0940699613229441],"hsluv":[265.874320218191428,17.6184615311656536,70.0940699613229441]},"#aaaacc":{"lch":[70.6323884029978188,27.7441307883788433,265.87432021818438],"luv":[70.6323884029978188,-1.99603725260327192,-27.6722356973355303],"rgb":[0.66666666666666663,0.66666666666666663,0.8],"xyz":[0.41849213093563209,0.416549766852616576,0.629641512528409719],"hpluv":[265.87432021818438,49.8432735452352063,70.6323884029978188],"hsluv":[265.87432021818438,36.467826786828347,70.6323884029978188]},"#aaaadd":{"lch":[71.2250312240615813,42.0886841218373817,265.874320218182],"luv":[71.2250312240615813,-3.02804878123905441,-41.979617097899343],"rgb":[0.66666666666666663,0.66666666666666663,0.866666666666666696],"xyz":[0.440010456486265689,0.425157097072870083,0.742971360428415717],"hpluv":[265.874320218182,74.9845908684596,71.2250312240615813],"hsluv":[265.874320218182,56.4865697219014891,71.2250312240615813]},"#aaaaee":{"lch":[71.8715993709786432,56.5301989351418541,265.874320218180742],"luv":[71.8715993709786432,-4.0670361537863835,-56.3837087159979902],"rgb":[0.66666666666666663,0.66666666666666663,0.933333333333333348],"xyz":[0.463822636752440398,0.4346819691793401,0.86838217649693894],"hpluv":[265.874320218180742,99.8073514218055,71.8715993709786432],"hsluv":[265.874320218180742,77.6546881169827259,71.8715993709786432]},"#aaaaff":{"lch":[72.5714133442747595,70.9376272522327,265.87432021818006],"luv":[72.5714133442747595,-5.10357119085512778,-70.7538021683399],"rgb":[0.66666666666666663,0.66666666666666663,1],"xyz":[0.489993685162271819,0.445150388543272824,1.00621636478872079],"hpluv":[265.87432021818006,124.036757123492009,72.5714133442747595],"hsluv":[265.87432021818006,99.999999999997641,72.5714133442747595]},"#88bb00":{"lch":[70.0174964893220135,84.793654921948729,107.670265811619984],"luv":[70.0174964893220135,-25.7381496181260658,80.7930168347331659],"rgb":[0.533333333333333326,0.733333333333333282,0],"xyz":[0.279226618658270809,0.407742918869184512,0.0639910921330886],"hpluv":[107.670265811619984,153.672481251000221,70.0174964893220135],"hsluv":[107.670265811619984,100.000000000002288,70.0174964893220135]},"#88bb11":{"lch":[70.045943224524,83.6147085810298,107.921872667069366],"luv":[70.045943224524,-25.7299069713944561,79.5574721715938296],"rgb":[0.533333333333333326,0.733333333333333282,0.0666666666666666657],"xyz":[0.280238284157907913,0.408147585069039365,0.0693191970978442318],"hpluv":[107.921872667069366,151.474322676164348,70.045943224524],"hsluv":[107.921872667069366,98.3704135852689,70.045943224524]},"#88bb22":{"lch":[70.0986261940145567,81.4532385975490172,108.403169751544382],"luv":[70.0986261940145567,-25.7149121100318041,77.2876016784231],"rgb":[0.533333333333333326,0.733333333333333282,0.133333333333333331],"xyz":[0.28211364229638497,0.408897728324430165,0.0791960832938234244],"hpluv":[108.403169751544382,147.447759071005407,70.0986261940145567],"hsluv":[108.403169751544382,95.3794817356858431,70.0986261940145567]},"#88bb33":{"lch":[70.185227758130182,77.9617926087192643,109.240455548552404],"luv":[70.185227758130182,-25.6910124331637526,73.6071530961765887],"rgb":[0.533333333333333326,0.733333333333333282,0.2],"xyz":[0.285201393028842676,0.410132828617413292,0.0954582371514345607],"hpluv":[109.240455548552404,140.95335886915251,70.185227758130182],"hsluv":[109.240455548552404,90.5378353052476399,70.185227758130182]},"#88bb44":{"lch":[70.3099541281250708,73.067556170236557,110.558097475340105],"luv":[70.3099541281250708,-25.6581823155790048,68.4143657790612281],"rgb":[0.533333333333333326,0.733333333333333282,0.266666666666666663],"xyz":[0.289659388273061591,0.411916026715100858,0.118937012104321199],"hpluv":[110.558097475340105,131.870330314080604,70.3099541281250708],"hsluv":[110.558097475340105,83.7238240635208655,70.3099541281250708]},"#88bb55":{"lch":[70.4762099132372,66.7907607981454845,112.553407091589676],"luv":[70.4762099132372,-25.6172250438111178,61.682765089203194],"rgb":[0.533333333333333326,0.733333333333333282,0.333333333333333315],"xyz":[0.295621802312423576,0.414300992330845719,0.150339059378295115],"hpluv":[112.553407091589676,120.257778383662554,70.4762099132372],"hsluv":[112.553407091589676,74.9213657205140606,70.4762099132372]},"#88bb66":{"lch":[70.6867901559138687,59.2534136994931373,115.564788197424377],"luv":[70.6867901559138687,-25.56971066242372,53.4523800375924836],"rgb":[0.533333333333333326,0.733333333333333282,0.4],"xyz":[0.303206798085931761,0.417334990640249037,0.190286703785439076],"hpluv":[115.564788197424377,106.368844477737383,70.6867901559138687],"hsluv":[115.564788197424377,64.2082802413586791,70.6867901559138687]},"#88bb77":{"lch":[70.9439811929011483,50.7088031944788611,120.213509646437856],"luv":[70.9439811929011483,-25.5178724843925657,43.8203252530908287],"rgb":[0.533333333333333326,0.733333333333333282,0.466666666666666674],"xyz":[0.312520811106133667,0.421060595848329833,0.239340505691836986],"hpluv":[120.213509646437856,90.6999673798200519,70.9439811929011483],"hsluv":[120.213509646437856,51.7430673824667338,70.9439811929011483]},"#88bb88":{"lch":[71.2496205680497781,41.6266624709187667,127.715012949237462],"luv":[71.2496205680497781,-25.4644588867656232,32.9293237414924747],"rgb":[0.533333333333333326,0.733333333333333282,0.533333333333333326],"xyz":[0.323661228208077467,0.425516762689107431,0.298013369095409153],"hpluv":[127.715012949237462,74.1358655131278397,71.2496205680497781],"hsluv":[127.715012949237462,37.7483692132655,71.2496205680497781]},"#88bb99":{"lch":[71.605136773449729,32.9376822973712677,140.491872589160209],"luv":[71.605136773449729,-25.4125532319559895,20.9545473192710077],"rgb":[0.533333333333333326,0.733333333333333282,0.6],"xyz":[0.336718192317150167,0.430739548332736588,0.366780046736527088],"hpluv":[140.491872589160209,58.3697971606621948,71.605136773449729],"hsluv":[140.491872589160209,40.0947707109065163,71.605136773449729]},"#88bbaa":{"lch":[72.0115788449514298,26.624214972975043,162.310745910586235],"luv":[72.0115788449514298,-25.3653817896029707,8.0898843993512255],"rgb":[0.533333333333333326,0.733333333333333282,0.66666666666666663],"xyz":[0.351775885282402723,0.43676262551883771,0.446083896353525633],"hpluv":[162.310745910586235,46.9152251525928463,72.0115788449514298],"hsluv":[162.310745910586235,42.5902472855224445,72.0115788449514298]},"#88bbbb":{"lch":[72.4696411221425478,25.9090725846495289,192.177050630060563],"luv":[72.4696411221425478,-25.3261303787159093,-5.46508574835939687],"rgb":[0.533333333333333326,0.733333333333333282,0.733333333333333282],"xyz":[0.368913477389739397,0.443617662361772469,0.536341881452167435],"hpluv":[192.177050630060563,45.3664800039612786,72.4696411221425478],"hsluv":[192.177050630060563,45.1889022919971595,72.4696411221425478]},"#88bbcc":{"lch":[72.9796861172365539,31.9509756483125074,217.648879320727843],"luv":[72.9796861172365539,-25.297786835453639,-19.5163220435359541],"rgb":[0.533333333333333326,0.733333333333333282,0.8],"xyz":[0.388205852833461096,0.451334612539261271,0.637948392122437591],"hpluv":[217.648879320727843,55.5547835161394303,72.9796861172365539],"hsluv":[217.648879320727843,47.846459663484211,72.9796861172365539]},"#88bbdd":{"lch":[73.5417671198988501,42.2771793498237827,233.271065498294831],"luv":[73.5417671198988501,-25.2830202693059967,-33.8840490472881442],"rgb":[0.533333333333333326,0.733333333333333282,0.866666666666666696],"xyz":[0.409724178384094695,0.459941942759514777,0.751278240022443589],"hpluv":[233.271065498294831,72.9476439375157781,73.5417671198988501],"hsluv":[233.271065498294831,52.600286903313318,73.5417671198988501]},"#88bbee":{"lch":[74.1556513704433655,54.6140049995012049,242.42172167609948],"luv":[74.1556513704433655,-25.2841013367454792,-48.4087157615106349],"rgb":[0.533333333333333326,0.733333333333333282,0.933333333333333348],"xyz":[0.433536358650269404,0.469466814865984794,0.876689056090966812],"hpluv":[242.42172167609948,93.4542589851821646,74.1556513704433655],"hsluv":[242.42172167609948,75.5983078602269387,74.1556513704433655]},"#88bbff":{"lch":[74.8208441285393206,67.8489412305869877,248.103607922481928],"luv":[74.8208441285393206,-25.3028619495915343,-62.9543009116260492],"rgb":[0.533333333333333326,0.733333333333333282,1],"xyz":[0.459707407060100826,0.479935234229917518,1.01452324438274855],"hpluv":[248.103607922481928,115.069386567942303,74.8208441285393206],"hsluv":[248.103607922481928,99.9999999999973568,74.8208441285393206]},"#333300":{"lch":[20.3279441284931792,22.4095383785379596,85.8743202181747449],"luv":[20.3279441284931792,1.61224273913978733,22.3514671484727536],"rgb":[0.2,0.2,0],"xyz":[0.0254898472303871464,0.0307148568226560392,0.00458585760277267773],"hpluv":[85.8743202181747449,139.887458074797735,20.3279441284931792],"hsluv":[85.8743202181747449,100.000000000002458,20.3279441284931792]},"#333311":{"lch":[20.4867879892499971,17.9332091798965507,85.8743202181741],"luv":[20.4867879892499971,1.2901955319819518,17.8867377399899183],"rgb":[0.2,0.2,0.0666666666666666657],"xyz":[0.0265015127300242681,0.0311195230225108921,0.00991396256752831],"hpluv":[85.8743202181741,111.076827622251201,20.4867879892499971],"hsluv":[85.8743202181741,79.4044220625277717,20.4867879892499971]},"#333322":{"lch":[20.7776374982028358,10.4602453251552614,85.8743202181717749],"luv":[20.7776374982028358,0.752556982220839221,10.4331390411008691],"rgb":[0.2,0.2,0.133333333333333331],"xyz":[0.0283768708685012867,0.0318696662779017134,0.019790848763507507],"hpluv":[85.8743202181717749,63.8829601302186703,20.7776374982028358],"hsluv":[85.8743202181717749,45.6673964981637113,20.7776374982028358]},"#333333":{"lch":[21.246731294981295,1.12524964979295229e-12,0],"luv":[21.246731294981295,1.05794917113478783e-12,3.83314917077821647e-13],"rgb":[0.2,0.2,0.2],"xyz":[0.0314646216009590307,0.0331047665708848263,0.0360530026211186502],"hpluv":[0,6.72041492281092149e-12,21.246731294981295],"hsluv":[0,1.92419399944792236e-12,21.246731294981295]},"#333344":{"lch":[21.9038391599933462,12.2084714240410825,265.874320218182163],"luv":[21.9038391599933462,-0.878332211796974,-12.176834853004598],"rgb":[0.2,0.2,0.266666666666666663],"xyz":[0.0359226168451779043,0.0348879646685724,0.0595317775740052887],"hpluv":[265.874320218182163,70.7262082967351517,21.9038391599933462],"hsluv":[265.874320218182163,13.7757030029577514,21.9038391599933462]},"#333355":{"lch":[22.7485838486986935,25.0264321710322868,265.874320218179776],"luv":[22.7485838486986935,-1.80051382017376982,-24.9615796213830023],"rgb":[0.2,0.2,0.333333333333333315],"xyz":[0.0418850308845399,0.0372729302843172322,0.0909338248479792],"hpluv":[265.874320218179776,139.599512106194084,22.7485838486986935],"hsluv":[265.874320218179776,27.1905063829271256,22.7485838486986935]},"#333366":{"lch":[23.7726526978294,37.7235732610660364,265.874320218179],"luv":[23.7726526978294,-2.71400312032964841,-37.625817820292724],"rgb":[0.2,0.2,0.4],"xyz":[0.0494700266580480746,0.0403069285937205438,0.130881469255123173],"hpluv":[265.874320218179,201.360603518100845,23.7726526978294],"hsluv":[265.874320218179,39.2200280117306193,23.7726526978294]},"#333377":{"lch":[24.9621315786770737,49.9646270765614062,265.874320218178639],"luv":[24.9621315786770737,-3.59467945556105306,-49.8351506319748268],"rgb":[0.2,0.2,0.466666666666666674],"xyz":[0.0587840396782499941,0.0440325338018013601,0.179935271161521082],"hpluv":[265.874320218178639,253.992158426909725,24.9621315786770737],"hsluv":[265.874320218178639,49.4713434217918646,24.9621315786770737]},"#333388":{"lch":[26.2997861111378413,61.6680265106551175,265.874320218178468],"luv":[26.2997861111378413,-4.43667452222106906,-61.5082223194812912],"rgb":[0.2,0.2,0.533333333333333326],"xyz":[0.0699244567801938222,0.048488700642578958,0.238608134565093222],"hpluv":[265.874320218178468,297.541234413863208,26.2997861111378413],"hsluv":[265.874320218178468,57.953618257344317,26.2997861111378413]},"#333399":{"lch":[27.7670269025285634,72.8744236647892336,265.874320218178354],"luv":[27.7670269025285634,-5.24291301488723782,-72.6855796399362788],"rgb":[0.2,0.2,0.6],"xyz":[0.0829814208892665356,0.0537114862862081155,0.307374812206211157],"hpluv":[265.874320218178354,333.031319879373427,27.7670269025285634],"hsluv":[265.874320218178354,64.8662025552495862,27.7670269025285634]},"#3333aa":{"lch":[29.34539826905295,83.6653121043175361,265.874320218178241],"luv":[29.34539826905295,-6.01925794630032573,-83.4485049793509575],"rgb":[0.2,0.2,0.66666666666666663],"xyz":[0.0980391138545190777,0.059734563472309217,0.386678661823209757],"hpluv":[265.874320218178241,361.780166220798492,29.34539826905295],"hsluv":[265.874320218178241,70.4657614516561353,29.34539826905295]},"#3333bb":{"lch":[31.0175640968910713,94.1237197643615247,265.874320218178184],"luv":[31.0175640968910713,-6.77168271864664284,-93.8798111173964855],"rgb":[0.2,0.2,0.733333333333333282],"xyz":[0.115176705961855724,0.0665896003152439686,0.476936646921851504],"hpluv":[265.874320218178184,385.062051502536349,31.0175640968910713],"hsluv":[265.874320218178184,75.0004925607309758,31.0175640968910713]},"#3333cc":{"lch":[32.7678589751368321,104.319620441623087,265.874320218178127],"luv":[32.7678589751368321,-7.50522156082274261,-104.049290523324899],"rgb":[0.2,0.2,0.8],"xyz":[0.134469081405577451,0.0743065504927327702,0.578543157592121604],"hpluv":[265.874320218178127,403.977575952485893,32.7678589751368321],"hsluv":[265.874320218178127,79.524052836351089,32.7678589751368321]},"#3333dd":{"lch":[34.5825131799139243,114.307143948468337,265.874320218178127],"luv":[34.5825131799139243,-8.22376881440244745,-114.010932739554079],"rgb":[0.2,0.2,0.866666666666666696],"xyz":[0.155987406956211,0.0829138807129863,0.691873005492127602],"hpluv":[265.874320218178127,419.426773039758132,34.5825131799139243],"hsluv":[265.874320218178127,86.1542613798901584,34.5825131799139243]},"#3333ee":{"lch":[36.4496605331747929,124.126383834434506,265.87432021817807],"luv":[36.4496605331747929,-8.93020898923314732,-123.80472741871364],"rgb":[0.2,0.2,0.933333333333333348],"xyz":[0.179799587222385732,0.092438752819456349,0.817283821560650825],"hpluv":[265.87432021817807,432.12554656995303,36.4496605331747929],"hsluv":[265.87432021817807,92.9362870993519,36.4496605331747929]},"#3333ff":{"lch":[38.3592184432327414,133.806417871427385,265.87432021817807],"luv":[38.3592184432327414,-9.62663407069321231,-133.45967698167118],"rgb":[0.2,0.2,1],"xyz":[0.205970635632217125,0.102907172183389045,0.95511800985243267],"hpluv":[265.87432021817807,442.635784237250618,38.3592184432327414],"hsluv":[265.87432021817807,99.99999999999946,38.3592184432327414]},"#aabb00":{"lch":[72.2864137555308162,81.0402066187271686,93.9104624709461291],"luv":[72.2864137555308162,-5.52673715975233737,80.8515322376329664],"rgb":[0.66666666666666663,0.733333333333333282,0],"xyz":[0.343467394669040582,0.440867068999738376,0.0670023785085933632],"hpluv":[93.9104624709461291,142.260125307220505,72.2864137555308162],"hsluv":[93.9104624709461291,100.00000000000226,72.2864137555308162]},"#aabb11":{"lch":[72.3134178153803759,79.8795424406406198,94.0047051989067199],"luv":[72.3134178153803759,-5.5786590117117969,79.6845020324350912],"rgb":[0.66666666666666663,0.733333333333333282,0.0666666666666666657],"xyz":[0.344479060168677687,0.441271735199593229,0.072330483473349],"hpluv":[94.0047051989067199,140.170301198642704,72.3134178153803759],"hsluv":[94.0047051989067199,98.4998030851846522,72.3134178153803759]},"#aabb22":{"lch":[72.3634325080893319,77.7463008610920667,94.1853407287125179],"luv":[72.3634325080893319,-5.67416055225396132,77.5389656857163],"rgb":[0.66666666666666663,0.733333333333333282,0.133333333333333331],"xyz":[0.346354418307154743,0.44202187845498403,0.0822073696693281925],"hpluv":[94.1853407287125179,136.332658010127801,72.3634325080893319],"hsluv":[94.1853407287125179,95.7441801677588131,72.3634325080893319]},"#aabb33":{"lch":[72.4456578556837343,74.284969405898,94.5007685828256427],"luv":[72.4456578556837343,-5.82932493434540167,74.0558954469191377],"rgb":[0.66666666666666663,0.733333333333333282,0.2],"xyz":[0.349442169039612449,0.443256978747967156,0.0984695235269393288],"hpluv":[94.5007685828256427,130.115164427369336,72.4456578556837343],"hsluv":[94.5007685828256427,91.2774770665997721,72.4456578556837343]},"#aabb44":{"lch":[72.5641031469497193,69.3968632274838768,95.0004815565242922],"luv":[72.5641031469497193,-6.04891620231322502,69.1327363742496317],"rgb":[0.66666666666666663,0.733333333333333282,0.266666666666666663],"xyz":[0.353900164283831364,0.445040176845654722,0.121948298479825967],"hpluv":[95.0004815565242922,121.354905136961719,72.5641031469497193],"hsluv":[95.0004815565242922,84.978619462346515,72.5641031469497193]},"#aabb55":{"lch":[72.7220260779140659,63.0543258899363366,95.7659530899235705],"luv":[72.7220260779140659,-6.33475857174489843,62.7353078200147181],"rgb":[0.66666666666666663,0.733333333333333282,0.333333333333333315],"xyz":[0.359862578323193349,0.447425142461399583,0.153350345753799883],"hpluv":[95.7659530899235705,110.024206089370551,72.7220260779140659],"hsluv":[95.7659530899235705,76.8198788639563475,72.7220260779140659]},"#aabb66":{"lch":[72.922116394456026,55.2958006214329245,96.9449007941817342],"luv":[72.922116394456026,-6.68608027099689206,54.8900892418207675],"rgb":[0.66666666666666663,0.733333333333333282,0.4],"xyz":[0.367447574096701535,0.450459140770802902,0.193297990160943844],"hpluv":[96.9449007941817342,96.2215198645611167,72.922116394456026],"hsluv":[96.9449007941817342,66.8569788454327778,72.922116394456026]},"#aabb77":{"lch":[73.1665925415562555,46.2248747385797927,98.8352478745929801],"luv":[73.1665925415562555,-7.09985217623529596,45.6763740206356488],"rgb":[0.66666666666666663,0.733333333333333282,0.466666666666666674],"xyz":[0.37676158711690344,0.454184745978883697,0.242351792067341754],"hpluv":[98.8352478745929801,80.1682197570307267,73.1665925415562555],"hsluv":[98.8352478745929801,55.2184354086421223,73.1665925415562555]},"#aabb88":{"lch":[73.4572589636137,36.0214199172978056,102.133241078873],"luv":[73.4572589636137,-7.57119112276486117,35.2167539367396216],"rgb":[0.66666666666666663,0.733333333333333282,0.533333333333333326],"xyz":[0.387902004218847241,0.458640912819661295,0.301024655470913949],"hpluv":[102.133241078873,62.2250760292602862,73.4572589636137],"hsluv":[102.133241078873,42.0922357464751116,73.4572589636137]},"#aabb99":{"lch":[73.7955437608147236,25.0118273668521454,108.880774444702425],"luv":[73.7955437608147236,-8.09382587885112592,23.6660408786948082],"rgb":[0.66666666666666663,0.733333333333333282,0.6],"xyz":[0.40095896832792,0.463863698463290453,0.369791333112031828],"hpluv":[108.880774444702425,43.0085312761643337,73.7955437608147236],"hsluv":[108.880774444702425,27.7101400322224,73.7955437608147236]},"#aabbaa":{"lch":[74.1825262226786464,14.1574418893213867,127.715012949227386],"luv":[74.1825262226786464,-8.66059336811296632,11.1994322785447302],"rgb":[0.66666666666666663,0.733333333333333282,0.66666666666666663],"xyz":[0.416016661293172496,0.469886775649391575,0.449095182729030429],"hpluv":[127.715012949227386,24.2171200924073027,74.1825262226786464],"hsluv":[127.715012949227386,12.3308304853939106,74.1825262226786464]},"#aabbbb":{"lch":[74.6189593067414734,9.47715438031144153,192.177050630059],"luv":[74.6189593067414734,-9.26392276955498417,-1.99904729008021675],"rgb":[0.66666666666666663,0.733333333333333282,0.733333333333333282],"xyz":[0.43315425340050917,0.476741812492326333,0.539353167827672175],"hpluv":[192.177050630059,16.1164020856357908,74.6189593067414734],"hsluv":[192.177050630059,16.0533177597809029,74.6189593067414734]},"#aabbcc":{"lch":[75.1052899078477623,18.5983929047544514,237.852316168687679],"luv":[75.1052899078477623,-9.89626817417043547,-15.7468757175676597],"rgb":[0.66666666666666663,0.733333333333333282,0.8],"xyz":[0.452446628844230925,0.484458762669815135,0.640959678497942331],"hpluv":[237.852316168687679,31.4227520087917149,75.1052899078477623],"hsluv":[237.852316168687679,25.8004515395991127,75.1052899078477623]},"#aabbdd":{"lch":[75.6416785331857682,31.6798915222297,250.547006926215033],"luv":[75.6416785331857682,-10.5504613433008458,-29.8714461033234144],"rgb":[0.66666666666666663,0.733333333333333282,0.866666666666666696],"xyz":[0.473964954394864413,0.493066092890068641,0.754289526397948329],"hpluv":[250.547006926215033,53.1449318902714438,75.6416785331857682],"hsluv":[250.547006926215033,48.9122949421499484,75.6416785331857682]},"#aabbee":{"lch":[76.2280192594463699,45.6175545861468166,255.761586302643195],"luv":[76.2280192594463699,-11.2199701465387403,-44.2162137267639],"rgb":[0.66666666666666663,0.733333333333333282,0.933333333333333348],"xyz":[0.497777134661039178,0.502590964996538658,0.879700342466471552],"hpluv":[255.761586302643195,76.8288153841444483,76.2280192594463699],"hsluv":[255.761586302643195,73.6249760737912311,76.2280192594463699]},"#aabbff":{"lch":[76.863960378353255,59.8395450787859247,258.530312903596609],"luv":[76.863960378353255,-11.8990616804050067,-58.6445520603744583],"rgb":[0.66666666666666663,0.733333333333333282,1],"xyz":[0.523948183070870543,0.513059384360471382,1.01753453075825329],"hpluv":[258.530312903596609,104.151140840900069,76.863960378353255],"hsluv":[258.530312903596609,99.9999999999969305,76.863960378353255]},"#88cc00":{"lch":[75.0884647575288,93.9986167747887,111.475410134903882],"luv":[75.0884647575288,-34.413070492851,87.4727416674912348],"rgb":[0.533333333333333326,0.8,0],"xyz":[0.317450361967887784,0.484190405488419406,0.0767323399029605363],"hpluv":[111.475410134903882,158.85012628624969,75.0884647575288],"hsluv":[111.475410134903882,100.000000000002288,75.0884647575288]},"#88cc11":{"lch":[75.1138336746799,92.9472917959209752,111.713770271434171],"luv":[75.1138336746799,-34.3877142984514421,86.3520941119794685],"rgb":[0.533333333333333326,0.8,0.0666666666666666657],"xyz":[0.318462027467524889,0.484595071688274259,0.082060444867716173],"hpluv":[111.713770271434171,157.020421425354783,75.1138336746799],"hsluv":[111.713770271434171,98.6248626695712289,75.1138336746799]},"#88cc22":{"lch":[75.1608235532889495,91.0175657840787551,112.166724150973],"luv":[75.1608235532889495,-34.3412008388942667,84.2904455214339805],"rgb":[0.533333333333333326,0.8,0.133333333333333331],"xyz":[0.320337385606001945,0.48534521494366506,0.0919373310636953656],"hpluv":[112.166724150973,153.664310911800271,75.1608235532889495],"hsluv":[112.166724150973,96.0970283406349,75.1608235532889495]},"#88cc33":{"lch":[75.2380863503033908,87.8942550668024865,112.94545296029041],"luv":[75.2380863503033908,-34.2659803117460342,80.9397471396048331],"rgb":[0.533333333333333326,0.8,0.2],"xyz":[0.323425136338459651,0.486580315236648187,0.108199484921306516],"hpluv":[112.94545296029041,148.2388630129999,75.2380863503033908],"hsluv":[112.94545296029041,91.9942509365254324,75.2380863503033908]},"#88cc44":{"lch":[75.3494055810326415,83.5027286146262,114.147802574759467],"luv":[75.3494055810326415,-34.1602904869016655,76.1956707427555244],"rgb":[0.533333333333333326,0.8,0.266666666666666663],"xyz":[0.327883131582678566,0.488363513334335753,0.131678259874193154],"hpluv":[114.147802574759467,140.624231819797672,75.3494055810326415],"hsluv":[114.147802574759467,86.1974134191241177,75.3494055810326415]},"#88cc55":{"lch":[75.4978684165763241,77.8461227965530469,115.917002828128631],"luv":[75.4978684165763241,-34.0241050685150555,70.0169915716368365],"rgb":[0.533333333333333326,0.8,0.333333333333333315],"xyz":[0.333845545622040552,0.490748478950080613,0.16308030714816707],"hpluv":[115.917002828128631,130.840327774204638,75.4978684165763241],"hsluv":[115.917002828128631,78.6694108520956092,75.4978684165763241]},"#88cc66":{"lch":[75.6860396561484663,71.0106875190110287,118.477611184333398],"luv":[75.6860396561484663,-33.8589835890750237,62.4186428259808963],"rgb":[0.533333333333333326,0.8,0.4],"xyz":[0.341430541395548737,0.493782477259483932,0.203027951555311],"hpluv":[118.477611184333398,119.054896833398359,75.6860396561484663],"hsluv":[118.477611184333398,69.4467240035668141,75.6860396561484663]},"#88cc77":{"lch":[75.9160535408259705,63.1826013081171638,122.199343200922883],"luv":[75.9160535408259705,-33.6678964132470924,53.4650713940171656],"rgb":[0.533333333333333326,0.8,0.466666666666666674],"xyz":[0.350744554415750642,0.497508082467564727,0.252081753461708913],"hpluv":[122.199343200922883,105.609553255175555,75.9160535408259705],"hsluv":[122.199343200922883,58.6308874961384063,75.9160535408259705]},"#88cc88":{"lch":[76.1896681333118124,54.6887581458639929,127.715012949238314],"luv":[76.1896681333118124,-33.4549913615237,43.2622678616965288],"rgb":[0.533333333333333326,0.8,0.533333333333333326],"xyz":[0.361884971517694443,0.50196424930834227,0.310754616865281108],"hpluv":[127.715012949238314,91.92606633748386,76.1896681333118124],"hsluv":[127.715012949238314,46.3779062484352878,76.1896681333118124]},"#88cc99":{"lch":[76.5083007543168492,46.0935908553499587,136.122445502284393],"luv":[76.5083007543168492,-33.2253063874269188,31.9483666781575764],"rgb":[0.533333333333333326,0.8,0.6],"xyz":[0.374941935626767142,0.507187034951971483,0.379521294506399],"hpluv":[136.122445502284393,78.7570782006024643,76.5083007543168492],"hsluv":[136.122445502284393,48.1280089891728622,76.5083007543168492]},"#88ccaa":{"lch":[76.8730534179438223,38.4110576559043437,149.173477570542047],"luv":[76.8730534179438223,-32.9844501501569098,19.6833787378341469],"rgb":[0.533333333333333326,0.8,0.66666666666666663],"xyz":[0.389999628592019698,0.513210112138072549,0.458825144123397588],"hpluv":[149.173477570542047,66.8865090410736229,76.8730534179438223],"hsluv":[149.173477570542047,50.0095890879800891,76.8730534179438223]},"#88ccbb":{"lch":[77.2847330465352087,33.404634806871222,168.536638924911273],"luv":[77.2847330465352087,-32.73827895277973,6.638879257104497],"rgb":[0.533333333333333326,0.8,0.733333333333333282],"xyz":[0.407137220699356372,0.520065148981007308,0.54908312922203939],"hpluv":[168.536638924911273,59.444025112992847,77.2847330465352087],"hsluv":[168.536638924911273,51.9915664660802292,77.2847330465352087]},"#88cccc":{"lch":[77.7438691793350074,33.2404934388306,192.177050630060876],"luv":[77.7438691793350074,-32.4925976386916417,-7.01152642061846443],"rgb":[0.533333333333333326,0.8,0.8],"xyz":[0.426429596143078071,0.527782099158496165,0.650689639892309546],"hpluv":[192.177050630060876,60.6231146417445359,77.7438691793350074],"hsluv":[192.177050630060876,54.0427382519684585,77.7438691793350074]},"#88ccdd":{"lch":[78.2507307533704,38.5418325774740964,213.193277164244591],"luv":[78.2507307533704,-32.2529061156020589,-21.1003058159876602],"rgb":[0.533333333333333326,0.8,0.866666666666666696],"xyz":[0.44794792169371167,0.536389429378749671,0.764019487792315544],"hpluv":[213.193277164244591,72.2588367593471759,78.2507307533704],"hsluv":[213.193277164244591,56.1332045791076126,78.2507307533704]},"#88ccee":{"lch":[78.8053428571366368,47.78945312574524,227.924421751618695],"luv":[78.8053428571366368,-32.0242046898233,-35.4722728908382834],"rgb":[0.533333333333333326,0.8,0.933333333333333348],"xyz":[0.47176010195988638,0.545914301485219688,0.889430303860838767],"hpluv":[227.924421751618695,92.3999074491721473,78.8053428571366368],"hsluv":[227.924421751618695,70.4270935368067796,78.8053428571366368]},"#88ccff":{"lch":[79.4075039272108114,59.2521837878726885,237.529017152572294],"luv":[79.4075039272108114,-31.8108626015509195,-49.9889018100727327],"rgb":[0.533333333333333326,0.8,1],"xyz":[0.497931150369717801,0.556382720849152412,1.02726449215262061],"hpluv":[237.529017152572294,118.549697277888072,79.4075039272108114],"hsluv":[237.529017152572294,99.999999999996561,79.4075039272108114]},"#334400":{"lch":[26.2681529832905483,31.0251081485104194,104.276907196552472],"luv":[26.2681529832905483,-7.65105337509169647,30.0669040288198879],"rgb":[0.2,0.266666666666666663,0],"xyz":[0.034322417713353183,0.0483799977885883553,0.00753004776376127276],"hpluv":[104.276907196552472,149.872894059772364,26.2681529832905483],"hsluv":[104.276907196552472,100.000000000002302,26.2681529832905483]},"#334411":{"lch":[26.3856741683463127,27.3886432490873446,106.295788944443402],"luv":[26.3856741683463127,-7.68514827558869662,26.2883296351821087],"rgb":[0.2,0.266666666666666663,0.0666666666666666657],"xyz":[0.0353340832129903082,0.0487846639884432082,0.0128581527285169042],"hpluv":[106.295788944443402,131.716945387015755,26.3856741683463127],"hsluv":[106.295788944443402,86.6296124974134614,26.3856741683463127]},"#334422":{"lch":[26.6018195362025054,21.2226436820006832,111.412237748000109],"luv":[26.6018195362025054,-7.74787020962619799,19.7578114189793403],"rgb":[0.2,0.266666666666666663,0.133333333333333331],"xyz":[0.0372094413514673233,0.0495348072438340295,0.0227350389244961],"hpluv":[111.412237748000109,101.234249163259577,26.6018195362025054],"hsluv":[111.412237748000109,63.7673799144094,26.6018195362025054]},"#334433":{"lch":[26.9529945323855813,12.8320575385027151,127.715012949236225],"luv":[26.9529945323855813,-7.8498102472204323,10.150969399721264],"rgb":[0.2,0.266666666666666663,0.2],"xyz":[0.0402971920839250639,0.0507699075368171424,0.038997192782107247],"hpluv":[127.715012949236225,60.4127494816677171,26.9529945323855813],"hsluv":[127.715012949236225,30.7608572023581708,26.9529945323855813]},"#334444":{"lch":[27.4501004194092673,8.17817622085537721,192.177050630060421],"luv":[27.4501004194092673,-7.99417102070306651,-1.72504956193021397],"rgb":[0.2,0.266666666666666663,0.266666666666666663],"xyz":[0.0447551873281439444,0.0525531056345047154,0.0624759677349938855],"hpluv":[192.177050630060421,37.8052272806132379,27.4501004194092673],"hsluv":[192.177050630060421,37.6572465300637518,27.4501004194092673]},"#334455":{"lch":[28.0976851129048839,16.9879579660521678,241.20654356816641],"luv":[28.0976851129048839,-8.1823109542023289,-14.8875956186718064],"rgb":[0.2,0.266666666666666663,0.333333333333333315],"xyz":[0.0507176013675059364,0.0549380712502495483,0.0938780150089678],"hpluv":[241.20654356816641,76.720241835207986,28.0976851129048839],"hsluv":[241.20654356816641,44.9859363973003568,28.0976851129048839]},"#334466":{"lch":[28.8949601880565652,29.7043747380071501,253.545194757545516],"luv":[28.8949601880565652,-8.41402976058801855,-28.487786536758108],"rgb":[0.2,0.266666666666666663,0.4],"xyz":[0.0583025971410141147,0.0579720695596528598,0.133825659416111742],"hpluv":[253.545194757545516,130.448064952476017,28.8949601880565652],"hsluv":[253.545194757545516,52.1427730716471629,28.8949601880565652]},"#334477":{"lch":[29.8367962202096138,42.8398018741040758,258.299336276781332],"luv":[29.8367962202096138,-8.68785350705267589,-41.9496105590085691],"rgb":[0.2,0.266666666666666663,0.466666666666666674],"xyz":[0.0676166101612160342,0.0616976747677336762,0.182879461322509651],"hpluv":[258.299336276781332,182.19421868795277,29.8367962202096138],"hsluv":[258.299336276781332,58.7347196438674857,29.8367962202096138]},"#334488":{"lch":[30.9147794404111025,55.6960507233291082,260.699324576281469],"luv":[30.9147794404111025,-9.00134255207500189,-54.9638599302837605],"rgb":[0.2,0.266666666666666663,0.533333333333333326],"xyz":[0.0787570272631598622,0.066153841608511274,0.241552324726081818],"hpluv":[260.699324576281469,228.611238042833349,30.9147794404111025],"hsluv":[260.699324576281469,64.5716173949788583,30.9147794404111025]},"#334499":{"lch":[32.1182691124294664,68.0605660836803281,262.102678541403236],"luv":[32.1182691124294664,-9.35140200670356769,-67.4150720250304],"rgb":[0.2,0.266666666666666663,0.6],"xyz":[0.0918139913722325618,0.0713766272521404316,0.310319002367199726],"hpluv":[262.102678541403236,268.895014901030436,32.1182691124294664],"hsluv":[262.102678541403236,69.6097770986353623,32.1182691124294664]},"#3344aa":{"lch":[33.435366318838156,79.8975403264742852,263.001802037450773],"luv":[33.435366318838156,-9.73456660877536528,-79.3023023824649158],"rgb":[0.2,0.266666666666666663,0.66666666666666663],"xyz":[0.106871684337485118,0.07739970443824154,0.389622851984198326],"hpluv":[263.001802037450773,303.226149032408784,33.435366318838156],"hsluv":[263.001802037450773,73.891501645941716,33.435366318838156]},"#3344bb":{"lch":[34.8537252521307721,91.2457354427413492,263.615054402289786],"luv":[34.8537252521307721,-10.1472390443123768,-90.6797539490724773],"rgb":[0.2,0.266666666666666663,0.733333333333333282],"xyz":[0.124009276444821764,0.0842547412811763,0.479880837082840073],"hpluv":[263.615054402289786,332.202349056841342,34.8537252521307721],"hsluv":[263.615054402289786,77.4995146205371412,34.8537252521307721]},"#3344cc":{"lch":[36.3611746115969083,102.170263494902102,264.052905077601281],"luv":[36.3611746115969083,-10.5858721727669973,-101.620382074461631],"rgb":[0.2,0.266666666666666663,0.8],"xyz":[0.143301651888543491,0.0919716914586651,0.581487347753110284],"hpluv":[264.052905077601281,356.55451128807033,36.3611746115969083],"hsluv":[264.052905077601281,80.5286468598271767,36.3611746115969083]},"#3344dd":{"lch":[37.9461503215655611,112.73940211649635,264.376684246138268],"luv":[37.9461503215655611,-11.0470957042534899,-112.196855865421313],"rgb":[0.2,0.266666666666666663,0.866666666666666696],"xyz":[0.164819977439177034,0.100579021678918634,0.694817195653116282],"hpluv":[264.376684246138268,377.005191833442723,37.9461503215655611],"hsluv":[264.376684246138268,84.1625325255073,37.9461503215655611]},"#3344ee":{"lch":[39.5979632159824462,123.014623823289881,264.622878978329823],"luv":[39.5979632159824462,-11.5277944422180187,-122.473293536523641],"rgb":[0.2,0.266666666666666663,0.933333333333333348],"xyz":[0.188632157705351772,0.110103893785388651,0.820228011721639505],"hpluv":[264.622878978329823,394.205992168221826,39.5979632159824462],"hsluv":[264.622878978329823,91.9832832027675664,39.5979632159824462]},"#3344ff":{"lch":[41.3069357297154482,133.047388274610427,264.814390787746049],"luv":[41.3069357297154482,-12.0251481753234213,-132.502842754623401],"rgb":[0.2,0.266666666666666663,1],"xyz":[0.214803206115183165,0.120572313149321361,0.95806220001342135],"hpluv":[264.814390787746049,408.716999433792864,41.3069357297154482],"hsluv":[264.814390787746049,99.9999999999994458,41.3069357297154482]},"#aacc00":{"lch":[77.1199831352121,88.8460909387721,100.173289143969555],"luv":[77.1199831352121,-15.692520471132994,87.4492577233428108],"rgb":[0.66666666666666663,0.8,0],"xyz":[0.381691137978657502,0.517314555618973326,0.0797436262784653],"hpluv":[100.173289143969555,156.730643533439519,77.1199831352121],"hsluv":[100.173289143969555,100.000000000002373,77.1199831352121]},"#aacc11":{"lch":[77.1442576556984676,87.800209961997254,100.311366942902],"luv":[77.1442576556984676,-15.7160097521192821,86.3821967007212237],"rgb":[0.66666666666666663,0.8,0.0666666666666666657],"xyz":[0.382702803478294606,0.517719221818828235,0.085071731243220941],"hpluv":[100.311366942902,155.08420894585916,77.1442576556984676],"hsluv":[100.311366942902,98.7181568051142,77.1442576556984676]},"#aacc22":{"lch":[77.1892227090432641,85.8765024717939411,100.574350259733862],"luv":[77.1892227090432641,-15.7593085348968636,84.4181134075499102],"rgb":[0.66666666666666663,0.8,0.133333333333333331],"xyz":[0.384578161616771663,0.518469365074219,0.0949486174392001336],"hpluv":[100.574350259733862,152.047171814071362,77.1892227090432641],"hsluv":[100.574350259733862,96.3604791744028404,77.1892227090432641]},"#aacc33":{"lch":[77.2631626362465482,82.7513779572315116,101.028364552392574],"luv":[77.2631626362465482,-15.8299191574657527,81.2231753460099668],"rgb":[0.66666666666666663,0.8,0.2],"xyz":[0.387665912349229369,0.519704465367202162,0.111210771296811284],"hpluv":[101.028364552392574,147.088857703341773,77.2631626362465482],"hsluv":[101.028364552392574,92.5301726329619,77.2631626362465482]},"#aacc44":{"lch":[77.3697083481362569,78.3307208035327278,101.734312614214147],"luv":[77.3697083481362569,-15.9304072801298968,76.6937021240348],"rgb":[0.66666666666666663,0.8,0.266666666666666663],"xyz":[0.392123907593448284,0.521487663464889728,0.134689546249697922],"hpluv":[101.734312614214147,140.021584702469511,77.3697083481362569],"hsluv":[101.734312614214147,87.1104907412273377,77.3697083481362569]},"#aacc55":{"lch":[77.5118305539362495,72.5836718124644875,102.784946304826448],"luv":[77.5118305539362495,-16.0622064150904862,70.7841432727597493],"rgb":[0.66666666666666663,0.8,0.333333333333333315],"xyz":[0.398086321632810269,0.523872629080634478,0.16609159352367181],"hpluv":[102.784946304826448,130.736122666873541,77.5118305539362495],"hsluv":[102.784946304826448,80.0585735006639,77.5118305539362495]},"#aacc66":{"lch":[77.6920071630818114,65.5409770618580865,104.333567867024144],"luv":[77.6920071630818114,-16.225762577214013,63.5007425390513731],"rgb":[0.66666666666666663,0.8,0.4],"xyz":[0.405671317406318455,0.526906627390037796,0.2060392379308158],"hpluv":[104.333567867024144,119.198186871977654,77.6920071630818114],"hsluv":[104.333567867024144,71.3979720959128,77.6920071630818114]},"#aacc77":{"lch":[77.912311817127474,57.2990991241466574,106.653185897117098],"luv":[77.912311817127474,-16.4206512214041886,54.8958010589496865],"rgb":[0.66666666666666663,0.8,0.466666666666666674],"xyz":[0.41498533042652036,0.530632232598118647,0.255093039837213709],"hpluv":[106.653185897117098,105.457526508453554,77.912311817127474],"hsluv":[106.653185897117098,61.2114900666368769,77.912311817127474]},"#aacc88":{"lch":[78.1744663257663,48.0371110011961946,110.274462486898784],"luv":[78.1744663257663,-16.6457037997795574,45.0608985524173633],"rgb":[0.66666666666666663,0.8,0.533333333333333326],"xyz":[0.42612574752846416,0.53508839943889619,0.313765903240785848],"hpluv":[110.274462486898784,89.6844859178180513,78.1744663257663],"hsluv":[110.274462486898784,49.6324036967210418,78.1744663257663]},"#aacc99":{"lch":[78.4798746855988583,38.0746183254558517,116.349336294343573],"luv":[78.4798746855988583,-16.8991518201031816,34.1188397866961779],"rgb":[0.66666666666666663,0.8,0.6],"xyz":[0.43918271163753686,0.540311185082525403,0.382532580881903783],"hpluv":[116.349336294343573,72.2917022308792383,78.4798746855988583],"hsluv":[116.349336294343573,36.8338589582570535,78.4798746855988583]},"#aaccaa":{"lch":[78.8296472340984593,28.0820980315160789,127.715012949234293],"luv":[78.8296472340984593,-17.1787837008838338,22.2147163027108476],"rgb":[0.66666666666666663,0.8,0.66666666666666663],"xyz":[0.454240404602789416,0.546334262268626469,0.461836430498902384],"hpluv":[127.715012949234293,54.3703242245777503,78.8296472340984593],"hsluv":[127.715012949234293,23.0170216670413055,78.8296472340984593]},"#aaccbb":{"lch":[79.2246195207133,19.8998018903229301,151.462718702096396],"luv":[79.2246195207133,-17.4821042808439238,9.50674209115818236],"rgb":[0.66666666666666663,0.8,0.733333333333333282],"xyz":[0.47137799671012609,0.553189299111561228,0.55209441559754413],"hpluv":[151.462718702096396,39.3999249764932173,79.2246195207133],"hsluv":[151.462718702096396,25.9022649263565761,79.2246195207133]},"#aacccc":{"lch":[79.665368512397464,18.216345023755192,192.177050630059796],"luv":[79.665368512397464,-17.80648564660072,-3.84243346616347603],"rgb":[0.66666666666666663,0.8,0.8],"xyz":[0.490670372153847789,0.560906249289050085,0.653700926267814286],"hpluv":[192.177050630059796,36.9937893704297878,79.665368512397464],"hsluv":[192.177050630059796,28.9019874878943099,79.665368512397464]},"#aaccdd":{"lch":[80.1522276755556504,25.332665849504842,224.238778454296437],"luv":[80.1522276755556504,-18.1492995031005968,-17.6733382978265112],"rgb":[0.66666666666666663,0.8,0.866666666666666696],"xyz":[0.512188697704481388,0.569513579509303591,0.767030774167820284],"hpluv":[224.238778454296437,52.9363308364733882,80.1522276755556504],"hsluv":[224.238778454296437,37.9969627853472787,80.1522276755556504]},"#aaccee":{"lch":[80.6853018377357216,36.8247992939862954,239.828051209207672],"luv":[80.6853018377357216,-18.5080244281037345,-31.8358112007702587],"rgb":[0.66666666666666663,0.8,0.933333333333333348],"xyz":[0.536000877970656098,0.579038451615773608,0.892441590236343507],"hpluv":[239.828051209207672,79.4490805971393854,80.6853018377357216],"hsluv":[239.828051209207672,67.7857500876551313,80.6853018377357216]},"#aaccff":{"lch":[81.2644823279674284,49.9029399741520834,247.769045833277914],"luv":[81.2644823279674284,-18.8803249793402337,-46.1934708236816434],"rgb":[0.66666666666666663,0.8,1],"xyz":[0.562171926380487519,0.589506870979706332,1.03027577852812535],"hpluv":[247.769045833277914,111.562078640814406,81.2644823279674284],"hsluv":[247.769045833277914,99.9999999999962625,81.2644823279674284]},"#88dd00":{"lch":[80.1491214608994085,103.252993693735874,114.339076779275487],"luv":[80.1491214608994085,-42.5542610136121837,94.0761158653142218],"rgb":[0.533333333333333326,0.866666666666666696,0],"xyz":[0.360084352515062933,0.569458386582770926,0.0909436700853518548],"hpluv":[114.339076779275487,215.722602995807392,80.1491214608994085],"hsluv":[114.339076779275487,100.000000000002288,80.1491214608994085]},"#88dd11":{"lch":[80.1718911006532551,102.308936337717924,114.55620444532569],"luv":[80.1718911006532551,-42.518128048011647,93.0555062414261727],"rgb":[0.533333333333333326,0.866666666666666696,0.0666666666666666657],"xyz":[0.361096018014700038,0.569863052782625834,0.0962717750501074915],"hpluv":[114.55620444532569,214.038948901986089,80.1718911006532551],"hsluv":[114.55620444532569,98.8288322371321186,80.1718911006532551]},"#88dd22":{"lch":[80.2140714473537315,100.574216022873557,114.966813202702411],"luv":[80.2140714473537315,-42.4516967311958453,91.1757992740300125],"rgb":[0.533333333333333326,0.866666666666666696,0.133333333333333331],"xyz":[0.362971376153177094,0.570613196038016635,0.106148661246086684],"hpluv":[114.966813202702411,210.937294411552,80.2140714473537315],"hsluv":[114.966813202702411,96.6732644510524,80.2140714473537315]},"#88dd33":{"lch":[80.283440325316,97.7612202004146695,115.666709499512805],"luv":[80.283440325316,-42.3438510501166832,88.1150069699792908],"rgb":[0.533333333333333326,0.866666666666666696,0.2],"xyz":[0.3660591268856348,0.571848296330999761,0.122410815103697834],"hpluv":[115.666709499512805,205.88559104418357,80.283440325316],"hsluv":[115.666709499512805,93.1672856447162303,80.283440325316]},"#88dd44":{"lch":[80.3834168948860821,93.7943752395521,116.732715571790365],"luv":[80.3834168948860821,-42.1914333437924896,83.7691338081886698],"rgb":[0.533333333333333326,0.866666666666666696,0.266666666666666663],"xyz":[0.370517122129853715,0.573631494428687327,0.145889590056584473],"hpluv":[116.732715571790365,198.714220363605108,80.3834168948860821],"hsluv":[116.732715571790365,88.1979852499996184,80.3834168948860821]},"#88dd55":{"lch":[80.5168087418625475,88.6629430887769,118.270203219525229],"luv":[80.5168087418625475,-41.9934519908601374,78.0875628192801088],"rgb":[0.533333333333333326,0.866666666666666696,0.333333333333333315],"xyz":[0.376479536169215701,0.576016460044432077,0.17729163733055836],"hpluv":[118.270203219525229,189.352414361266369,80.5168087418625475],"hsluv":[118.270203219525229,81.7170886524359474,80.5168087418625475]},"#88dd66":{"lch":[80.6859701106092757,82.4238546620344437,120.433562333743893],"luv":[80.6859701106092757,-41.7508898851674672,71.0672569552589266],"rgb":[0.533333333333333326,0.866666666666666696,0.4],"xyz":[0.384064531942723886,0.579050458353835396,0.21723928173770235],"hpluv":[120.433562333743893,177.835721711884361,80.6859701106092757],"hsluv":[120.433562333743893,73.7344666622195604,80.6859701106092757]},"#88dd77":{"lch":[80.8928858528116734,75.2114908165065827,123.458458278308711],"luv":[80.8928858528116734,-41.4665196955592208,62.7478772165182832],"rgb":[0.533333333333333326,0.866666666666666696,0.466666666666666674],"xyz":[0.393378544962925791,0.582776063561916247,0.266293083644100259],"hpluv":[123.458458278308711,164.332036041008877,80.8928858528116734],"hsluv":[123.458458278308711,64.312379996729149,80.8928858528116734]},"#88dd88":{"lch":[81.1392211885512,67.2590471315356524,127.71501294923884],"luv":[81.1392211885512,-41.1446687958856145,53.2061617739807531],"rgb":[0.533333333333333326,0.866666666666666696,0.533333333333333326],"xyz":[0.404518962064869592,0.587232230402693789,0.324965947047672399],"hpluv":[127.71501294923884,149.199726190229825,81.1392211885512],"hsluv":[127.71501294923884,53.5585775308776633,81.1392211885512]},"#88dd99":{"lch":[81.4263538436063072,58.943488890057,133.791370377408185],"luv":[81.4263538436063072,-40.7909253788266,42.5492102073736831],"rgb":[0.533333333333333326,0.866666666666666696,0.6],"xyz":[0.417575926173942347,0.592455016046323,0.393732624688790334],"hpluv":[133.791370377408185,133.11083868071384,81.4263538436063072],"hsluv":[133.791370377408185,54.8771054313611515,81.4263538436063072]},"#88ddaa":{"lch":[81.7553965772464437,50.8758256364689956,142.591286230634154],"luv":[81.7553965772464437,-40.4117997418374131,30.906893661738728],"rgb":[0.533333333333333326,0.866666666666666696,0.66666666666666663],"xyz":[0.432633619139194847,0.598478093232424069,0.473036474305788934],"hpluv":[142.591286230634154,117.302359569381537,81.7553965772464437],"hsluv":[142.591286230634154,56.3076629138628,81.7553965772464437]},"#88ddbb":{"lch":[82.1272144034785327,44.0521153731503716,155.27715859232552],"luv":[82.1272144034785327,-40.0143654100278567,18.4238820470094566],"rgb":[0.533333333333333326,0.866666666666666696,0.733333333333333282],"xyz":[0.449771211246531522,0.605333130075358827,0.563294459404430681],"hpluv":[155.27715859232552,104.020343594656595,82.1272144034785327],"hsluv":[155.27715859232552,57.829298146967858,82.1272144034785327]},"#88ddcc":{"lch":[82.542438979776648,39.9525966793572422,172.446474622419316],"luv":[82.542438979776648,-39.6059077008678173,5.25186220437346396],"rgb":[0.533333333333333326,0.866666666666666696,0.8],"xyz":[0.469063586690253276,0.613050080252847684,0.664900970074700837],"hpluv":[172.446474622419316,96.9346789585341355,82.542438979776648],"hsluv":[172.446474622419316,59.4202271347422908,82.542438979776648]},"#88dddd":{"lch":[83.0014816422074375,40.0957403917498354,192.177050630060734],"luv":[83.0014816422074375,-39.1936046909777,-8.4575261684472629],"rgb":[0.533333333333333326,0.866666666666666696,0.866666666666666696],"xyz":[0.490581912240886764,0.621657410473101191,0.778230817974706834],"hpluv":[192.177050630060734,100.308679558078737,83.0014816422074375],"hsluv":[192.177050630060734,61.0588228331018783,83.0014816422074375]},"#88ddee":{"lch":[83.5045459788204,44.8677054153188,210.184175125347622],"luv":[83.5045459788204,-38.7842593009493157,-22.5586395802706683],"rgb":[0.533333333333333326,0.866666666666666696,0.933333333333333348],"xyz":[0.514394092507061584,0.631182282579571208,0.903641634043230058],"hpluv":[210.184175125347622,116.175045715242419,83.5045459788204],"hsluv":[210.184175125347622,62.7244468832174746,83.5045459788204]},"#88ddff":{"lch":[84.0516404633952732,53.2556266987753659,223.883407592331508],"luv":[84.0516404633952732,-38.3840933399078779,-36.9164347351224436],"rgb":[0.533333333333333326,0.866666666666666696,1],"xyz":[0.540565140916892894,0.641650701943503932,1.04147582233501179],"hpluv":[223.883407592331508,143.298172182841085,84.0516404633952732],"hsluv":[223.883407592331508,99.9999999999952,84.0516404633952732]},"#335500":{"lch":[32.2593993637483862,41.1235506245754365,113.326494368716226],"luv":[32.2593993637483862,-16.2836990313566261,37.7622504868051223],"rgb":[0.2,0.333333333333333315,0],"xyz":[0.0461356744276991415,0.0720065112172806193,0.0114678000018764836],"hpluv":[113.326494368716226,161.760937136611716,32.2593993637483862],"hsluv":[113.326494368716226,100.000000000002288,32.2593993637483862]},"#335511":{"lch":[32.3496341583576381,38.1897920123001313,115.090818108356473],"luv":[32.3496341583576381,-16.1945453684027605,34.5860797757347456],"rgb":[0.2,0.333333333333333315,0.0666666666666666657],"xyz":[0.0471473399273362598,0.0724111774171354722,0.016795904966632115],"hpluv":[115.090818108356473,149.801873896373706,32.3496341583576381],"hsluv":[115.090818108356473,90.8995446090399923,32.3496341583576381]},"#335522":{"lch":[32.5160201858231659,33.1206139518783189,118.966642902489184],"luv":[32.5160201858231659,-16.0403246718637718,28.9772851207727022],"rgb":[0.2,0.333333333333333315,0.133333333333333331],"xyz":[0.0490226980658132819,0.0731613206725262866,0.0266727911626113111],"hpluv":[118.966642902489184,129.252907346834121,32.5160201858231659],"hsluv":[118.966642902489184,74.935129302234273,32.5160201858231659]},"#335533":{"lch":[32.7875119073456176,25.8516304293262671,127.715012949238741],"luv":[32.7875119073456176,-15.8143300747053051,20.4502753072602665],"rgb":[0.2,0.333333333333333315,0.2],"xyz":[0.0521104487982710224,0.0743964209655094,0.0429349450202224578],"hpluv":[127.715012949238741,100.050394151032577,32.7875119073456176],"hsluv":[127.715012949238741,50.9434831873252207,32.7875119073456176]},"#335544":{"lch":[33.1742322541989836,18.1915220066791647,148.674883917516439],"luv":[33.1742322541989836,-15.539762262897943,9.45765624941535421],"rgb":[0.2,0.333333333333333315,0.266666666666666663],"xyz":[0.0565684440424899,0.0761796190631969794,0.0664137199731090894],"hpluv":[148.674883917516439,69.5836942134034899,33.1742322541989836],"hsluv":[148.674883917516439,54.5088767633859703,33.1742322541989836]},"#335555":{"lch":[33.6821363315134121,15.5994691341387064,192.177050630060819],"luv":[33.6821363315134121,-15.2484882598238034,-3.29044724269541522],"rgb":[0.2,0.333333333333333315,0.333333333333333315],"xyz":[0.0625308580818519,0.0785645846789418123,0.097815767247083],"hpluv":[192.177050630060819,58.7691644617976934,33.6821363315134121],"hsluv":[192.177050630060819,58.539124710901028,33.6821363315134121]},"#335566":{"lch":[34.3136156967701496,22.6822476529859181,228.692277460856218],"luv":[34.3136156967701496,-14.9726179113300351,-17.0383412183435361],"rgb":[0.2,0.333333333333333315,0.4],"xyz":[0.0701158538553600663,0.0815985829883451308,0.137763411654226953],"hpluv":[228.692277460856218,83.8800984368335,34.3136156967701496],"hsluv":[228.692277460856218,62.7386213411417089,34.3136156967701496]},"#335577":{"lch":[35.0679836745485218,34.4527831327976131,244.673076132176305],"luv":[35.0679836745485218,-14.7383029974912176,-31.1412377780608658],"rgb":[0.2,0.333333333333333315,0.466666666666666674],"xyz":[0.0794298668755619858,0.0853241881964259402,0.186817213560624862],"hpluv":[244.673076132176305,124.667382519216758,35.0679836745485218],"hsluv":[244.673076132176305,66.8604241763398335,35.0679836745485218]},"#335588":{"lch":[35.9419713942028523,47.4274747217606318,252.117898483801355],"luv":[35.9419713942028523,-14.5630489263951493,-45.1362710516793229],"rgb":[0.2,0.333333333333333315,0.533333333333333326],"xyz":[0.0905702839775058138,0.089780355037203538,0.245490076964197029],"hpluv":[252.117898483801355,167.443168522882189,35.9419713942028523],"hsluv":[252.117898483801355,70.7327730687023433,35.9419713942028523]},"#335599":{"lch":[36.9302538454711851,60.4953772811161272,256.174865065393647],"luv":[36.9302538454711851,-14.4559426241851021,-58.7427986669927833],"rgb":[0.2,0.333333333333333315,0.6],"xyz":[0.103627248086578527,0.0950031406808327,0.314256754605314936],"hpluv":[256.174865065393647,207.863972679723531,36.9302538454711851],"hsluv":[256.174865065393647,74.2581677802949258,36.9302538454711851]},"#3355aa":{"lch":[38.0259842211890557,73.2582460718320903,258.648348715518409],"luv":[38.0259842211890557,-14.4194259870406505,-71.8251402485603165],"rgb":[0.2,0.333333333333333315,0.66666666666666663],"xyz":[0.118684941051831069,0.101026217866933804,0.393560604222313537],"hpluv":[258.648348715518409,244.464262316607687,38.0259842211890557],"hsluv":[258.648348715518409,77.3978910060545,38.0259842211890557]},"#3355bb":{"lch":[39.2213032744107579,85.5750988898230815,260.277622363739169],"luv":[39.2213032744107579,-14.4514388960387397,-84.3460340729607623],"rgb":[0.2,0.333333333333333315,0.733333333333333282],"xyz":[0.135822533159167702,0.107881254709868563,0.483818589320955283],"hpluv":[260.277622363739169,276.862869377010384,39.2213032744107579],"hsluv":[260.277622363739169,80.1529964351826578,39.2213032744107579]},"#3355cc":{"lch":[40.5077939091134667,97.4185991778777,261.412040351160215],"luv":[40.5077939091134667,-14.5472816309580448,-96.326320717286734],"rgb":[0.2,0.333333333333333315,0.8],"xyz":[0.155114908602889456,0.115598204887357364,0.585425099991225495],"hpluv":[261.412040351160215,305.17054630009352,40.5077939091134667],"hsluv":[261.412040351160215,82.5478264076183734,40.5077939091134667]},"#3355dd":{"lch":[41.8768615158020552,108.813506268261335,262.235450095721887],"luv":[41.8768615158020552,-14.7009821832840935,-107.815862790406285],"rgb":[0.2,0.333333333333333315,0.866666666666666696],"xyz":[0.176633234153523,0.124205535107610898,0.698754947891231493],"hpluv":[262.235450095721887,329.72206067647727,41.8768615158020552],"hsluv":[262.235450095721887,84.6180359154754456,41.8768615158020552]},"#3355ee":{"lch":[43.3200322197542533,119.805986402952101,262.852770803428143],"luv":[43.3200322197542533,-14.9061911990543372,-118.875059797762361],"rgb":[0.2,0.333333333333333315,0.933333333333333348],"xyz":[0.200445414419697737,0.133730407214080915,0.824165763959754716],"hpluv":[262.852770803428143,350.936931775297865,43.3200322197542533],"hsluv":[262.852770803428143,90.8055999978327577,43.3200322197542533]},"#3355ff":{"lch":[44.8291710285026497,130.447860525532377,263.327743444412704],"luv":[44.8291710285026497,-15.1567128937849134,-129.564340657235334],"rgb":[0.2,0.333333333333333315,1],"xyz":[0.226616462829529131,0.144198826578013639,0.961999952251536561],"hpluv":[263.327743444412704,369.245812735261836,44.8291710285026497],"hsluv":[263.327743444412704,99.9999999999993,44.8291710285026497]},"#aadd00":{"lch":[81.9783608763648175,97.3184216433040916,105.014728605041086],"luv":[81.9783608763648175,-25.2120246284188454,93.9958988747909245],"rgb":[0.66666666666666663,0.866666666666666696,0],"xyz":[0.424325128525832707,0.602582536713324846,0.0939549564608566229],"hpluv":[105.014728605041086,227.603505169437568,81.9783608763648175],"hsluv":[105.014728605041086,100.000000000002203,81.9783608763648175]},"#aadd11":{"lch":[82.0002885274849262,96.374791846509865,105.167446282879951],"luv":[82.0002885274849262,-25.2155818179290208,93.017605521973266],"rgb":[0.66666666666666663,0.866666666666666696,0.0666666666666666657],"xyz":[0.425336794025469811,0.602987202913179754,0.0992830614256122596],"hpluv":[105.167446282879951,225.71449396257529,82.0002885274849262],"hsluv":[105.167446282879951,98.8971907906987298,82.0002885274849262]},"#aadd22":{"lch":[82.0409106120811,94.6380623122949345,105.456830413527484],"luv":[82.0409106120811,-25.2222030700150874,91.2151484706391216],"rgb":[0.66666666666666663,0.866666666666666696,0.133333333333333331],"xyz":[0.427212152163946868,0.603737346168570554,0.109159947621591452],"hpluv":[105.456830413527484,222.227322886837186,82.0409106120811],"hsluv":[105.456830413527484,96.86659260915998,82.0409106120811]},"#aadd33":{"lch":[82.1077210543303693,91.8137349028061891,105.951891130476156],"luv":[82.1077210543303693,-25.2331804702422886,88.2782448860360773],"rgb":[0.66666666666666663,0.866666666666666696,0.2],"xyz":[0.430299902896404574,0.604972446461553681,0.125422101479202602],"hpluv":[105.951891130476156,216.526835376233663,82.1077210543303693],"hsluv":[105.951891130476156,93.5615293661406469,82.1077210543303693]},"#aadd44":{"lch":[82.204019596801416,87.812555976334508,106.710442618715334],"luv":[82.204019596801416,-25.2491908313752447,84.1042409718896238],"rgb":[0.66666666666666663,0.866666666666666696,0.266666666666666663],"xyz":[0.434757898140623489,0.606755644559241247,0.148900876432089241],"hpluv":[106.710442618715334,208.386709262610594,82.204019596801416],"hsluv":[106.710442618715334,88.8720213109455415,82.204019596801416]},"#aadd55":{"lch":[82.332521082647844,82.6008871447080537,107.814707884186447],"luv":[82.332521082647844,-25.2708912490316564,78.6402480449573],"rgb":[0.66666666666666663,0.866666666666666696,0.333333333333333315],"xyz":[0.440720312179985474,0.609140610174986,0.180302923706063156],"hpluv":[107.814707884186447,197.666387369374576,82.332521082647844],"hsluv":[107.814707884186447,82.7472331150865,82.332521082647844]},"#aadd66":{"lch":[82.495508489392364,76.2000100439918526,109.390646830849064],"luv":[82.495508489392364,-25.2989483474785786,71.8777068583581666],"rgb":[0.66666666666666663,0.866666666666666696,0.4],"xyz":[0.448305307953493659,0.612174608484389315,0.22025056811320709],"hpluv":[109.390646830849064,184.308617744019813,82.495508489392364],"hsluv":[109.390646830849064,75.1895211365387723,82.495508489392364]},"#aadd77":{"lch":[82.694914273715753,68.6905071379487,111.642517734809914],"luv":[82.694914273715753,-25.3340491820501299,63.8480361711309499],"rgb":[0.66666666666666663,0.866666666666666696,0.466666666666666674],"xyz":[0.457619320973695565,0.615900213692470166,0.269304370019605],"hpluv":[111.642517734809914,168.351618208890358,82.694914273715753],"hsluv":[111.642517734809914,66.2494286969421182,82.694914273715753]},"#aadd88":{"lch":[82.9323686283524921,60.2252781448786436,114.920875432447886],"luv":[82.9323686283524921,-25.3769003534370228,54.6177357282387277],"rgb":[0.66666666666666663,0.866666666666666696,0.533333333333333326],"xyz":[0.468759738075639365,0.620356380533247709,0.327977233423177195],"hpluv":[114.920875432447886,149.967217229555729,82.9323686283524921],"hsluv":[114.920875432447886,56.0198042099318698,82.9323686283524921]},"#aadd99":{"lch":[83.2092305924335,51.0640475908324305,119.865599423026282],"luv":[83.2092305924335,-25.4282188712646082,44.2825320120006438],"rgb":[0.66666666666666663,0.866666666666666696,0.6],"xyz":[0.481816702184712065,0.625579166176876922,0.396743911064295074],"hpluv":[119.865599423026282,129.562195810811914,83.2092305924335],"hsluv":[119.865599423026282,44.6286172342680487,83.2092305924335]},"#aaddaa":{"lch":[83.526609727912188,41.6663179647472717,127.715012949236481],"luv":[83.526609727912188,-25.4887175141036408,32.9606937461220255],"rgb":[0.66666666666666663,0.866666666666666696,0.66666666666666663],"xyz":[0.496874395149964621,0.631602243362978,0.476047760681293675],"hpluv":[127.715012949236481,108.050849780995421,83.526609727912188],"hsluv":[127.715012949236481,32.2306770176982198,83.526609727912188]},"#aaddbb":{"lch":[83.8853825066367449,32.9442078204095523,140.880295511025736],"luv":[83.8853825066367449,-25.5590871805440472,20.7859060762739638],"rgb":[0.66666666666666663,0.866666666666666696,0.733333333333333282],"xyz":[0.514011987257301239,0.638457280205912747,0.566305745779935421],"hpluv":[140.880295511025736,87.605014056209555,83.8853825066367449],"hsluv":[140.880295511025736,34.4766875289621382,83.8853825066367449]},"#aaddcc":{"lch":[84.2862057978904602,26.8294893367150316,162.87488866986746],"luv":[84.2862057978904602,-25.639978502468459,7.90018990036700242],"rgb":[0.66666666666666663,0.866666666666666696,0.8],"xyz":[0.533304362701023,0.646174230383401604,0.667912256450205577],"hpluv":[162.87488866986746,73.4171355960865526,84.2862057978904602],"hsluv":[162.87488866986746,36.8333761539634708,84.2862057978904602]},"#aadddd":{"lch":[84.729528894444158,26.3242685722419552,192.177050630060421],"luv":[84.729528894444158,-25.7319846477226655,-5.55266440124834],"rgb":[0.66666666666666663,0.866666666666666696,0.866666666666666696],"xyz":[0.554822688251656593,0.654781560603655111,0.781242104350211575],"hpluv":[192.177050630060421,74.4077864529294146,84.729528894444158],"hsluv":[192.177050630060421,39.269697519551606,84.729528894444158]},"#aaddee":{"lch":[85.2156049558348769,32.3281965376105802,216.94937298104162],"luv":[85.2156049558348769,-25.8356267715816657,-19.4327733659894548],"rgb":[0.66666666666666663,0.866666666666666696,0.933333333333333348],"xyz":[0.578634868517831302,0.664306432710125128,0.906652920418734798],"hpluv":[216.94937298104162,94.7745998726022094,85.2156049558348769],"hsluv":[216.94937298104162,58.4216362813771397,85.2156049558348769]},"#aaddff":{"lch":[85.744502396509489,42.4619511969095527,232.326067904807843],"luv":[85.744502396509489,-25.9513430438233641,-33.608705623253762],"rgb":[0.66666666666666663,0.866666666666666696,1],"xyz":[0.604805916927662723,0.674774852074057852,1.04448710871051675],"hpluv":[232.326067904807843,129.682154580054771,85.744502396509489],"hsluv":[232.326067904807843,99.9999999999945572,85.744502396509489]},"#88ee00":{"lch":[85.1906878331824515,112.448241602139106,116.535675589642423],"luv":[85.1906878331824515,-50.2368100475369914,100.602534538950536],"rgb":[0.533333333333333326,0.933333333333333348,0],"xyz":[0.40726312885557775,0.663815939263801891,0.106669928865523039],"hpluv":[116.535675589642423,329.03324103323672,85.1906878331824515],"hsluv":[116.535675589642423,100.000000000002416,85.1906878331824515]},"#88ee11":{"lch":[85.2112458075113182,111.594873497969587,116.730132104203335],"luv":[85.2112458075113182,-50.1941202672300193,99.669283541253],"rgb":[0.533333333333333326,0.933333333333333348,0.0666666666666666657],"xyz":[0.408274794355214854,0.664220605463656799,0.111998033830278676],"hpluv":[116.730132104203335,327.047318494663614,85.2112458075113182],"hsluv":[116.730132104203335,98.9939616796445,85.2112458075113182]},"#88ee22":{"lch":[85.2493327369145,110.025246585506409,117.096539077460619],"luv":[85.2493327369145,-50.115524286233132,97.9489107224652429],"rgb":[0.533333333333333326,0.933333333333333348,0.133333333333333331],"xyz":[0.410150152493691911,0.6649707487190476,0.121874920026257869],"hpluv":[117.096539077460619,323.384561507736407,85.2493327369145],"hsluv":[117.096539077460619,97.140453749143191,85.2493327369145]},"#88ee33":{"lch":[85.3119799721786,107.475578977757436,117.717135468026783],"luv":[85.3119799721786,-49.9876247553973769,95.1432469906181097],"rgb":[0.533333333333333326,0.933333333333333348,0.2],"xyz":[0.413237903226149617,0.666205849012030726,0.138137073883869],"hpluv":[117.717135468026783,317.406918528502,85.3119799721786],"hsluv":[117.717135468026783,94.120593299189423,85.3119799721786]},"#88ee44":{"lch":[85.4022915890189864,103.870397610997969,118.652974854946393],"luv":[85.4022915890189864,-49.8062112723248518,91.1504296126099],"rgb":[0.533333333333333326,0.933333333333333348,0.266666666666666663],"xyz":[0.417695898470368532,0.667989047109718292,0.161615848836755643],"hpluv":[118.652974854946393,308.894438519259097,85.4022915890189864],"hsluv":[118.652974854946393,89.8292917088674869,85.4022915890189864]},"#88ee55":{"lch":[85.5228293578601466,99.1885702075232,119.98340282305692],"luv":[85.5228293578601466,-49.5693999595221584,85.9141842041562],"rgb":[0.533333333333333326,0.933333333333333348,0.333333333333333315],"xyz":[0.423658312509730517,0.670374012725463,0.193017896110729559],"hpluv":[119.98340282305692,297.731707367046795,85.5228293578601466],"hsluv":[119.98340282305692,84.2131356884780473,85.5228293578601466]},"#88ee66":{"lch":[85.6757572108422,93.4644574192068234,121.818598205465591],"luv":[85.6757572108422,-49.2774194314266083,79.4187681524083189],"rgb":[0.533333333333333326,0.933333333333333348,0.4],"xyz":[0.431243308283238702,0.673408011034866361,0.232965540517873521],"hpluv":[121.818598205465591,283.912655540997662,85.6757572108422],"hsluv":[121.818598205465591,77.2651144072775082,85.6757572108422]},"#88ee77":{"lch":[85.8629182835971676,86.7937408847250822,124.317503927832064],"luv":[85.8629182835971676,-48.9324360738715,71.6852157466327071],"rgb":[0.533333333333333326,0.933333333333333348,0.466666666666666674],"xyz":[0.440557321303440608,0.677133616242947212,0.282019342424271402],"hpluv":[124.317503927832064,267.563092583833793,85.8629182835971676],"hsluv":[124.317503927832064,69.0205357789205749,85.8629182835971676]},"#88ee88":{"lch":[86.0858807036169793,79.3454652904755164,127.71501294923921],"luv":[86.0858807036169793,-48.5383458294846,62.7672832477191918],"rgb":[0.533333333333333326,0.933333333333333348,0.533333333333333326],"xyz":[0.451697738405384408,0.681589783083724754,0.340692205827843597],"hpluv":[127.71501294923921,248.989760930573482,86.0858807036169793],"hsluv":[127.71501294923921,59.5524101967812,86.0858807036169793]},"#88ee99":{"lch":[86.3459670558122525,71.3853284581525429,132.362204285947513],"luv":[86.3459670558122525,-48.1005130697284287,52.7466184841000825],"rgb":[0.533333333333333326,0.933333333333333348,0.6],"xyz":[0.464754702514457163,0.686812568727354,0.409458883468961532],"hpluv":[132.362204285947513,228.778132650246619,86.3459670558122525],"hsluv":[132.362204285947513,60.5562348819982645,86.3459670558122525]},"#88eeaa":{"lch":[86.6442747471204768,63.319361027400987,138.776693085718904],"luv":[86.6442747471204768,-47.625461320552418,41.7271723811105204],"rgb":[0.533333333333333326,0.933333333333333348,0.66666666666666663],"xyz":[0.479812395479709664,0.692835645913455,0.488762733085960077],"hpluv":[138.776693085718904,207.981038552319745,86.6442747471204768],"hsluv":[138.776693085718904,61.6537348625427342,86.6442747471204768]},"#88eebb":{"lch":[86.9816911545789679,55.7684583245382299,147.664608842749317],"luv":[86.9816911545789679,-47.1205330954276,29.8291184029711189],"rgb":[0.533333333333333326,0.933333333333333348,0.733333333333333282],"xyz":[0.496949987587046338,0.699690682756389792,0.579020718184601879],"hpluv":[147.664608842749317,188.458500832318975,86.9816911545789679],"hsluv":[147.664608842749317,62.830800627143077,86.9816911545789679]},"#88eecc":{"lch":[87.3589058048410294,49.6608679924305463,159.75715297219557],"luv":[87.3589058048410294,-46.5935415809549696,17.182656741768227],"rgb":[0.533333333333333326,0.933333333333333348,0.8],"xyz":[0.516242363030768092,0.70740763293387865,0.680627228854872],"hpluv":[159.75715297219557,173.371642714007834,87.3589058048410294],"hsluv":[159.75715297219557,64.0722902507549179,87.3589058048410294]},"#88eedd":{"lch":[87.7764209496729,46.2191498548509543,175.132102674355139],"luv":[87.7764209496729,-46.0524373199716166,3.92209512827700335],"rgb":[0.533333333333333326,0.933333333333333348,0.866666666666666696],"xyz":[0.53776068858140158,0.716014963154132156,0.793957076754878],"hpluv":[175.132102674355139,167.447502067072264,87.7764209496729],"hsluv":[175.132102674355139,65.3626972838926434,87.7764209496729]},"#88eeee":{"lch":[88.2345613859691866,46.5524177333431339,192.177050630060933],"luv":[88.2345613859691866,-45.5050097647113958,-9.8194543195231],"rgb":[0.533333333333333326,0.933333333333333348,0.933333333333333348],"xyz":[0.56157286884757629,0.725539835260602173,0.919367892823401256],"hpluv":[192.177050630060933,175.887543813927181,88.2345613859691866],"hsluv":[192.177050630060933,66.6867488369664443,88.2345613859691866]},"#88eeff":{"lch":[88.7334840469836763,50.9233073192915242,208.009521596121829],"luv":[88.7334840469836763,-44.9586380478967271,-23.9145163700465169],"rgb":[0.533333333333333326,0.933333333333333348,1],"xyz":[0.587743917257407711,0.736008254624534897,1.05720208111518299],"hpluv":[208.009521596121829,201.749007974481685,88.7334840469836763],"hsluv":[208.009521596121829,99.9999999999925109,88.7334840469836763]},"#336600":{"lch":[38.2101034680229574,51.4017776291135888,118.130952889189317],"luv":[38.2101034680229574,-24.2353400261634,45.3298029694491902],"rgb":[0.2,0.4,0],"xyz":[0.0611637321335456105,0.10206262662897396,0.0164771525704918292],"hpluv":[118.130952889189317,170.702252266418213,38.2101034680229574],"hsluv":[118.130952889189317,100.000000000002288,38.2101034680229574]},"#336611":{"lch":[38.2816545292110959,48.9828222693822468,119.470954908934345],"luv":[38.2816545292110959,-24.0986808399199681,42.6447002480913682],"rgb":[0.2,0.4,0.0666666666666666657],"xyz":[0.0621753976331827357,0.102467292828828813,0.021805257535247459],"hpluv":[119.470954908934345,162.365005406289157,38.2816545292110959],"hsluv":[119.470954908934345,93.5286374368429,38.2816545292110959]},"#336622":{"lch":[38.4137944304132617,44.7307250918699282,122.230818066602779],"luv":[38.4137944304132617,-23.8562978467226365,37.8380076152656173],"rgb":[0.2,0.4,0.133333333333333331],"xyz":[0.0640507557716597509,0.103217436084219627,0.0316821437312266585],"hpluv":[122.230818066602779,147.760399550800031,38.4137944304132617],"hsluv":[122.230818066602779,81.994947572555219,38.4137944304132617]},"#336633":{"lch":[38.6299730126545171,38.3921679396875817,127.715012949239437],"luv":[38.6299730126545171,-23.4858075099586969,30.3706339201924216],"rgb":[0.2,0.4,0.2],"xyz":[0.0671385065041174844,0.10445253637720274,0.0479442975888378],"hpluv":[127.715012949239437,126.112332565807833,38.6299730126545171],"hsluv":[127.715012949239437,64.2136550115152,38.6299730126545171]},"#336644":{"lch":[38.9390987599147635,30.7877900918170191,138.353415806708398],"luv":[38.9390987599147635,-23.0064236741332095,20.4595329483365589],"rgb":[0.2,0.4,0.266666666666666663],"xyz":[0.0715965017483363719,0.10623573447489032,0.0714230725417244472],"hpluv":[138.353415806708398,100.330262339301328,38.9390987599147635],"hsluv":[138.353415806708398,66.1490613915476899,38.9390987599147635]},"#336655":{"lch":[39.3471830293532108,24.0314899024670439,159.111050143656939],"luv":[39.3471830293532108,-22.4519783641565418,8.56861566811244479],"rgb":[0.2,0.4,0.333333333333333315],"xyz":[0.077558915787698357,0.108620700090635153,0.102825119815698349],"hpluv":[159.111050143656939,77.5008343503898089,39.3471830293532108],"hsluv":[159.111050143656939,68.4324421599544337,39.3471830293532108]},"#336666":{"lch":[39.8577781510875653,22.3660784387423632,192.177050630061],"luv":[39.8577781510875653,-21.8628519700770774,-4.71775036033837925],"rgb":[0.2,0.4,0.4],"xyz":[0.0851439115612065422,0.111654698400038471,0.142772764222842297],"hpluv":[192.177050630061,71.205917149352544,39.8577781510875653],"hsluv":[192.177050630061,70.9271962998489727,39.8577781510875653]},"#336677":{"lch":[40.4722660639059,28.403364995264031,221.483563289625266],"luv":[40.4722660639059,-21.2782609928981294,-18.8145356618838697],"rgb":[0.2,0.4,0.466666666666666674],"xyz":[0.0944579245814084478,0.115380303608119281,0.191826566129240206],"hpluv":[221.483563289625266,89.0536244466218534,40.4722660639059],"hsluv":[221.483563289625266,73.4989606489913,40.4722660639059]},"#336688":{"lch":[41.1901179582142731,39.1584560294521253,238.034471274574031],"luv":[41.1901179582142731,-20.7308371309926542,-33.2207325394668516],"rgb":[0.2,0.4,0.533333333333333326],"xyz":[0.105598341683352276,0.119836470448896878,0.250499429532812401],"hpluv":[238.034471274574031,120.634589470818128,41.1901179582142731],"hsluv":[238.034471274574031,76.0346320246428746,41.1901179582142731]},"#336699":{"lch":[42.0091634944821948,51.6886413393569626,246.942440261812],"luv":[42.0091634944821948,-20.2441498032976277,-47.5593318103852951],"rgb":[0.2,0.4,0.6],"xyz":[0.118655305792425,0.12505925609252605,0.31926610717393028],"hpluv":[246.942440261812,156.131455895945,42.0091634944821948],"hsluv":[246.942440261812,78.4511744564818514,42.0091634944821948]},"#3366aa":{"lch":[42.9258754740709847,64.6951641030825,252.148217293940775],"luv":[42.9258754740709847,-19.832670948043944,-61.5802681172418218],"rgb":[0.2,0.4,0.66666666666666663],"xyz":[0.133712998757677531,0.131082333278627144,0.398569956790928881],"hpluv":[252.148217293940775,191.245834212653307,42.9258754740709847],"hsluv":[252.148217293940775,80.6959595489171,42.9258754740709847]},"#3366bb":{"lch":[43.9356615222631106,77.6311657782158164,255.449757662516049],"luv":[43.9356615222631106,-19.5031901130623,-75.1413566253536374],"rgb":[0.2,0.4,0.733333333333333282],"xyz":[0.150850590865014178,0.137937370121561903,0.488827941889570627],"hpluv":[255.449757662516049,224.211696450950683,43.9356615222631106],"hsluv":[255.449757662516049,82.7420790911240402,43.9356615222631106]},"#3366cc":{"lch":[45.0331492258045287,90.2591849706621332,257.681278432902445],"luv":[45.0331492258045287,-19.2567634880452658,-88.1810497302775786],"rgb":[0.2,0.4,0.8],"xyz":[0.170142966308735932,0.145654320299050705,0.590434452559840839],"hpluv":[257.681278432902445,254.330482568364204,45.0331492258045287],"hsluv":[257.681278432902445,84.5818015821218694,45.0331492258045287]},"#3366dd":{"lch":[46.2124513047425367,102.485732700579547,259.264483160570819],"luv":[46.2124513047425367,-19.0906003056708045,-100.691977769551045],"rgb":[0.2,0.4,0.866666666666666696],"xyz":[0.191661291859369476,0.154261650519304239,0.703764300459846837],"hpluv":[259.264483160570819,281.412724566330553,46.2124513047425367],"hsluv":[259.264483160570819,86.2202337385041488,46.2124513047425367]},"#3366ee":{"lch":[47.467400384741687,114.289765210034219,260.43068521754094],"luv":[47.467400384741687,-18.99960653492559,-112.699447129445844],"rgb":[0.2,0.4,0.933333333333333348],"xyz":[0.215473472125544213,0.163786522625774256,0.82917511652837006],"hpluv":[260.43068521754094,305.528142270574733,47.467400384741687],"hsluv":[260.43068521754094,89.4216395109538524,47.467400384741687]},"#3366ff":{"lch":[48.7917470574018068,125.686826272807437,261.315666926990161],"luv":[48.7917470574018068,-18.9775194272026404,-124.245853270525785],"rgb":[0.2,0.4,1],"xyz":[0.241644520535375606,0.17425494198970698,0.967009304820151905],"hpluv":[261.315666926990161,326.875761207371056,48.7917470574018068],"hsluv":[261.315666926990161,99.9999999999992184,48.7917470574018068]},"#aaee00":{"lch":[86.8465682321076713,106.130019137569278,108.773889799394041],"luv":[86.8465682321076713,-34.1562767274136,100.483479847491182],"rgb":[0.66666666666666663,0.933333333333333348,0],"xyz":[0.471503904866347523,0.696940089394355811,0.109681215241027807],"hpluv":[108.773889799394041,354.560190530248747,86.8465682321076713],"hsluv":[108.773889799394041,100.000000000002302,86.8465682321076713]},"#aaee11":{"lch":[86.8664697406872364,105.275413073012288,108.926122010215039],"luv":[86.8664697406872364,-34.1459453835818323,99.5839696515197801],"rgb":[0.66666666666666663,0.933333333333333348,0.0666666666666666657],"xyz":[0.472515570365984627,0.697344755594210719,0.115009320205783444],"hpluv":[108.926122010215039,352.296735211520456,86.8664697406872364],"hsluv":[108.926122010215039,99.0448212343627,86.8664697406872364]},"#aaee22":{"lch":[86.9033414770782286,103.701584155213482,109.21343759479339],"luv":[86.9033414770782286,-34.1269596340241961,97.9253245204656224],"rgb":[0.66666666666666663,0.933333333333333348,0.133333333333333331],"xyz":[0.474390928504461684,0.69809489884960152,0.124886206401762637],"hpluv":[109.21343759479339,348.114419217609168,86.9033414770782286],"hsluv":[109.21343759479339,97.2844700630890742,86.9033414770782286]},"#aaee33":{"lch":[86.9639927659971,101.139559122436452,109.701502859778287],"luv":[86.9639927659971,-34.0961634116812462,95.2190215245081504],"rgb":[0.66666666666666663,0.933333333333333348,0.2],"xyz":[0.47747867923691939,0.699329999142584646,0.141148360259373773],"hpluv":[109.701502859778287,341.266668172598315,86.9639927659971],"hsluv":[109.701502859778287,94.4148698146506,86.9639927659971]},"#aaee44":{"lch":[87.0514332975086091,97.5044422856038864,110.440992284795044],"luv":[87.0514332975086091,-34.052698770047833,91.3648180204122298],"rgb":[0.66666666666666663,0.933333333333333348,0.266666666666666663],"xyz":[0.481936674481138305,0.701113197240272212,0.164627135212260411],"hpluv":[110.440992284795044,331.464832239423686,87.0514332975086091],"hsluv":[110.440992284795044,90.3338544995677353,87.0514332975086091]},"#aaee55":{"lch":[87.1681505263978,92.7597711807761556,111.499860176168639],"luv":[87.1681505263978,-33.9963593100021271,86.3054036730909644],"rgb":[0.66666666666666663,0.933333333333333348,0.333333333333333315],"xyz":[0.48789908852050029,0.703498162856017,0.196029182486234327],"hpluv":[111.499860176168639,318.513853400728863,87.1681505263978],"hsluv":[111.499860176168639,84.9871568734489813,87.1681505263978]},"#aaee66":{"lch":[87.3162499846890086,86.9168013961255923,112.975973936880195],"luv":[87.3162499846890086,-33.9275471197994563,80.0215715377255492],"rgb":[0.66666666666666663,0.933333333333333348,0.4],"xyz":[0.495484084294008476,0.70653216116542028,0.235976826893378289],"hpluv":[112.975973936880195,302.308385752370668,87.3162499846890086],"hsluv":[112.975973936880195,78.3634586897027106,87.3162499846890086]},"#aaee77":{"lch":[87.4975302296396,80.0378594698754853,115.017197938190947],"luv":[87.4975302296396,-33.8472328521792534,72.5287789554594298],"rgb":[0.66666666666666663,0.933333333333333348,0.466666666666666674],"xyz":[0.504798097314210326,0.710257766373501132,0.285030628799776198],"hpluv":[115.017197938190947,282.845349503141222,87.4975302296396],"hsluv":[115.017197938190947,70.4907283307095,87.4975302296396]},"#aaee88":{"lch":[87.7135274362348838,72.2451165326571072,117.856267937731204],"luv":[87.7135274362348838,-33.7569011423620324,63.8735351149597861],"rgb":[0.66666666666666663,0.933333333333333348,0.533333333333333326],"xyz":[0.515938514416154237,0.714713933214278674,0.343703492203348393],"hpluv":[117.856267937731204,260.261444274219798,87.7135274362348838],"hsluv":[117.856267937731204,61.4321883079204412,87.7135274362348838]},"#aaee99":{"lch":[87.9655440812905312,63.7405265694191954,121.874104620002555],"luv":[87.9655440812905312,-33.6584769753751445,54.1291202131068871],"rgb":[0.66666666666666663,0.933333333333333348,0.6],"xyz":[0.528995478525226881,0.719936718857907887,0.412470169844466272],"hpluv":[121.874104620002555,234.922523447188695,87.9655440812905312],"hsluv":[121.874104620002555,51.2814060811362182,87.9655440812905312]},"#aaeeaa":{"lch":[88.2546687059401,54.8509913255605497,127.715012949237604],"luv":[88.2546687059401,-33.5542349686064441,43.3906045713616138],"rgb":[0.66666666666666663,0.933333333333333348,0.66666666666666663],"xyz":[0.544053171490479492,0.725959796044009,0.491774019461464873],"hpluv":[127.715012949237604,207.631017102058365,88.2546687059401],"hsluv":[127.715012949237604,42.8122115000723795,88.2546687059401]},"#aaeebb":{"lch":[88.5817905154621457,46.1299748711590425,136.47329364537066],"luv":[88.5817905154621457,-33.4466969972147226,31.7693726974624511],"rgb":[0.66666666666666663,0.933333333333333348,0.733333333333333282],"xyz":[0.561190763597816056,0.732814832886943712,0.582032004560106619],"hpluv":[136.47329364537066,180.106084736741337,88.5817905154621457],"hsluv":[136.47329364537066,42.5306558804052,88.5817905154621457]},"#aaeecc":{"lch":[88.947610994722524,38.5659339652702471,149.820563383504265],"luv":[88.947610994722524,-33.3385252257337896,19.3874701388989088],"rgb":[0.66666666666666663,0.933333333333333348,0.8],"xyz":[0.58048313904153781,0.740531783064432569,0.683638515230376775],"hpluv":[149.820563383504265,156.025185046421541,88.947610994722524],"hsluv":[149.820563383504265,43.7743007306855176,88.947610994722524]},"#aaeedd":{"lch":[89.3526538659385636,33.8378115459028308,169.14561851222],"luv":[89.3526538659385636,-33.2324178366612202,6.37211856022751721],"rgb":[0.66666666666666663,0.933333333333333348,0.866666666666666696],"xyz":[0.602001464592171409,0.749139113284686076,0.796968363130382773],"hpluv":[169.14561851222,142.575756051086472,89.3526538659385636],"hsluv":[169.14561851222,45.7128350403065866,89.3526538659385636]},"#aaeeee":{"lch":[89.797274219494,33.893604395025335,192.177050630060734],"luv":[89.797274219494,-33.1310138990311174,-7.14928925898844092],"rgb":[0.66666666666666663,0.933333333333333348,0.933333333333333348],"xyz":[0.625813644858346119,0.758663985391156093,0.922379179198906],"hpluv":[192.177050630060734,149.574468983420843,89.797274219494],"hsluv":[192.177050630060734,47.7079369778472326,89.797274219494]},"#aaeeff":{"lch":[90.2816673401601406,39.1749897548907384,212.508271358442045],"luv":[90.2816673401601406,-33.0368122621910558,-21.0534761464356919],"rgb":[0.66666666666666663,0.933333333333333348,1],"xyz":[0.65198469326817754,0.769132404755088817,1.06021336749068773],"hpluv":[212.508271358442045,182.211685385120148,90.2816673401601406],"hsluv":[212.508271358442045,99.9999999999910898,90.2816673401601406]},"#88ff00":{"lch":[90.2073775103659727,121.530167505498795,118.25137340908573],"luv":[90.2073775103659727,-57.5251845782800331,107.053420090856534],"rgb":[0.533333333333333326,1,0],"xyz":[0.459115501285251582,0.767520684123151,0.12395405300874715],"hpluv":[118.25137340908573,560.639311859311,90.2073775103659727],"hsluv":[118.25137340908573,100.00000000000226,90.2073775103659727]},"#88ff11":{"lch":[90.2260397586701828,120.75410845816802,118.424372307304225],"luv":[90.2260397586701828,-57.4787561773275684,106.196738640291272],"rgb":[0.533333333333333326,1,0.0666666666666666657],"xyz":[0.460127166784888686,0.767925350323005906,0.129282157973502787],"hpluv":[118.424372307304225,558.207032378019221,90.2260397586701828],"hsluv":[118.424372307304225,99.9999999999909335,90.2260397586701828]},"#88ff22":{"lch":[90.260617257984066,119.32542599803422,118.749452026898098],"luv":[90.260617257984066,-57.393189210317729,104.616342518179295],"rgb":[0.533333333333333326,1,0.133333333333333331],"xyz":[0.462002524923365743,0.768675493578396707,0.139159044169481966],"hpluv":[118.749452026898098,553.71568515647823,90.260617257984066],"hsluv":[118.749452026898098,99.9999999999907772,90.260617257984066]},"#88ff33":{"lch":[90.3174996442954665,117.001153508636776,119.297411154505227],"luv":[90.3174996442954665,-57.253701051451273,102.035697862378711],"rgb":[0.533333333333333326,1,0.2],"xyz":[0.465090275655823449,0.769910593871379834,0.155421198027093116],"hpluv":[119.297411154505227,546.370637823869743,90.3174996442954665],"hsluv":[119.297411154505227,99.9999999999907914,90.3174996442954665]},"#88ff44":{"lch":[90.399517385893148,113.706822542904789,120.117552028257023],"luv":[90.399517385893148,-57.0553255590242614,98.3561452994036074],"rgb":[0.533333333333333326,1,0.266666666666666663],"xyz":[0.469548270900042364,0.7716937919690674,0.178899972979979754],"hpluv":[120.117552028257023,535.877566613280692,90.399517385893148],"hsluv":[120.117552028257023,99.9999999999907914,90.399517385893148]},"#88ff55":{"lch":[90.5090160073098389,109.413894688598035,121.271093020798972],"luv":[90.5090160073098389,-56.7954345723420317,93.518334901057969],"rgb":[0.533333333333333326,1,0.333333333333333315],"xyz":[0.475510684939404349,0.774078757584812149,0.21030202025395367],"hpluv":[121.271093020798972,522.05545338002139,90.5090160073098389],"hsluv":[121.271093020798972,99.9999999999906493,90.5090160073098389]},"#88ff66":{"lch":[90.6479884721694,104.139810410505333,122.839359042112989],"luv":[90.6479884721694,-56.4735097148607039,87.4976731851854908],"rgb":[0.533333333333333326,1,0.4],"xyz":[0.483095680712912534,0.777112755894215468,0.250249664661097659],"hpluv":[122.839359042112989,504.839052288882328,90.6479884721694],"hsluv":[122.839359042112989,99.9999999999905498,90.6479884721694]},"#88ff77":{"lch":[90.8181461195308515,97.9515013566305441,124.934550835890477],"luv":[90.8181461195308515,-56.0909812525741813,80.3012978733306],"rgb":[0.533333333333333326,1,0.466666666666666674],"xyz":[0.49240969373311444,0.780838361102296319,0.299303466567495513],"hpluv":[124.934550835890477,484.301391198376791,90.8181461195308515],"hsluv":[124.934550835890477,99.9999999999904,90.8181461195308515]},"#88ff88":{"lch":[91.0209609702079803,90.9725812653771,127.715012949239437],"luv":[91.0209609702079803,-55.6510519447396348,71.9650676337452779],"rgb":[0.533333333333333326,1,0.533333333333333326],"xyz":[0.503550110835058295,0.785294527943073861,0.357976329971067708],"hpluv":[127.715012949239437,460.703998076760797,91.0209609702079803],"hsluv":[127.715012949239437,99.9999999999902087,91.0209609702079803]},"#88ff99":{"lch":[91.2576929391802167,83.3964386150156116,131.406800448379954],"luv":[91.2576929391802167,-55.158478848678719,62.5500454417735057],"rgb":[0.533333333333333326,1,0.6],"xyz":[0.51660707494413094,0.790517313586703074,0.426743007612185643],"hpluv":[131.406800448379954,434.595507650037121,91.2576929391802167],"hsluv":[131.406800448379954,99.9999999999900524,91.2576929391802167]},"#88ffaa":{"lch":[91.5294084976530229,75.5094657025462226,136.33125230150921],"luv":[91.5294084976530229,-54.6193101996060264,52.1383770748881048],"rgb":[0.533333333333333326,1,0.66666666666666663],"xyz":[0.531664767909383551,0.796540390772804141,0.506046857229184188],"hpluv":[136.33125230150921,406.99849880976177,91.5294084976530229],"hsluv":[136.33125230150921,99.9999999999897824,91.5294084976530229]},"#88ffbb":{"lch":[91.8369943060547911,67.7301008509963225,142.928263991524119],"luv":[91.8369943060547911,-54.0405872892441,40.8286846067776423],"rgb":[0.533333333333333326,1,0.733333333333333282],"xyz":[0.548802360016720114,0.8033954276157389,0.596304842327826],"hpluv":[142.928263991524119,379.751065707187763,91.8369943060547911],"hsluv":[142.928263991524119,99.9999999999894413,91.8369943060547911]},"#88ffcc":{"lch":[92.1811678623774498,60.665065650155249,151.731515164157571],"luv":[92.1811678623774498,-53.4300279465168941,28.7312078404662543],"rgb":[0.533333333333333326,1,0.8],"xyz":[0.568094735460441869,0.811112377793227757,0.697911352998096146],"hpluv":[151.731515164157571,356.080713038752435,92.1811678623774498],"hsluv":[151.731515164157571,99.9999999999893134,92.1811678623774498]},"#88ffdd":{"lch":[92.5624864174544371,55.1561732277505712,163.177123134509742],"luv":[92.5624864174544371,-52.7957106082625316,15.9629692256241533],"rgb":[0.533333333333333326,1,0.866666666666666696],"xyz":[0.589613061011075468,0.819719708013481263,0.811241200898102144],"hpluv":[163.177123134509742,341.369587308077,92.5624864174544371],"hsluv":[163.177123134509742,99.9999999999887,92.5624864174544371]},"#88ffee":{"lch":[92.9813549493531752,52.2127257219241301,177.098205352907513],"luv":[92.9813549493531752,-52.1457771028834927,2.64322864112605771],"rgb":[0.533333333333333326,1,0.933333333333333348],"xyz":[0.613425241277250177,0.82924458011995128,0.936652016966625367],"hpluv":[177.098205352907513,343.566349205584061,92.9813549493531752],"hsluv":[177.098205352907513,99.9999999999882,92.9813549493531752]},"#88ffff":{"lch":[93.4380337051328524,52.6732939730945162,192.177050630061075],"luv":[93.4380337051328524,-51.4881691068088543,-11.1105508416409933],"rgb":[0.533333333333333326,1,1],"xyz":[0.639596289687081598,0.839712999483884,1.07448620525840721],"hpluv":[192.177050630061075,372.044084252862206,93.4380337051328524],"hsluv":[192.177050630061075,99.9999999999874802,93.4380337051328524]},"#337700":{"lch":[44.0848685544221084,61.4877933810524127,120.932619831412623],"luv":[44.0848685544221084,-31.6065510805688668,52.7425318283298168],"rgb":[0.2,0.466666666666666674,0],"xyz":[0.0796174701869632462,0.138970102735809731,0.0226283985882975332],"hpluv":[120.932619831412623,176.985906279588789,44.0848685544221084],"hsluv":[120.932619831412623,100.000000000002217,44.0848685544221084]},"#337711":{"lch":[44.1431322932100159,59.4532082216814146,121.943929432148849],"luv":[44.1431322932100159,-31.4560442613915434,50.449987584497805],"rgb":[0.2,0.466666666666666674,0.0666666666666666657],"xyz":[0.0806291356866003645,0.139374768935664584,0.0279565035530531664],"hpluv":[121.943929432148849,170.903703930819205,44.1431322932100159],"hsluv":[121.943929432148849,95.223210781581642,44.1431322932100159]},"#337722":{"lch":[44.2508401312458517,55.8308883755444327,123.957293362486936],"luv":[44.2508401312458517,-31.1857277137109214,46.3091619851707605],"rgb":[0.2,0.466666666666666674,0.133333333333333331],"xyz":[0.0825044938250774,0.140124912191055412,0.037833389749032359],"hpluv":[123.957293362486936,160.100373243526178,44.2508401312458517],"hsluv":[123.957293362486936,86.6219708852072,44.2508401312458517]},"#337733":{"lch":[44.4273451577554681,50.2894934834324943,127.715012949239792],"luv":[44.4273451577554681,-30.7638100974309978,39.782171171385329],"rgb":[0.2,0.466666666666666674,0.2],"xyz":[0.0855922445575351271,0.141360012484038511,0.0540955436066435091],"hpluv":[127.715012949239792,143.636966976451419,44.4273451577554681],"hsluv":[127.715012949239792,73.1368174441878409,44.4273451577554681]},"#337744":{"lch":[44.6803728315295743,43.2379901525315873,134.305487238163835],"luv":[44.6803728315295743,-30.2010367205865329,30.9422231494797764],"rgb":[0.2,0.466666666666666674,0.266666666666666663],"xyz":[0.090050239801754,0.143143210581726105,0.0775743185595301477],"hpluv":[134.305487238163835,122.797079037201513,44.6803728315295743],"hsluv":[134.305487238163835,74.2422920898123664,44.6803728315295743]},"#337755":{"lch":[45.0155248592042057,35.7001949681147,145.791078733963843],"luv":[45.0155248592042057,-29.5238129364495734,20.071083439987369],"rgb":[0.2,0.466666666666666674,0.333333333333333315],"xyz":[0.096012653841116,0.145528176197470938,0.108976365833504049],"hpluv":[145.791078733963843,100.634662922797503,45.0155248592042057],"hsluv":[145.791078733963843,75.5860232244433377,45.0155248592042057]},"#337766":{"lch":[45.436632811343884,29.7520619336037022,165.22669317203713],"luv":[45.436632811343884,-28.7685269489331041,7.58663604567268468],"rgb":[0.2,0.466666666666666674,0.4],"xyz":[0.103597649614624171,0.148562174506874228,0.148924010240648025],"hpluv":[165.22669317203713,83.0902864995861847,45.436632811343884],"hsluv":[165.22669317203713,77.1054195363406194,45.436632811343884]},"#337777":{"lch":[45.9459628200325696,28.6191137838588361,192.177050630061018],"luv":[45.9459628200325696,-27.9751968985082726,-6.03672363647301413],"rgb":[0.2,0.466666666666666674,0.466666666666666674],"xyz":[0.11291166263482609,0.152287779714955052,0.197977812147045934],"hpluv":[192.177050630061018,79.0402219352416324,45.9459628200325696],"hsluv":[192.177050630061018,78.7308353184449743,45.9459628200325696]},"#337788":{"lch":[46.5443737533918309,33.948531272854666,216.805091226728479],"luv":[46.5443737533918309,-27.1818468531358306,-20.3383867904182836],"rgb":[0.2,0.466666666666666674,0.533333333333333326],"xyz":[0.124052079736769919,0.156743946555732649,0.256650675550618101],"hpluv":[216.805091226728479,92.5535593562344587,46.5443737533918309],"hsluv":[216.805091226728479,80.3955897349876381,46.5443737533918309]},"#337799":{"lch":[47.2314677007312085,43.7891028043947799,232.889035089769209],"luv":[47.2314677007312085,-26.4206199262946413,-34.9204290798973105],"rgb":[0.2,0.466666666666666674,0.6],"xyz":[0.137109043845842632,0.161966732199361807,0.325417353191736],"hpluv":[232.889035089769209,117.645124104106614,47.2314677007312085],"hsluv":[232.889035089769209,82.0429045074046144,47.2314677007312085]},"#3377aa":{"lch":[48.0057466772197472,55.756363166772573,242.534195481556935],"luv":[48.0057466772197472,-25.7159019754829359,-49.471854818395343],"rgb":[0.2,0.466666666666666674,0.66666666666666663],"xyz":[0.15216673681109516,0.167989809385462902,0.404721202808734581],"hpluv":[242.534195481556935,147.380673097935755,48.0057466772197472],"hsluv":[242.534195481556935,83.6292827510673078,48.0057466772197472]},"#3377bb":{"lch":[48.8647777502949623,68.5281348418467076,248.528316013511841],"luv":[48.8647777502949623,-25.0841318464231762,-63.7721851155626],"rgb":[0.2,0.466666666666666674,0.733333333333333282],"xyz":[0.169304328918431835,0.17484484622839766,0.494979187907376328],"hpluv":[248.528316013511841,177.955866809146045,48.8647777502949623],"hsluv":[248.528316013511841,85.1249045257873,48.8647777502949623]},"#3377cc":{"lch":[49.8053630390326845,81.4640551302433096,252.471981644912631],"luv":[49.8053630390326845,-24.5347040681135518,-77.6816617648812553],"rgb":[0.2,0.466666666666666674,0.8],"xyz":[0.188596704362153561,0.182561796405886462,0.596585698577646539],"hpluv":[252.471981644912631,207.553107999557341,49.8053630390326845],"hsluv":[252.471981644912631,86.5120902950020678,49.8053630390326845]},"#3377dd":{"lch":[50.8237086019957047,94.2508792352234,255.202895611269554],"luv":[50.8237086019957047,-24.0713820337122506,-91.1251710758325],"rgb":[0.2,0.466666666666666674,0.866666666666666696],"xyz":[0.210115029912787105,0.19116912662614,0.709915546477652537],"hpluv":[255.202895611269554,235.319753343529385,50.8237086019957047],"hsluv":[255.202895611269554,87.7828608732328,50.8237086019957047]},"#3377ee":{"lch":[51.9155858415672498,106.73807185779232,257.174602046687482],"luv":[51.9155858415672498,-23.6937959642247655,-104.075069141100855],"rgb":[0.2,0.466666666666666674,0.933333333333333348],"xyz":[0.233927210178961842,0.200693998732610041,0.83532636254617576],"hpluv":[257.174602046687482,260.892095272406607,51.9155858415672498],"hsluv":[257.174602046687482,88.9363454602875692,51.9155858415672498]},"#3377ff":{"lch":[53.0764799083082721,118.861737619173724,258.646767383963777],"luv":[53.0764799083082721,-23.3987809317452253,-116.535873106771263],"rgb":[0.2,0.466666666666666674,1],"xyz":[0.260098258588793207,0.211162418096542737,0.973160550837957605],"hpluv":[258.646767383963777,284.170694785425781,53.0764799083082721],"hsluv":[258.646767383963777,99.9999999999990763,53.0764799083082721]},"#aaff00":{"lch":[91.7137860391432156,115.080534629040301,111.722667154579099],"luv":[91.7137860391432156,-42.5929524944460596,106.908230966149674],"rgb":[0.66666666666666663,1,0],"xyz":[0.523356277296021299,0.800644834253704918,0.126965339384251918],"hpluv":[111.722667154579099,635.020942157405898,91.7137860391432156],"hsluv":[111.722667154579099,100.000000000002359,91.7137860391432156]},"#aaff11":{"lch":[91.7319300755291209,114.302910123776968,111.867287470019974],"luv":[91.7319300755291209,-42.5730312099484394,106.078707931238455],"rgb":[0.66666666666666663,1,0.0666666666666666657],"xyz":[0.524367942795658459,0.801049500453559826,0.132293444349007555],"hpluv":[111.867287470019974,632.205251281199821,91.7319300755291209],"hsluv":[111.867287470019974,99.9999999999902087,91.7319300755291209]},"#aaff22":{"lch":[91.76554812600844,112.870020698142184,112.139393409643191],"luv":[91.76554812600844,-42.5363318976714595,104.548084827461963],"rgb":[0.66666666666666663,1,0.133333333333333331],"xyz":[0.526243300934135405,0.801799643708950627,0.142170330544986734],"hpluv":[112.139393409643191,626.996151229530483,91.76554812600844],"hsluv":[112.139393409643191,99.9999999999901,91.76554812600844]},"#aaff33":{"lch":[91.8208541183991116,110.535111156119868,112.599114759903571],"luv":[91.8208541183991116,-42.4765495373732875,102.047800258971023],"rgb":[0.66666666666666663,1,0.2],"xyz":[0.529331051666593222,0.803034744001933753,0.158432484402597884],"hpluv":[112.599114759903571,618.449193227995465,91.8208541183991116],"hsluv":[112.599114759903571,99.9999999999900808,91.8208541183991116]},"#aaff44":{"lch":[91.9006031807778498,107.217215837920833,113.289723447654],"luv":[91.9006031807778498,-42.3916247074254713,98.4808688360338],"rgb":[0.66666666666666663,1,0.266666666666666663],"xyz":[0.533789046910812082,0.80481794209962132,0.181911259355484523],"hpluv":[113.289723447654,606.175591066234915,91.9006031807778498],"hsluv":[113.289723447654,99.9999999999900808,91.9006031807778498]},"#aaff55":{"lch":[92.0070808640835338,102.877427982590888,114.266397603879824],"luv":[92.0070808640835338,-42.2805422001356135,93.7876374559873796],"rgb":[0.66666666666666663,1,0.333333333333333315],"xyz":[0.539751460950174,0.807202907715366069,0.213313306629458438],"hpluv":[114.266397603879824,589.885725054723707,92.0070808640835338],"hsluv":[114.266397603879824,99.9999999999897,92.0070808640835338]},"#aaff66":{"lch":[92.142232175119787,97.5178938455906,115.604656391492952],"luv":[92.142232175119787,-42.1432392632638226,87.9413839126902559],"rgb":[0.66666666666666663,1,0.4],"xyz":[0.547336456723682252,0.810236906024769388,0.2532609510366024],"hpluv":[115.604656391492952,569.381090837871511,92.142232175119787],"hsluv":[115.604656391492952,99.9999999999898,92.142232175119787]},"#aaff77":{"lch":[92.3077308115560555,91.1840841453542197,117.412488820025033],"luv":[92.3077308115560555,-41.9805406670279666,80.9454841651530899],"rgb":[0.66666666666666663,1,0.466666666666666674],"xyz":[0.556650469743884102,0.813962511232850239,0.302314752943000309],"hpluv":[117.412488820025033,544.56608764574878,92.3077308115560555],"hsluv":[117.412488820025033,99.9999999999895692,92.3077308115560555]},"#aaff88":{"lch":[92.5050204995058749,83.9705472319660657,119.849478645386625],"luv":[92.5050204995058749,-41.7940850853900727,72.8306752289927601],"rgb":[0.66666666666666663,1,0.533333333333333326],"xyz":[0.567790886845828,0.818418678073627781,0.360987616346572504],"hpluv":[119.849478645386625,515.487838204951345,92.5050204995058749],"hsluv":[119.849478645386625,99.9999999999892708,92.5050204995058749]},"#aaff99":{"lch":[92.7353415895377,76.0327408171719,123.158131820453576],"luv":[92.7353415895377,-41.5862309318022625,63.6518897838709137],"rgb":[0.66666666666666663,1,0.6],"xyz":[0.580847850954900657,0.823641463717257,0.429754293987690383],"hpluv":[123.158131820453576,482.430180447041607,92.7353415895377],"hsluv":[123.158131820453576,99.9999999999891145,92.7353415895377]},"#aaffaa":{"lch":[92.9997492696274435,67.6109506527765802,127.715012949238414],"luv":[92.9997492696274435,-41.3599402641421108,53.4845397242865488],"rgb":[0.66666666666666663,1,0.66666666666666663],"xyz":[0.595905543920153269,0.829664540903358061,0.509058143604689],"hpluv":[127.715012949238414,446.121940639593902,92.9997492696274435],"hsluv":[127.715012949238414,99.9999999999887308,92.9997492696274435]},"#aaffbb":{"lch":[93.2991268167713201,59.0781485982363,134.10730048328],"luv":[93.2991268167713201,-41.1186450338129887,42.4203332421914823],"rgb":[0.66666666666666663,1,0.733333333333333282],"xyz":[0.613043136027489832,0.836519577746292819,0.599316128703330731],"hpluv":[134.10730048328,408.190288953842469,93.2991268167713201],"hsluv":[134.10730048328,99.9999999999883613,93.2991268167713201]},"#aaffcc":{"lch":[93.6341958749929404,51.0306218960527929,143.208028901391231],"luv":[93.6341958749929404,-40.8661030238149436,30.5628204644932246],"rgb":[0.66666666666666663,1,0.8],"xyz":[0.632335511471211587,0.844236527923781677,0.700922639373600886],"hpluv":[143.208028901391231,372.11656739719416,93.6341958749929404],"hsluv":[143.208028901391231,99.9999999999879492,93.6341958749929404]},"#aaffdd":{"lch":[94.005524978734,44.4262644213682094,156.066165366624773],"luv":[94.005524978734,-40.6062520520773305,18.0229094410556279],"rgb":[0.66666666666666663,1,0.866666666666666696],"xyz":[0.653853837021845186,0.852843858144035183,0.814252487273606884],"hpluv":[156.066165366624773,345.018188987702331,94.005524978734],"hsluv":[156.066165366624773,99.999999999986926,94.005524978734]},"#aaffee":{"lch":[94.4135370960349576,40.641316399200953,173.054449077896464],"luv":[94.4135370960349576,-40.3430708217409446,4.91459411670529711],"rgb":[0.66666666666666663,1,0.933333333333333348],"xyz":[0.677666017288019895,0.8623687302505052,0.939663303342130107],"hpluv":[173.054449077896464,339.745490646316398,94.4135370960349576],"hsluv":[173.054449077896464,99.9999999999862865,94.4135370960349576]},"#aaffff":{"lch":[94.8585166918378633,41.0030022313427764,192.177050630060705],"luv":[94.8585166918378633,-40.0804535568370639,-8.64889788711415264],"rgb":[0.66666666666666663,1,1],"xyz":[0.703837065697851316,0.872837149614437924,1.07749749163391195],"hpluv":[192.177050630060705,373.711432895013843,94.8585166918378633],"hsluv":[192.177050630060705,99.9999999999852491,94.8585166918378633]},"#338800":{"lch":[49.8717454753508918,71.2965557675853461,122.69380865426514],"luv":[49.8717454753508918,-38.5107906934601871,60.0009821960016509],"rgb":[0.2,0.533333333333333326,0],"xyz":[0.101689839911933699,0.183114842185751275,0.0299858551632874795],"hpluv":[122.69380865426514,181.406693814272955,49.8717454753508918],"hsluv":[122.69380865426514,100.000000000002245,49.8717454753508918]},"#338811":{"lch":[49.9202331837381053,69.5570511040883162,123.47043015419375],"luv":[49.9202331837381053,-38.361169332567485,58.0224443274741475],"rgb":[0.2,0.533333333333333326,0.0666666666666666657],"xyz":[0.102701505411570818,0.183519508385606128,0.0353139601280431092],"hpluv":[123.47043015419375,176.808802540010674,49.9202331837381053],"hsluv":[123.47043015419375,96.3624965314944291,49.9202331837381053]},"#338822":{"lch":[50.0099282713402,66.4316762124597915,124.985970570646856],"luv":[50.0099282713402,-38.0903182709230137,54.426971791721833],"rgb":[0.2,0.533333333333333326,0.133333333333333331],"xyz":[0.104576863550047847,0.184269651640996956,0.0451908463240223088],"hpluv":[124.985970570646856,168.561468288507513,50.0099282713402],"hsluv":[124.985970570646856,89.7672781446156876,50.0099282713402]},"#338833":{"lch":[50.1570811029395429,61.5658815699287487,127.715012949239991],"luv":[50.1570811029395429,-37.6619639194057143,48.7025076070614134],"rgb":[0.2,0.533333333333333326,0.2],"xyz":[0.10766461428250558,0.185504751933980055,0.061453000181633452],"hpluv":[127.715012949239991,155.756856758587162,50.1570811029395429],"hsluv":[127.715012949239991,79.3080015418374416,50.1570811029395429]},"#338844":{"lch":[50.3683877843642165,55.1600753981733334,132.238380805917416],"luv":[50.3683877843642165,-37.0795228857786441,40.8380080377971524],"rgb":[0.2,0.533333333333333326,0.266666666666666663],"xyz":[0.112122609526724454,0.187287950031667649,0.0849317751345200905],"hpluv":[132.238380805917416,138.965222681713072,50.3683877843642165],"hsluv":[132.238380805917416,79.9701630926319922,50.3683877843642165]},"#338855":{"lch":[50.648916869713247,47.7759983149871488,139.558488969535745],"luv":[50.648916869713247,-36.3608093871966886,30.990926990033774],"rgb":[0.2,0.533333333333333326,0.333333333333333315],"xyz":[0.118085023566086453,0.189672915647412482,0.116333822408493992],"hpluv":[139.558488969535745,119.695806374350084,50.648916869713247],"hsluv":[139.558488969535745,80.7922551095087726,50.648916869713247]},"#338866":{"lch":[51.0024095938582747,40.50700493167151,151.3112863122482],"luv":[51.0024095938582747,-35.5343950908498,19.4454162738124445],"rgb":[0.2,0.533333333333333326,0.4],"xyz":[0.125670019339594624,0.192706913956815773,0.156281466815637954],"hpluv":[151.3112863122482,100.78102351571394,51.0024095938582747],"hsluv":[151.3112863122482,81.7453783644028249,51.0024095938582747]},"#338877":{"lch":[51.4314426692160964,35.2513066472794421,169.271441625736571],"luv":[51.4314426692160964,-34.635118433957949,6.56225505495134165],"rgb":[0.2,0.533333333333333326,0.466666666666666674],"xyz":[0.134984032359796557,0.196432519164896596,0.205335268722035863],"hpluv":[169.271441625736571,86.9732781104886499,51.4314426692160964],"hsluv":[169.271441625736571,82.7938072280844182,51.4314426692160964]},"#338888":{"lch":[51.9375397067754818,34.4751674240590873,192.177050630061075],"luv":[51.9375397067754818,-33.6994920276336458,-7.27196025816705482],"rgb":[0.2,0.533333333333333326,0.533333333333333326],"xyz":[0.146124449461740358,0.200888686005674194,0.26400813212560803],"hpluv":[192.177050630061075,84.229522237058,51.9375397067754818],"hsluv":[192.177050630061075,83.8998231764876579,51.9375397067754818]},"#338899":{"lch":[52.5212658253882267,39.2899369869163,213.503984387174484],"luv":[52.5212658253882267,-32.7618132949538179,-21.68784770470414],"rgb":[0.2,0.533333333333333326,0.6],"xyz":[0.159181413570813085,0.206111471649303352,0.332774809766725965],"hpluv":[213.503984387174484,94.9260641143146415,52.5212658253882267],"hsluv":[213.503984387174484,85.0278067813718081,52.5212658253882267]},"#3388aa":{"lch":[53.1823203703714142,48.3403865273999855,228.783963154055925],"luv":[53.1823203703714142,-31.8514822326876157,-36.3631138545534753],"rgb":[0.2,0.533333333333333326,0.66666666666666663],"xyz":[0.174239106536065613,0.212134548835404446,0.412078659383724566],"hpluv":[228.783963154055925,115.340588590435829,53.1823203703714142],"hsluv":[228.783963154055925,86.1470646970195588,53.1823203703714142]},"#3388bb":{"lch":[53.9196335036436238,59.7107302664646866,238.732819450220632],"luv":[53.9196335036436238,-30.9916356267104831,-51.0381213421469],"rgb":[0.2,0.533333333333333326,0.733333333333333282],"xyz":[0.191376698643402288,0.218989585678339205,0.502336644482366257],"hpluv":[238.732819450220632,140.522147305520861,53.9196335036436238],"hsluv":[238.732819450220632,87.2332789223686262,53.9196335036436238]},"#3388cc":{"lch":[54.7314676322995268,72.1439684856409826,245.254262274299492],"luv":[54.7314676322995268,-30.1989009668194051,-65.5192992121664446],"rgb":[0.2,0.533333333333333326,0.8],"xyz":[0.210669074087124014,0.226706535855828,0.603943155152636413],"hpluv":[245.254262274299492,167.263916186866481,54.7314676322995268],"hsluv":[245.254262274299492,88.2687848362996,54.7314676322995268]},"#3388dd":{"lch":[55.6155220749816692,84.9545141717074728,249.692682338977761],"luv":[55.6155220749816692,-29.4839257322198733,-79.6741338300441697],"rgb":[0.2,0.533333333333333326,0.866666666666666696],"xyz":[0.232187399637757558,0.23531386607608154,0.717273003052642411],"hpluv":[249.692682338977761,193.833915517882872,55.6155220749816692],"hsluv":[249.692682338977761,89.2420383366021923,55.6155220749816692]},"#3388ee":{"lch":[56.5690381344568323,97.7754852991564434,252.83721230554255],"luv":[56.5690381344568323,-28.8523290085395629,-93.4215640859675602],"rgb":[0.2,0.533333333333333326,0.933333333333333348],"xyz":[0.255999579903932295,0.244838738182551585,0.842683819121165634],"hpluv":[252.83721230554255,219.32619909500923,56.5690381344568323],"hsluv":[252.83721230554255,90.146641202583325,56.5690381344568323]},"#3388ff":{"lch":[57.5889013880528182,110.410831334845568,255.145344615238457],"luv":[57.5889013880528182,-28.3057941013035759,-106.720821287817699],"rgb":[0.2,0.533333333333333326,1],"xyz":[0.282170628313763716,0.255307157546484254,0.980518007412947479],"hpluv":[255.145344615238457,243.283252172694205,57.5889013880528182],"hsluv":[255.145344615238457,99.9999999999988489,57.5889013880528182]},"#339900":{"lch":[55.5688440832231,80.82821284508357,123.866754715109295],"luv":[55.5688440832231,-45.0426054376311527,67.1145564473163603],"rgb":[0.2,0.6,0],"xyz":[0.127559440364401172,0.23485404309068697,0.0386090553141097345],"hpluv":[123.866754715109295,184.574176757765827,55.5688440832231],"hsluv":[123.866754715109295,100.00000000000226,55.5688440832231]},"#339911":{"lch":[55.6099261578814463,79.3206910999707446,124.475743785225987],"luv":[55.6099261578814463,-44.9000555787807372,65.3892731692238556],"rgb":[0.2,0.6,0.0666666666666666657],"xyz":[0.128571105864038304,0.235258709290541823,0.0439371602788653642],"hpluv":[124.475743785225987,180.997883954149785,55.6099261578814463],"hsluv":[124.475743785225987,97.1571693172972601,55.6099261578814463]},"#339922":{"lch":[55.6859569378682124,76.5942224429011418,125.649114872203555],"luv":[55.6859569378682124,-44.6406262928881503,62.240576763164114],"rgb":[0.2,0.6,0.133333333333333331],"xyz":[0.130446464002515305,0.236008852545932651,0.0538140464748445638],"hpluv":[125.649114872203555,174.537861698610129,55.6859569378682124],"hsluv":[125.649114872203555,91.9778413864117113,55.6859569378682124]},"#339933":{"lch":[55.8107903110879278,72.2971425020977563,127.715012949240148],"luv":[55.8107903110879278,-44.2266447414942618,57.191613973364035],"rgb":[0.2,0.6,0.2],"xyz":[0.133534214734973067,0.23724395283891575,0.070076200332455707],"hpluv":[127.715012949240148,164.377468022308932,55.8107903110879278],"hsluv":[127.715012949240148,83.6974291768240874,55.8107903110879278]},"#339944":{"lch":[55.9902586993563602,66.5149718399310501,131.021169741293448],"luv":[55.9902586993563602,-43.6562926505411042,50.1833597009719128],"rgb":[0.2,0.6,0.266666666666666663],"xyz":[0.137992209979191927,0.239027150936603344,0.0935549752853423455],"hpluv":[131.021169741293448,150.746162046382238,55.9902586993563602],"hsluv":[131.021169741293448,84.1112663411127386,55.9902586993563602]},"#339955":{"lch":[56.2289015921924,59.572114639014508,136.121417864766215],"luv":[56.2289015921924,-42.9401916463123783,41.2913645202220323],"rgb":[0.2,0.6,0.333333333333333315],"xyz":[0.143954624018553912,0.241412116552348177,0.124957022559316261],"hpluv":[136.121417864766215,134.438216783596687,56.2289015921924],"hsluv":[136.121417864766215,84.6329955380286236,56.2289015921924]},"#339966":{"lch":[56.5302268191487514,52.1043875673731947,143.898662284026642],"luv":[56.5302268191487514,-42.0991012865816785,30.700698275986678],"rgb":[0.2,0.6,0.4],"xyz":[0.151539619792062097,0.244446114861751468,0.164904666966460223],"hpluv":[143.898662284026642,116.958797396111564,56.5302268191487514],"hsluv":[143.898662284026642,85.2491724948614689,56.5302268191487514]},"#339977":{"lch":[56.8968484427531678,45.1992705399313124,155.596009487994166],"luv":[56.8968484427531678,-41.1609366004351855,18.6748856895258584],"rgb":[0.2,0.6,0.466666666666666674],"xyz":[0.160853632812264,0.248171720069832291,0.213958468872858132],"hpluv":[155.596009487994166,100.805108459810327,56.8968484427531678],"hsluv":[155.596009487994166,85.9413862611579873,56.8968484427531678]},"#339988":{"lch":[57.330574208667926,40.5351988689668303,172.17134267960472],"luv":[57.330574208667926,-40.1574041849560217,5.52134371985359085],"rgb":[0.2,0.6,0.533333333333333326],"xyz":[0.171994049914207858,0.252627886910609889,0.272631332276430272],"hpluv":[172.17134267960472,89.7191897797317,57.330574208667926],"hsluv":[172.17134267960472,86.6885468018933665,57.330574208667926]},"#339999":{"lch":[57.8324724587931627,40.0212192418936539,192.177050630061103],"luv":[57.8324724587931627,-39.1207602326874735,-8.44180717763071],"rgb":[0.2,0.6,0.6],"xyz":[0.185051014023280558,0.257850672554239047,0.341398009917548206],"hpluv":[192.177050630061103,87.8128114771670312,57.8324724587931627],"hsluv":[192.177050630061103,87.4690863712762194,57.8324724587931627]},"#3399aa":{"lch":[58.4029323329449568,44.4430671798845367,211.035048784986628],"luv":[58.4029323329449568,-38.0811346860811923,-22.913170914918652],"rgb":[0.2,0.6,0.66666666666666663],"xyz":[0.200108706988533114,0.263873749740340169,0.420701859534546807],"hpluv":[211.035048784986628,96.5625435737210154,58.4029323329449568],"hsluv":[211.035048784986628,88.2627766327166,58.4029323329449568]},"#3399bb":{"lch":[59.0417237507550823,52.8166449153409445,225.431517702392057],"luv":[59.0417237507550823,-37.064675814253917,-37.6272213549907448],"rgb":[0.2,0.6,0.733333333333333282],"xyz":[0.217246299095869733,0.270728786583274927,0.510959844633188554],"hpluv":[225.431517702392057,113.514439229551684,59.0417237507550823],"hsluv":[225.431517702392057,89.0519907331041196,59.0417237507550823]},"#3399cc":{"lch":[59.7480598269018373,63.5982744854026194,235.423336237979868],"luv":[59.7480598269018373,-36.0925574956591646,-52.364757336811472],"rgb":[0.2,0.6,0.8],"xyz":[0.236538674539591487,0.278445736760763729,0.612566355303458709],"hpluv":[235.423336237979868,135.070607162709791,59.7480598269018373],"hsluv":[235.423336237979868,89.8223822716188636,59.7480598269018373]},"#3399dd":{"lch":[60.5206621982976856,75.6357863680042186,242.281144195606601],"luv":[60.5206621982976856,-35.1807304699237235,-66.9558689220665286],"rgb":[0.2,0.6,0.866666666666666696],"xyz":[0.25805700009022503,0.287053066981017235,0.725896203203464707],"hpluv":[242.281144195606601,158.58531958905732,60.5206621982976856],"hsluv":[242.281144195606601,90.5630616197976508,60.5206621982976856]},"#3399ee":{"lch":[61.3578284965586818,88.2341933332873083,247.095644636752098],"luv":[61.3578284965586818,-34.3402162860227946,-81.277441019049661],"rgb":[0.2,0.6,0.933333333333333348],"xyz":[0.28186918035639974,0.296577939087487252,0.85130701927198793],"hpluv":[247.095644636752098,182.476215369006297,61.3578284965586818],"hsluv":[247.095644636752098,91.2664056494933504,61.3578284965586818]},"#3399ff":{"lch":[62.2575005434706554,100.992674077385175,250.5808182685887],"luv":[62.2575005434706554,-33.5777301361133595,-95.2473425151972],"rgb":[0.2,0.6,1],"xyz":[0.308040228766231161,0.30704635845142,0.989141207563769775],"hpluv":[250.5808182685887,205.84367033720622,62.2575005434706554],"hsluv":[250.5808182685887,99.9999999999985789,62.2575005434706554]},"#220000":{"lch":[3.07250446727781679,10.3329293192956264,12.1770506300617765],"luv":[3.07250446727781679,10.1004431663672367,2.17955870775360072],"rgb":[0.133333333333333331,0,0],"xyz":[0.00659672420629513,0.00340143591887099878,0.000309221447170077699],"hpluv":[12.1770506300617765,426.746789183125429,3.07250446727781679],"hsluv":[12.1770506300617765,100.000000000002217,3.07250446727781679]},"#220011":{"lch":[3.43803794680403607,8.12070857757986353,344.488545895364155],"luv":[3.43803794680403607,7.82492808895188574,-2.17172931202554675],"rgb":[0.133333333333333331,0,0.0666666666666666657],"xyz":[0.00760838970593225201,0.00380610211872585338,0.00563732641192570948],"hpluv":[344.488545895364155,299.724735916282839,3.43803794680403607],"hsluv":[344.488545895364155,99.9999999999976836,3.43803794680403607]},"#220022":{"lch":[4.11563957101797229,9.37475958111893348,307.715012949243601],"luv":[4.11563957101797229,5.73486236359989565,-7.41602797151862436],"rgb":[0.133333333333333331,0,0.133333333333333331],"xyz":[0.00948374784440927,0.00455624537411667124,0.0155142126079049047],"hpluv":[307.715012949243601,289.042783730483393,4.11563957101797229],"hsluv":[307.715012949243601,99.9999999999988205,4.11563957101797229]},"#220033":{"lch":[5.23130109110515384,14.2535250315243012,286.735013267555587],"luv":[5.23130109110515384,4.10424250296207127,-13.6498413654214126],"rgb":[0.133333333333333331,0,0.2],"xyz":[0.0125714985768670112,0.00579134566709978496,0.0317763664655160497],"hpluv":[286.735013267555587,345.74180296647927,5.23130109110515384],"hsluv":[286.735013267555587,99.9999999999995737,5.23130109110515384]},"#220044":{"lch":[6.84205732813722722,21.3889830656619786,277.641816515271671],"luv":[6.84205732813722722,2.84430225454687724,-21.1990221771654959],"rgb":[0.133333333333333331,0,0.266666666666666663],"xyz":[0.01702949382108589,0.0075745437647873606,0.0552551414184026882],"hpluv":[277.641816515271671,396.682237683346386,6.84205732813722722],"hsluv":[277.641816515271671,100.000000000000085,6.84205732813722722]},"#220055":{"lch":[8.95766614306443,30.4428627575942237,273.263558660643355],"luv":[8.95766614306443,1.73308321478426808,-30.3934913336449455],"rgb":[0.133333333333333331,0,0.333333333333333315],"xyz":[0.0229919078604478855,0.00995950938053219263,0.0866571886923766],"hpluv":[273.263558660643355,431.250830347711485,8.95766614306443],"hsluv":[273.263558660643355,100.000000000000242,8.95766614306443]},"#220066":{"lch":[11.2709410858812937,40.3162667149428913,270.881506896841],"luv":[11.2709410858812937,0.620249265146302853,-40.3114952920317435],"rgb":[0.133333333333333331,0,0.4],"xyz":[0.0305769036339560568,0.0129935076899355059,0.126604833099520558],"hpluv":[270.881506896841,453.899240935372916,11.2709410858812937],"hsluv":[270.881506896841,100.000000000000469,11.2709410858812937]},"#220077":{"lch":[13.6616791408408957,50.492834518379162,269.459540268375122],"luv":[13.6616791408408957,-0.476281836738408071,-50.4905881656414763],"rgb":[0.133333333333333331,0,0.466666666666666674],"xyz":[0.0398909166541579763,0.0167191128980163223,0.175658635005918468],"hpluv":[269.459540268375122,468.991527020998944,13.6616791408408957],"hsluv":[269.459540268375122,100.000000000000711,13.6616791408408957]},"#220088":{"lch":[16.0923146306383913,60.7890037695263104,268.549935621017426],"luv":[16.0923146306383913,-1.53830805749361632,-60.7695366743217278],"rgb":[0.133333333333333331,0,0.533333333333333326],"xyz":[0.0510313337561018043,0.0211752797387939132,0.234331498409490635],"hpluv":[268.549935621017426,479.34239057424071,16.0923146306383913],"hsluv":[268.549935621017426,100.000000000000711,16.0923146306383913]},"#220099":{"lch":[18.5394450926422749,71.1015482986176437,267.936483797094468],"luv":[18.5394450926422749,-2.56017951479828287,-71.0554406876254916],"rgb":[0.133333333333333331,0,0.6],"xyz":[0.0640882978651745178,0.0263980653824230742,0.30309817605060857],"hpluv":[267.936483797094468,486.655519564945394,18.5394450926422749],"hsluv":[267.936483797094468,100.000000000000739,18.5394450926422749]},"#2200aa":{"lch":[20.9885603179873783,81.3727160976321,267.505178931910336],"luv":[20.9885603179873783,-3.54207977840461252,-81.2955878012407851],"rgb":[0.133333333333333331,0,0.66666666666666663],"xyz":[0.0791459908304270598,0.0324211425685241791,0.382402025667607171],"hpluv":[267.505178931910336,491.966452636739518,20.9885603179873783],"hsluv":[267.505178931910336,100.000000000000782,20.9885603179873783]},"#2200bb":{"lch":[23.4306921856835828,91.57073581353,267.191578225858507],"luv":[23.4306921856835828,-4.48665301772878333,-91.4607544366971155],"rgb":[0.133333333333333331,0,0.733333333333333282],"xyz":[0.0962835829377637,0.0392761794114589377,0.472660010766248917],"hpluv":[267.191578225858507,495.919187528698728,23.4306921856835828],"hsluv":[267.191578225858507,100.000000000000909,23.4306921856835828]},"#2200cc":{"lch":[25.860342630381858,101.678845182637474,266.957159441292106],"luv":[25.860342630381858,-5.39738007409318588,-101.535490573545474],"rgb":[0.133333333333333331,0,0.8],"xyz":[0.115575958381485447,0.0469931295889477393,0.574266521436519],"hpluv":[266.957159441292106,498.925449111647538,25.860342630381858],"hsluv":[266.957159441292106,100.000000000000881,25.860342630381858]},"#2200dd":{"lch":[28.2742062228116282,111.689036790699618,266.777814373778199],"luv":[28.2742062228116282,-6.27782958394359714,-111.512464751476173],"rgb":[0.133333333333333331,0,0.866666666666666696],"xyz":[0.137094283932118977,0.0556004598092012733,0.687596369336525],"hpluv":[266.777814373778199,501.255846139694427,28.2742062228116282],"hsluv":[266.777814373778199,100.000000000000838,28.2742062228116282]},"#2200ee":{"lch":[30.6703766456275062,121.598437280905173,266.637867063772376],"luv":[30.6703766456275062,-7.13133722672581882,-121.389142753859758],"rgb":[0.133333333333333331,0,0.933333333333333348],"xyz":[0.160906464198293714,0.0651253319156713,0.813007185405048238],"hpluv":[266.637867063772376,503.092926092128948,30.6703766456275062],"hsluv":[266.637867063772376,100.000000000000838,30.6703766456275062]},"#2200ff":{"lch":[33.0478477502328261,131.407178056457695,266.526788769360394],"luv":[33.0478477502328261,-7.96089030872800674,-131.165813649189772],"rgb":[0.133333333333333331,0,1],"xyz":[0.187077512608125107,0.0755937512796040073,0.950841373696830083],"hpluv":[266.526788769360394,504.562807291912918,33.0478477502328261],"hsluv":[266.526788769360394,100.000000000000824,33.0478477502328261]},"#221100":{"lch":[6.69363913087575835,9.72440836304526535,42.3457761997067053],"luv":[6.69363913087575835,7.18724369375563921,6.55039282011655288],"rgb":[0.133333333333333331,0.0666666666666666657,0],"xyz":[0.00860112446722354,0.00741023644072787233,0.000977354867479528471],"hpluv":[42.3457761997067053,184.348759610596915,6.69363913087575835],"hsluv":[42.3457761997067053,100.000000000002402,6.69363913087575835]},"#221111":{"lch":[7.0591726104019763,6.19439175917428564,12.1770506300621],"luv":[7.0591726104019763,6.05502079617615863,1.30660339200560327],"rgb":[0.133333333333333331,0.0666666666666666657,0.0666666666666666657],"xyz":[0.00961278996686066103,0.00781490264058272606,0.00630545983223516],"hpluv":[12.1770506300621,111.348454543071412,7.0591726104019763],"hsluv":[12.1770506300621,26.092394217240134,7.0591726104019763]},"#221122":{"lch":[7.73677423461591474,7.55259268754738677,307.715012949245249],"luv":[7.73677423461591474,4.62018030186617779,-5.97457866985129],"rgb":[0.133333333333333331,0.0666666666666666657,0.133333333333333331],"xyz":[0.0114881481053376797,0.00856504589597354565,0.0161823460282143547],"hpluv":[307.715012949245249,123.872660774597591,7.73677423461591474],"hsluv":[307.715012949245249,42.856167926372315,7.73677423461591474]},"#221133":{"lch":[8.8238329822443653,14.9761175001236957,282.095598903329574],"luv":[8.8238329822443653,3.13814740657790647,-14.6436377390353236],"rgb":[0.133333333333333331,0.0666666666666666657,0.2],"xyz":[0.0145758988377954202,0.00980014618895665851,0.0324444998858255],"hpluv":[282.095598903329574,215.36805510923017,8.8238329822443653],"hsluv":[282.095598903329574,58.3941618505161273,8.8238329822443653]},"#221144":{"lch":[10.2463738670161,23.9334379374521049,274.255517801158362],"luv":[10.2463738670161,1.77596948547040223,-23.8674544912638211],"rgb":[0.133333333333333331,0.0666666666666666657,0.266666666666666663],"xyz":[0.0190338940820143,0.011583344286644235,0.0559232748387121364],"hpluv":[274.255517801158362,296.397281412249697,10.2463738670161],"hsluv":[274.255517801158362,70.1230959508528287,10.2463738670161]},"#221155":{"lch":[11.9365395500671561,33.3852442414483903,270.945812779521702],"luv":[11.9365395500671561,0.551083463009601,-33.3806956200430349],"rgb":[0.133333333333333331,0.0666666666666666657,0.333333333333333315],"xyz":[0.0249963081213762928,0.0139683099023890662,0.0873253221126860518],"hpluv":[270.945812779521702,354.907717298979946,11.9365395500671561],"hsluv":[270.945812779521702,78.3035236172291,11.9365395500671561]},"#221166":{"lch":[13.8282163263251512,43.1006504094303509,269.247085426223],"luv":[13.8282163263251512,-0.566362377205730683,-43.0969291176716496],"rgb":[0.133333333333333331,0.0666666666666666657,0.4],"xyz":[0.0325813038948844641,0.0170023082117923795,0.12727296651983],"hpluv":[269.247085426223,395.509560036398682,13.8282163263251512],"hsluv":[269.247085426223,83.9084652674952167,13.8282163263251512]},"#221177":{"lch":[15.8647012598499089,52.9790758801604,268.263491631539182],"luv":[15.8647012598499089,-1.60543281970815044,-52.954745458525224],"rgb":[0.133333333333333331,0.0666666666666666657,0.466666666666666674],"xyz":[0.0418953169150863836,0.0207279134198731958,0.176326768426227909],"hpluv":[268.263491631539182,423.75204448359591,15.8647012598499089],"hsluv":[268.263491631539182,87.783734282584831,15.8647012598499089]},"#221188":{"lch":[18.0016522099437424,62.9493123294311872,267.645454528547475],"luv":[18.0016522099437424,-2.58614693443793442,-62.8961665507666297],"rgb":[0.133333333333333331,0.0666666666666666657,0.533333333333333326],"xyz":[0.0530357340170302116,0.0251840802606507867,0.234999631829800076],"hpluv":[267.645454528547475,443.729139668046173,18.0016522099437424],"hsluv":[267.645454528547475,90.5156952975567464,18.0016522099437424]},"#221199":{"lch":[20.2061107483083475,72.9561611588118524,267.23334268313738],"luv":[20.2061107483083475,-3.52148568403582729,-72.8711231531918742],"rgb":[0.133333333333333331,0.0666666666666666657,0.6],"xyz":[0.066092698126102925,0.0304068659042799477,0.303766309470918],"hpluv":[267.23334268313738,458.161478440778865,20.2061107483083475],"hsluv":[267.23334268313738,92.4853336382361704,20.2061107483083475]},"#2211aa":{"lch":[22.4542330055690798,82.9584275230068471,266.945798214496847],"luv":[22.4542330055690798,-4.42007776686241449,-82.8405915576709759],"rgb":[0.133333333333333331,0.0666666666666666657,0.66666666666666663],"xyz":[0.0811503910913554671,0.0364299430903810492,0.383070159087916584],"hpluv":[266.945798214496847,468.815123306781686,22.4542330055690798],"hsluv":[266.945798214496847,93.9373181855700921,22.4542330055690798]},"#2211bb":{"lch":[24.7289983316777295,92.9268656932788701,266.737844101991243],"luv":[24.7289983316777295,-5.28796663316276483,-92.7762888698575097],"rgb":[0.133333333333333331,0.0666666666666666657,0.733333333333333282],"xyz":[0.0982879831986921138,0.0432849799333158078,0.473328144186558331],"hpluv":[266.737844101991243,476.841549380862261,24.7289983316777295],"hsluv":[266.737844101991243,95.0302193246277369,24.7289983316777295]},"#2211cc":{"lch":[27.0183279904475668,102.841627589427389,266.583003116257],"luv":[27.0183279904475668,-6.12961814831514129,-102.658794784462174],"rgb":[0.133333333333333331,0.0666666666666666657,0.8],"xyz":[0.117580358642413854,0.0510019301108046094,0.574934654856828486],"hpluv":[266.583003116257,483.002966655360069,27.0183279904475668],"hsluv":[266.583003116257,95.8686128249461689,27.0183279904475668]},"#2211dd":{"lch":[29.313669578695368,112.689841457512074,266.464886381494523],"luv":[29.313669578695368,-6.94848190374932617,-112.475414944566779],"rgb":[0.133333333333333331,0.0666666666666666657,0.866666666666666696],"xyz":[0.139098684193047384,0.0596092603310581434,0.688264502756834484],"hpluv":[266.464886381494523,487.813602393737767,29.313669578695368],"hsluv":[266.464886381494523,96.5228774582602256,29.313669578695368]},"#2211ee":{"lch":[31.6089746608533417,122.463629630364608,266.372923821556242],"luv":[31.6089746608533417,-7.74731231829930689,-122.21832814306471],"rgb":[0.133333333333333331,0.0666666666666666657,0.933333333333333348],"xyz":[0.162910864459222149,0.0691341324375281813,0.813675318825357707],"hpluv":[266.372923821556242,491.627361233059389,31.6089746608533417],"hsluv":[266.372923821556242,97.0413663214109761,31.6089746608533417]},"#2211ff":{"lch":[33.8999739889387115,132.15860685194221,266.300059947999785],"luv":[33.8999739889387115,-8.52836196764118,-131.883146789857562],"rgb":[0.133333333333333331,0.0666666666666666657,1],"xyz":[0.189081912869053514,0.0796025518014608774,0.951509507117139552],"hpluv":[266.300059947999785,494.692599475339,33.8999739889387115],"hsluv":[266.300059947999785,99.9999999999995737,33.8999739889387115]},"#77aa00":{"lch":[63.8935034159882491,78.4053265973676616,109.262687899665323],"luv":[63.8935034159882491,-25.8658938451783591,74.0158819067222424],"rgb":[0.466666666666666674,0.66666666666666663,0],"xyz":[0.219816749274909073,0.326708497135311,0.0514797056256764834],"hpluv":[109.262687899665323,155.714190603412163,63.8935034159882491],"hsluv":[109.262687899665323,100.000000000002132,63.8935034159882491]},"#77aa11":{"lch":[63.9264755829735662,77.0719876411919,109.595002167467626],"luv":[63.9264755829735662,-25.8475857965541422,72.6084952843247464],"rgb":[0.466666666666666674,0.66666666666666663,0.0666666666666666657],"xyz":[0.220828414774546206,0.32711316333516588,0.0568078105904321132],"hpluv":[109.595002167467626,152.98720995680398,63.9264755829735662],"hsluv":[109.595002167467626,97.9667163347824612,63.9264755829735662]},"#77aa22":{"lch":[63.9875253363426424,74.6349938152274603,110.235118064089221],"luv":[63.9875253363426424,-25.8142561390327501,70.0286118796271],"rgb":[0.466666666666666674,0.66666666666666663,0.133333333333333331],"xyz":[0.222703772913023207,0.32786330659055668,0.0666846967864113127],"hpluv":[110.235118064089221,148.008450888663447,63.9875253363426424],"hsluv":[110.235118064089221,94.2440053809013421,63.9875253363426424]},"#77aa33":{"lch":[64.0878403339217328,70.7199026331045,111.362593229805157],"luv":[64.0878403339217328,-25.7610573917560757,65.8610093340090685],"rgb":[0.466666666666666674,0.66666666666666663,0.2],"xyz":[0.22579152364548094,0.329098406883539807,0.0829468506440224629],"hpluv":[111.362593229805157,140.024923426145421,64.0878403339217328],"hsluv":[111.362593229805157,88.2427941375042,64.0878403339217328]},"#77aa44":{"lch":[64.2322300921174616,65.2796522257345,113.17268826837423],"luv":[64.2322300921174616,-25.6877867579927681,60.0130869576689463],"rgb":[0.466666666666666674,0.66666666666666663,0.266666666666666663],"xyz":[0.230249518889699828,0.330881604981227373,0.106425625596909101],"hpluv":[113.17268826837423,128.962712139229978,64.2322300921174616],"hsluv":[113.17268826837423,79.8488372015295482,64.2322300921174616]},"#77aa55":{"lch":[64.4245377454048338,58.3957340906732298,115.996670283872277],"luv":[64.4245377454048338,-25.5959546947607706,52.487225714952487],"rgb":[0.466666666666666674,0.66666666666666663,0.333333333333333315],"xyz":[0.236211932929061841,0.333266570596972234,0.137827672870883],"hpluv":[115.996670283872277,115.018880896771989,64.4245377454048338],"hsluv":[115.996670283872277,69.0944053471027075,64.4245377454048338]},"#77aa66":{"lch":[64.6678576456364,50.3036055521827663,120.443938093288892],"luv":[64.6678576456364,-25.4885877435648602,43.368013862617552],"rgb":[0.466666666666666674,0.66666666666666663,0.4],"xyz":[0.24379692870257,0.336300568906375552,0.177775317278026979],"hpluv":[120.443938093288892,98.707457943709727,64.6678576456364],"hsluv":[120.443938093288892,56.1391996219007723,64.6678576456364]},"#77aa77":{"lch":[64.964649263009,41.4721527505437351,127.71501294923786],"luv":[64.964649263009,-25.3699399849719889,32.8070967768157118],"rgb":[0.466666666666666674,0.66666666666666663,0.466666666666666674],"xyz":[0.253110941722771932,0.340026174114456348,0.226829119184424888],"hpluv":[127.71501294923786,81.006302212696113,64.964649263009],"hsluv":[127.71501294923786,41.2466460512923874,64.964649263009]},"#77aa88":{"lch":[65.3168057391263375,32.8409027786736161,140.238161573904051],"luv":[65.3168057391263375,-25.2451203613846147,21.004970679758074],"rgb":[0.466666666666666674,0.66666666666666663,0.533333333333333326],"xyz":[0.264251358824715732,0.344482340955233945,0.285501982587997],"hpluv":[140.238161573904051,63.8012923553667,65.3168057391263375],"hsluv":[140.238161573904051,43.6199696205744232,65.3168057391263375]},"#77aa99":{"lch":[65.7257012160132,26.4214783611449491,161.939459903532622],"luv":[65.7257012160132,-25.1196781367095241,8.19123245284666],"rgb":[0.466666666666666674,0.66666666666666663,0.6],"xyz":[0.277308322933788487,0.349705126598863103,0.354268660229114962],"hpluv":[161.939459903532622,51.0106916742292213,65.7257012160132],"hsluv":[161.939459903532622,46.1685656356417766,65.7257012160132]},"#77aaaa":{"lch":[66.1922284915170565,25.5746156232648509,192.177050630060677],"luv":[66.1922284915170565,-24.9991985449953802,-5.39453764336142338],"rgb":[0.466666666666666674,0.66666666666666663,0.66666666666666663],"xyz":[0.292366015899041,0.355728203784964225,0.433572509846113563],"hpluv":[192.177050630060677,49.0276908522131265,66.1922284915170565],"hsluv":[192.177050630060677,48.8357820868943122,66.1922284915170565]},"#77aabb":{"lch":[66.7168329685055568,31.6300901405034409,218.105494045696133],"luv":[66.7168329685055568,-24.8889541052261336,-19.519287021925777],"rgb":[0.466666666666666674,0.66666666666666663,0.733333333333333282],"xyz":[0.309503608006377662,0.362583240627899,0.523830494944755309],"hpluv":[218.105494045696133,60.1595160354738923,66.7168329685055568],"hsluv":[218.105494045696133,51.56699221483656,66.7168329685055568]},"#77aacc":{"lch":[67.2995460165272306,42.0550186755790207,233.874741843371567],"luv":[67.2995460165272306,-24.7936410920562054,-33.9691029790543908],"rgb":[0.466666666666666674,0.66666666666666663,0.8],"xyz":[0.328795983450099416,0.370300190805387786,0.625437005615025465],"hpluv":[233.874741843371567,79.2948573353567099,67.2995460165272306],"hsluv":[233.874741843371567,54.3124963748670382,67.2995460165272306]},"#77aadd":{"lch":[67.9400192524912,54.4863937886276304,243.022531341574677],"luv":[67.9400192524912,-24.7172120267711577,-48.557456046554158],"rgb":[0.466666666666666674,0.66666666666666663,0.866666666666666696],"xyz":[0.350314309000732904,0.378907521025641292,0.738766853515031463],"hpluv":[243.022531341574677,101.765770647841308,67.9400192524912],"hsluv":[243.022531341574677,60.6446157506369659,67.9400192524912]},"#77aaee":{"lch":[68.6375602707836,67.7758398266106781,248.660849953701415],"luv":[68.6375602707836,-24.6627990544268876,-63.1293181256010882],"rgb":[0.466666666666666674,0.66666666666666663,0.933333333333333348],"xyz":[0.374126489266907669,0.388432393132111309,0.864177669583554686],"hpluv":[248.660849953701415,125.300382334337471,68.6375602707836],"hsluv":[248.660849953701415,79.8712566390148453,68.6375602707836]},"#77aaff":{"lch":[69.3911697465266428,81.3794470542267874,252.380781260055755],"luv":[69.3911697465266428,-24.6327125013740549,-77.5618712878715399],"rgb":[0.466666666666666674,0.66666666666666663,1],"xyz":[0.400297537676739035,0.398900812496044033,1.00201185787533653],"hpluv":[252.380781260055755,148.816077288451226,69.3911697465266428],"hsluv":[252.380781260055755,99.9999999999980531,69.3911697465266428]},"#222200":{"lch":[12.5069288045758107,13.787646171799997,85.8743202181747307],"luv":[12.5069288045758107,0.991945128669063814,13.751917387057734],"rgb":[0.133333333333333331,0.133333333333333331,0],"xyz":[0.0123167482019914745,0.014841483910263846,0.002215896112402139],"hpluv":[85.8743202181747307,139.887458074797621,12.5069288045758107],"hsluv":[85.8743202181747307,100.000000000002359,12.5069288045758107]},"#222211":{"lch":[12.7636979604368612,8.34346759842367,85.8743202181729828],"luv":[12.7636979604368612,0.600266494900015157,8.32184665209868513],"rgb":[0.133333333333333331,0.133333333333333331,0.0666666666666666657],"xyz":[0.0133284137016285963,0.0152461501101187,0.00754400107715777046],"hpluv":[85.8743202181729828,82.9486632734846552,12.7636979604368612],"hsluv":[85.8743202181729828,59.2967120963297631,12.7636979604368612]},"#222222":{"lch":[13.2279109842717837,6.86787642036123471e-13,0],"luv":[13.2279109842717837,6.53891093021720259e-13,2.10008818196756883e-13],"rgb":[0.133333333333333331,0.133333333333333331,0.133333333333333331],"xyz":[0.0152037718401056149,0.0159962933655095202,0.0174208872731369674],"hpluv":[0,6.58825703928357502e-12,13.2279109842717837],"hsluv":[0,1.88635445986832e-12,13.2279109842717837]},"#222233":{"lch":[13.9615854376221584,10.5260121123804868,265.874320218180912],"luv":[13.9615854376221584,-0.757288539977712838,-10.4987354027615698],"rgb":[0.133333333333333331,0.133333333333333331,0.2],"xyz":[0.0182915225725633554,0.017231393658492633,0.0336830411307481106],"hpluv":[265.874320218180912,95.6683874279760431,13.9615854376221584],"hsluv":[265.874320218180912,18.6338179823007195,13.9615854376221584]},"#222244":{"lch":[14.9613810506728697,21.7214686924654536,265.874320218179207],"luv":[14.9613810506728697,-1.5627399186581008,-21.6651805001571454],"rgb":[0.133333333333333331,0.133333333333333331,0.266666666666666663],"xyz":[0.0227495178167822359,0.0190145917561802061,0.0571618160836347491],"hpluv":[265.874320218179207,184.228505509793536,14.9613810506728697],"hsluv":[265.874320218179207,35.8831222215914138,14.9613810506728697]},"#222255":{"lch":[16.2052187005970154,32.8139057554865161,265.874320218178639],"luv":[16.2052187005970154,-2.3607796110480268,-32.728873041368395],"rgb":[0.133333333333333331,0.133333333333333331,0.333333333333333315],"xyz":[0.028711931856144228,0.021399557371925039,0.0885638633576086576],"hpluv":[265.874320218178639,256.946292996249099,16.2052187005970154],"hsluv":[265.874320218178639,50.0467352240393097,16.2052187005970154]},"#222266":{"lch":[17.6604729086265309,43.5908485911403716,265.874320218178354],"luv":[17.6604729086265309,-3.13612123314657865,-43.477888915018994],"rgb":[0.133333333333333331,0.133333333333333331,0.4],"xyz":[0.0362969276296524063,0.0244335556813283505,0.128511507764752619],"hpluv":[265.874320218178354,313.207621322876264,17.6604729086265309],"hsluv":[265.874320218178354,61.00504004829466,17.6604729086265309]},"#222277":{"lch":[19.2910482951380544,54.0745009411091573,265.874320218178241],"luv":[19.2910482951380544,-3.89036222175517965,-53.9343743248547867],"rgb":[0.133333333333333331,0.133333333333333331,0.466666666666666674],"xyz":[0.0456109406498543188,0.0281591608894091669,0.177565309671150529],"hpluv":[265.874320218178241,355.693573155256843,19.2910482951380544],"hsluv":[265.874320218178241,69.2802447897283429,19.2910482951380544]},"#222288":{"lch":[21.0622605487373207,64.3390225585563371,265.874320218178184],"luv":[21.0622605487373207,-4.62883796225993471,-64.1722968492601353],"rgb":[0.133333333333333331,0.133333333333333331,0.533333333333333326],"xyz":[0.0567513577517981468,0.0326153277301867578,0.236238173074722696],"hpluv":[265.874320218178184,387.622344883614403,21.0622605487373207],"hsluv":[265.874320218178184,75.4991739133377706,21.0622605487373207]},"#222299":{"lch":[22.9434551626666803,74.4470789880776351,265.874320218178127],"luv":[22.9434551626666803,-5.35605689510984373,-74.2541596437089737],"rgb":[0.133333333333333331,0.133333333333333331,0.6],"xyz":[0.0698083218608708533,0.0378381133738159223,0.305004850715840603],"hpluv":[265.874320218178127,411.744842564929684,22.9434551626666803],"hsluv":[265.874320218178127,80.1976353712613559,22.9434551626666803]},"#2222aa":{"lch":[24.9089307040763188,84.4389391258505526,265.87432021817807],"luv":[24.9089307040763188,-6.07491614537627278,-84.2201272530844705],"rgb":[0.133333333333333331,0.133333333333333331,0.66666666666666663],"xyz":[0.0848660148261234093,0.0438611905599170238,0.384308700332839204],"hpluv":[265.87432021817807,430.157015573344836,24.9089307040763188],"hsluv":[265.87432021817807,83.7838678741945557,24.9089307040763188]},"#2222bb":{"lch":[26.937850813592469,94.3371638934954149,265.87432021817807],"luv":[26.937850813592469,-6.78703884698804139,-94.0927021354881106],"rgb":[0.133333333333333331,0.133333333333333331,0.733333333333333282],"xyz":[0.102003606933460056,0.0507162274028517823,0.47456668543148095],"hpluv":[265.87432021817807,444.384803230596,26.937850813592469],"hsluv":[265.87432021817807,86.5550863782758,26.937850813592469]},"#2222cc":{"lch":[29.0136770200274086,104.153206308830732,265.874320218178],"luv":[29.0136770200274086,-7.49324898143496743,-103.883307629821275],"rgb":[0.133333333333333331,0.133333333333333331,0.8],"xyz":[0.121295982377181782,0.058433177580340584,0.576173196101751106],"hpluv":[265.874320218178,455.521834046362642,29.0136770200274086],"hsluv":[265.874320218178,88.7243024658832695,29.0136770200274086]},"#2222dd":{"lch":[31.1234509916598299,113.892375340460845,265.874320218178],"luv":[31.1234509916598299,-8.19392849973896809,-113.597238947227837],"rgb":[0.133333333333333331,0.133333333333333331,0.866666666666666696],"xyz":[0.142814307927815326,0.067040507800594118,0.689503044001757104],"hpluv":[265.874320218178,464.350835522916555,31.1234509916598299],"hsluv":[265.874320218178,90.4439719502614565,31.1234509916598299]},"#2222ee":{"lch":[33.2570959032629503,123.556928623667645,265.874320218178],"luv":[33.2570959032629503,-8.88923982631188103,-123.236747872639071],"rgb":[0.133333333333333331,0.133333333333333331,0.933333333333333348],"xyz":[0.166626488193990063,0.0765653799070641489,0.814913860070280327],"hpluv":[265.874320218178,471.435310205520636,33.2570959032629503],"hsluv":[265.874320218178,93.8546607467714296,33.2570959032629503]},"#2222ff":{"lch":[35.4068078244889,133.147814572056944,265.874320218177957],"luv":[35.4068078244889,-9.57925119428392335,-132.802780361977625],"rgb":[0.133333333333333331,0.133333333333333331,1],"xyz":[0.192797536603821457,0.0870337992709968589,0.952748048362062172],"hpluv":[265.874320218177957,477.184793215987838,35.4068078244889],"hsluv":[265.874320218177957,99.999999999999531,35.4068078244889]},"#77bb00":{"lch":[69.0844312744863629,87.8096536524333544,113.037133893102563],"luv":[69.0844312744863629,-34.3623439699837476,80.8069588058406225],"rgb":[0.466666666666666674,0.733333333333333282,0],"xyz":[0.253771247183507853,0.394617492952509585,0.0627978715952091093],"hpluv":[113.037133893102563,161.287757631366873,69.0844312744863629],"hsluv":[113.037133893102563,100.000000000002331,69.0844312744863629]},"#77bb11":{"lch":[69.1135050244688216,86.6316159473835654,113.342165034517933],"luv":[69.1135050244688216,-34.3252912529264051,79.5412550948043275],"rgb":[0.466666666666666674,0.733333333333333282,0.0666666666666666657],"xyz":[0.254782912683144958,0.395022159152364438,0.068125976559964746],"hpluv":[113.342165034517933,159.057013433643618,69.1135050244688216],"hsluv":[113.342165034517933,98.3127503818399,69.1135050244688216]},"#77bb22":{"lch":[69.1673475306790664,84.4748154027895595,113.924619678029501],"luv":[69.1673475306790664,-34.2574435126740582,77.2167209955934197],"rgb":[0.466666666666666674,0.733333333333333282,0.133333333333333331],"xyz":[0.256658270821622,0.395772302407755239,0.0780028627559439386],"hpluv":[113.924619678029501,154.976360107776344,69.1673475306790664],"hsluv":[113.924619678029501,95.2170715716625438,69.1673475306790664]},"#77bb33":{"lch":[69.2558504240405313,80.9996568929936132,114.934551128374181],"luv":[69.2558504240405313,-34.1480550559542593,73.4496749664571666],"rgb":[0.466666666666666674,0.733333333333333282,0.2],"xyz":[0.25974602155407972,0.397007402700738365,0.0942650166135550749],"hpluv":[114.934551128374181,148.410982175614635,69.2558504240405313],"hsluv":[114.934551128374181,90.2088459481891363,69.2558504240405313]},"#77bb44":{"lch":[69.3833048234310752,76.148419012573342,116.514961433737128],"luv":[69.3833048234310752,-33.9950520676451049,68.1389620777462426],"rgb":[0.466666666666666674,0.733333333333333282,0.266666666666666663],"xyz":[0.264204016798298635,0.398790600798425932,0.117743791566441713],"hpluv":[116.514961433737128,139.266042804817573,69.3833048234310752],"hsluv":[116.514961433737128,83.166634884803841,69.3833048234310752]},"#77bb55":{"lch":[69.5531781358710788,69.9670725739878918,118.886197685461212],"luv":[69.5531781358710788,-33.7990968432466516,61.2618339356121666],"rgb":[0.466666666666666674,0.733333333333333282,0.333333333333333315],"xyz":[0.270166430837660621,0.401175566414170792,0.149145838840415629],"hpluv":[118.886197685461212,127.648598426560824,69.5531781358710788],"hsluv":[118.886197685461212,74.0801666731923092,69.5531781358710788]},"#77bb66":{"lch":[69.7683097004737647,62.6192143930699672,122.411113057511386],"luv":[69.7683097004737647,-33.5633071802414804,52.8646424591145],"rgb":[0.466666666666666674,0.733333333333333282,0.4],"xyz":[0.277751426611168806,0.404209564723574111,0.189093483247559591],"hpluv":[122.411113057511386,113.8908252780179,69.7683097004737647],"hsluv":[122.411113057511386,63.0377921091212627,69.7683097004737647]},"#77bb77":{"lch":[70.0310134677453391,54.4237865803123384,127.71501294923867],"luv":[70.0310134677453391,-33.2928991557924476,43.0526585885427053],"rgb":[0.466666666666666674,0.733333333333333282,0.466666666666666674],"xyz":[0.287065439631370711,0.407935169931654906,0.2381472851539575],"hpluv":[127.71501294923867,98.6137944921033522,70.0310134677453391],"hsluv":[127.71501294923867,50.2119979074062357,70.0310134677453391]},"#77bb88":{"lch":[70.3431390634792422,45.948041729110173,135.896820739423845],"luv":[70.3431390634792422,-32.9947227526694,31.9776610966863863],"rgb":[0.466666666666666674,0.733333333333333282,0.533333333333333326],"xyz":[0.298205856733314512,0.412391336772432504,0.296820148557529695],"hpluv":[135.896820739423845,82.8866502392756246,70.3431390634792422],"hsluv":[135.896820739423845,51.9268484553617711,70.3431390634792422]},"#77bb99":{"lch":[70.7061124793432612,38.2197788608509725,148.75629343317604],"luv":[70.7061124793432612,-32.6767203094589,19.8238100775241328],"rgb":[0.466666666666666674,0.733333333333333282,0.6],"xyz":[0.311262820842387211,0.417614122416061662,0.365586826198647574],"hpluv":[148.75629343317604,68.5915373148405,70.7061124793432612],"hsluv":[148.75629343317604,53.7921873551213565,70.7061124793432612]},"#77bbaa":{"lch":[71.1209666334754615,33.0529501718716148,168.140026251468868],"luv":[71.1209666334754615,-32.3473621836046874,6.79306078486928744],"rgb":[0.466666666666666674,0.733333333333333282,0.66666666666666663],"xyz":[0.326320513807639767,0.423637199602162784,0.444890675815646175],"hpluv":[168.140026251468868,58.9728212370576585,71.1209666334754615],"hsluv":[168.140026251468868,55.7713219876506372,71.1209666334754615]},"#77bbbb":{"lch":[71.5883672123020744,32.7520226121926044,192.177050630060876],"luv":[71.5883672123020744,-32.0151171807858432,-6.90849166534396097],"rgb":[0.466666666666666674,0.733333333333333282,0.733333333333333282],"xyz":[0.343458105914976441,0.430492236445097542,0.535148660914287921],"hpluv":[192.177050630060876,58.0543804308889762,71.5883672123020744],"hsluv":[192.177050630060876,57.8271385543864938,71.5883672123020744]},"#77bbcc":{"lch":[72.1086367753872111,38.0603267014846267,213.636027248927832],"luv":[72.1086367753872111,-31.6880044447458609,-21.0821925551758049],"rgb":[0.466666666666666674,0.733333333333333282,0.8],"xyz":[0.36275048135869814,0.438209186622586344,0.636755171584558077],"hpluv":[213.636027248927832,66.97682452789428,72.1086367753872111],"hsluv":[213.636027248927832,59.9241419588218278,72.1086367753872111]},"#77bbdd":{"lch":[72.6817787487410101,47.4106862821029651,228.567760630430627],"luv":[72.6817787487410101,-31.3732552756954277,-35.5456330249727728],"rgb":[0.466666666666666674,0.733333333333333282,0.866666666666666696],"xyz":[0.384268806909331739,0.44681651684283985,0.750085019484564075],"hpluv":[228.567760630430627,82.7732525696479371,72.6817787487410101],"hsluv":[228.567760630430627,62.0300015657167449,72.6817787487410101]},"#77bbee":{"lch":[73.3075021126589803,58.9885691422652769,238.208313348868131],"luv":[73.3075021126589803,-31.0770938488335098,-50.1384635520735316],"rgb":[0.466666666666666674,0.733333333333333282,0.933333333333333348],"xyz":[0.408080987175506449,0.456341388949309867,0.875495835553087298],"hpluv":[238.208313348868131,102.107764199280055,73.3075021126589803],"hsluv":[238.208313348868131,76.3238953534044,73.3075021126589803]},"#77bbff":{"lch":[73.9852470697490219,71.6819577745528846,244.548916872628638],"luv":[73.9852470697490219,-30.8046295043453391,-64.7254036023940102],"rgb":[0.466666666666666674,0.733333333333333282,1],"xyz":[0.43425203558533787,0.466809808313242591,1.01333002384486903],"hpluv":[244.548916872628638,122.943070755930805,73.9852470697490219],"hsluv":[244.548916872628638,99.9999999999974,73.9852470697490219]},"#223300":{"lch":[18.8330192465532917,22.9063411551717806,108.204985820955727],"luv":[18.8330192465532917,-7.15634373768739707,21.7597612446731326],"rgb":[0.133333333333333331,0.2,0],"xyz":[0.0184344702910022862,0.0270769280882856428,0.00425513680873902],"hpluv":[108.204985820955727,154.338793470845559,18.8330192465532917],"hsluv":[108.204985820955727,100.000000000002331,18.8330192465532917]},"#223311":{"lch":[19.0056890338669575,18.4529510656336271,112.754551304246377],"luv":[19.0056890338669575,-7.13731020483261602,17.0167625026225657],"rgb":[0.133333333333333331,0.2,0.0666666666666666657],"xyz":[0.0194461357906394079,0.0274815942881404957,0.0095832417734946513],"hpluv":[112.754551304246377,123.203072156705915,19.0056890338669575],"hsluv":[112.754551304246377,76.6034511576994248,19.0056890338669575]},"#223322":{"lch":[19.3213416797184507,11.6344605438365232,127.71501294923759],"luv":[19.3213416797184507,-7.11719904028337247,9.20359440474635],"rgb":[0.133333333333333331,0.2,0.133333333333333331],"xyz":[0.0213214939291164265,0.028231737543531317,0.0194601279694738491],"hpluv":[127.71501294923759,76.4096652359405084,19.3213416797184507],"hsluv":[127.71501294923759,38.9061385447444366,19.3213416797184507]},"#223333":{"lch":[19.8290945906418372,7.27996715422488894,192.177050630060677],"luv":[19.8290945906418372,-7.11617124458192585,-1.53558737438758408],"rgb":[0.133333333333333331,0.2,0.2],"xyz":[0.0244092446615741671,0.0294668378365144298,0.0357222818270849923],"hpluv":[192.177050630060677,46.5871198449043149,19.8290945906418372],"hsluv":[192.177050630060677,46.4047641905018935,19.8290945906418372]},"#223344":{"lch":[20.5377244517829496,15.5714684077650816,242.621028364370432],"luv":[20.5377244517829496,-7.16091210703038339,-13.8272183091687548],"rgb":[0.133333333333333331,0.2,0.266666666666666663],"xyz":[0.0288672399057930476,0.031250035934202,0.0592010567799716309],"hpluv":[242.621028364370432,96.2091932027738181,20.5377244517829496],"hsluv":[242.621028364370432,54.472556800898019,20.5377244517829496]},"#223355":{"lch":[21.4445377167678828,27.4997828393463344,254.670418676715883],"luv":[21.4445377167678828,-7.27014529691604761,-26.5213695644274097],"rgb":[0.133333333333333331,0.2,0.333333333333333315],"xyz":[0.0348296539451550397,0.0336350015499468358,0.0906031040539455323],"hpluv":[254.670418676715883,162.72410902482622,21.4445377167678828],"hsluv":[254.670418676715883,62.1025047738862597,21.4445377167678828]},"#223366":{"lch":[22.538163137523668,39.6650934211933617,259.172698399253136],"luv":[22.538163137523668,-7.45106225263504562,-38.9589695374422647],"rgb":[0.133333333333333331,0.2,0.4],"xyz":[0.042414649718663211,0.0366689998593501473,0.130550748461089494],"hpluv":[259.172698399253136,223.320859110196579,22.538163137523668],"hsluv":[259.172698399253136,68.7622962285398103,22.538163137523668]},"#223377":{"lch":[23.8014699151847751,51.4679604591091,261.393782909523054],"luv":[23.8014699151847751,-7.70180102721624227,-50.8884389105972517],"rgb":[0.133333333333333331,0.2,0.466666666666666674],"xyz":[0.0517286627388651304,0.0403946050674309637,0.179604550367487403],"hpluv":[261.393782909523054,274.392670476726266,23.8014699151847751],"hsluv":[261.393782909523054,74.3066649079193837,23.8014699151847751]},"#223388":{"lch":[25.214303338898695,62.8010579136007649,262.667168962641028],"luv":[25.214303338898695,-8.01548446335257658,-62.2874376089207189],"rgb":[0.133333333333333331,0.2,0.533333333333333326],"xyz":[0.0628690798408089585,0.0448507719082085615,0.238277413771059571],"hpluv":[262.667168962641028,316.052560368409843,25.214303338898695],"hsluv":[262.667168962641028,78.8060188103052184,25.214303338898695]},"#223399":{"lch":[26.7557115473943199,73.7050787305795723,263.468936800572067],"luv":[26.7557115473943199,-8.38335327394953111,-73.2267575314180732],"rgb":[0.133333333333333331,0.2,0.6],"xyz":[0.0759260439498816719,0.0500735575518377191,0.307044091412177478],"hpluv":[263.468936800572067,349.558796760350788,26.7557115473943199],"hsluv":[263.468936800572067,82.4151943494814105,26.7557115473943199]},"#2233aa":{"lch":[28.4055164492709622,84.2578478733767184,264.007358934798901],"luv":[28.4055164492709622,-8.79658068794244485,-83.7974050699281],"rgb":[0.133333333333333331,0.2,0.66666666666666663],"xyz":[0.090983736915134214,0.0560966347379388205,0.386347941029176078],"hpluv":[264.007358934798901,376.397732872534505,28.4055164492709622],"hsluv":[264.007358934798901,85.301735461295209,28.4055164492709622]},"#2233bb":{"lch":[30.1452579578322855,94.5340435151979506,264.386468786418391],"luv":[30.1452579578322855,-9.24712484322681583,-94.0806891209195868],"rgb":[0.133333333333333331,0.2,0.733333333333333282],"xyz":[0.108121329022470861,0.0629516715808735861,0.476605926127817825],"hpluv":[264.386468786418391,397.931717533943186,30.1452579578322855],"hsluv":[264.386468786418391,87.6154589527103553,30.1452579578322855]},"#2233cc":{"lch":[31.9586404471462444,104.593501952517812,264.663323368501551],"luv":[31.9586404471462444,-9.72802821613955615,-104.140127317558722],"rgb":[0.133333333333333331,0.2,0.8],"xyz":[0.127413704466192601,0.0706686217583623877,0.578212436798088],"hpluv":[264.663323368501551,415.294074833826699,31.9586404471462444],"hsluv":[264.663323368501551,89.4797268300864,31.9586404471462444]},"#2233dd":{"lch":[33.8316358854510284,114.480561125644712,264.87147297862515],"luv":[33.8316358854510284,-10.233440845943651,-114.022259072932982],"rgb":[0.133333333333333331,0.2,0.866666666666666696],"xyz":[0.148932030016826145,0.0792759519786159217,0.691542284698094],"hpluv":[264.87147297862515,429.386195390892226,33.8316358854510284],"hsluv":[264.87147297862515,90.9921469937159,33.8316358854510284]},"#2233ee":{"lch":[35.7523793143002209,124.226868169083772,265.031742065807748],"luv":[35.7523793143002209,-10.7585230682670669,-123.760126682580946],"rgb":[0.133333333333333331,0.2,0.933333333333333348],"xyz":[0.172744210283000882,0.0888008240850859387,0.816953100766617202],"hpluv":[265.031742065807748,440.909964314972513,35.7523793143002209],"hsluv":[265.031742065807748,93.1343838757889557,35.7523793143002209]},"#2233ff":{"lch":[37.7109573358094536,133.854664271403067,265.157628752861342],"luv":[37.7109573358094536,-11.2993072928814158,-133.376897556927247],"rgb":[0.133333333333333331,0.2,1],"xyz":[0.198915258692832275,0.0992692434490186487,0.954787289058399],"hpluv":[265.157628752861342,450.407151983715153,37.7109573358094536],"hsluv":[265.157628752861342,99.9999999999994884,37.7109573358094536]},"#77cc00":{"lch":[74.2578384949046892,97.2071675743180776,115.806356387580706],"luv":[74.2578384949046892,-42.3172913249353897,87.5127435448238202],"rgb":[0.466666666666666674,0.8,0],"xyz":[0.291994990493124773,0.47106497957174448,0.0755391193650810505],"hpluv":[115.806356387580706,166.109821583261578,74.2578384949046892],"hsluv":[115.806356387580706,100.000000000002331,74.2578384949046892]},"#77cc11":{"lch":[74.283676291108776,96.1575231653334441,116.077287726142885],"luv":[74.283676291108776,-42.2692272766684525,86.3688698937585144],"rgb":[0.466666666666666674,0.8,0.0666666666666666657],"xyz":[0.293006655992761877,0.471469645771599333,0.0808672243298366872],"hpluv":[116.077287726142885,164.2590118749402,74.283676291108776],"hsluv":[116.077287726142885,98.5840266713216522,74.283676291108776]},"#77cc22":{"lch":[74.3315335987815331,94.2328042547367914,116.591431825394338],"luv":[74.3315335987815331,-42.1809937248656581,84.2649699821603519],"rgb":[0.466666666666666674,0.8,0.133333333333333331],"xyz":[0.294882014131238934,0.472219789026990133,0.0907441105258158798],"hpluv":[116.591431825394338,160.867513369155,74.3315335987815331],"hsluv":[116.591431825394338,95.9817736999432611,74.3315335987815331]},"#77cc33":{"lch":[74.410219680569412,91.1231466477069176,117.473161926834081],"luv":[74.410219680569412,-42.0381214847294515,80.8469182901527148],"rgb":[0.466666666666666674,0.8,0.2],"xyz":[0.29796976486369664,0.47345488931997326,0.10700626438342703],"hpluv":[117.473161926834081,155.394430123968846,74.410219680569412],"hsluv":[117.473161926834081,91.7599970515073551,74.410219680569412]},"#77cc44":{"lch":[74.5235830687713445,86.7634188586395,118.828926444460791],"luv":[74.5235830687713445,-41.8369758074171045,76.0102513305232748],"rgb":[0.466666666666666674,0.8,0.266666666666666663],"xyz":[0.302427760107915555,0.475238087417660826,0.130485039336313668],"hpluv":[118.828926444460791,147.734611978654129,74.5235830687713445],"hsluv":[118.828926444460791,85.7987877580492153,74.5235830687713445]},"#77cc55":{"lch":[74.6747602628398,81.1723246922669688,120.810965560633605],"luv":[74.6747602628398,-41.5770530159641396,69.7158156981220571],"rgb":[0.466666666666666674,0.8,0.333333333333333315],"xyz":[0.30839017414727754,0.477623053033405687,0.161887086610287556],"hpluv":[120.810965560633605,137.934680546119694,74.6747602628398],"hsluv":[120.810965560633605,78.0638956664307671,74.6747602628398]},"#77cc66":{"lch":[74.866352492363319,74.4599116278811692,123.651008617564372],"luv":[74.866352492363319,-41.2606832822808798,61.982533464768764],"rgb":[0.466666666666666674,0.8,0.4],"xyz":[0.315975169920785726,0.480657051342809,0.201834731017431546],"hpluv":[123.651008617564372,126.204595224585091,74.866352492363319],"hsluv":[123.651008617564372,68.5978490432360388,74.866352492363319]},"#77cc77":{"lch":[75.1005189251371519,66.8471540376336719,127.715012949239053],"luv":[75.1005189251371519,-40.8926996459993219,52.8803282761483189],"rgb":[0.466666666666666674,0.8,0.466666666666666674],"xyz":[0.325289182940987631,0.484382656550889801,0.250888532923829455],"hpluv":[127.715012949239053,112.948199149412858,75.1005189251371519],"hsluv":[127.715012949239053,57.5107647824030153,75.1005189251371519]},"#77cc88":{"lch":[75.3790318815133,58.7087525381891311,133.590980823477452],"luv":[75.3790318815133,-40.4800101313413947,42.5215992685696946],"rgb":[0.466666666666666674,0.8,0.533333333333333326],"xyz":[0.336429600042931432,0.488838823391667399,0.309561396327401595],"hpluv":[133.590980823477452,98.8306436104363542,75.3790318815133],"hsluv":[133.590980823477452,58.7660231359317748,75.3790318815133]},"#77cc99":{"lch":[75.7033128937519848,50.6622606125816759,142.200076129410462],"luv":[75.7033128937519848,-40.0310804193600305,31.0512036938324556],"rgb":[0.466666666666666674,0.8,0.6],"xyz":[0.349486564152004187,0.494061609035296556,0.378328073968519529],"hpluv":[142.200076129410462,84.9198084445103802,75.7033128937519848],"hsluv":[142.200076129410462,60.1459848784672815,75.7033128937519848]},"#77ccaa":{"lch":[76.0744587192654,43.7254195479873289,154.773618890386814],"luv":[76.0744587192654,-39.5553661600219684,18.6355928962322395],"rgb":[0.466666666666666674,0.8,0.66666666666666663],"xyz":[0.364544257117256687,0.500084686221397678,0.45763192358551813],"hpluv":[154.773618890386814,73.067319501552376,76.0744587192654],"hsluv":[154.773618890386814,61.6269813218812459,76.0744587192654]},"#77ccbb":{"lch":[76.4932621718819235,39.4413790272598561,172.054536865796422],"luv":[76.4932621718819235,-39.0627454070693716,5.45199970968949721],"rgb":[0.466666666666666674,0.8,0.733333333333333282],"xyz":[0.381681849224593361,0.506939723064332437,0.547889908684159876],"hpluv":[172.054536865796422,67.3385729198675733,76.4932621718819235],"hsluv":[172.054536865796422,63.1840553036415713,76.4932621718819235]},"#77cccc":{"lch":[76.9602305249106,39.4506200876857847,192.177050630060961],"luv":[76.9602305249106,-38.5629992967744357,-8.32144882456723778],"rgb":[0.466666666666666674,0.8,0.8],"xyz":[0.400974224668315116,0.514656673241821183,0.64949641935443],"hpluv":[192.177050630060961,69.0111626451701312,76.9602305249106],"hsluv":[192.177050630060961,64.792316690459316,76.9602305249106]},"#77ccdd":{"lch":[77.4756030772436475,44.2250390945155942,210.602473757279853],"luv":[77.4756030772436475,-38.0653777824919359,-22.5140200139291444],"rgb":[0.466666666666666674,0.8,0.866666666666666696],"xyz":[0.422492550218948604,0.5232640034620748,0.762826267254436],"hpluv":[210.602473757279853,79.5030322309331439,77.4756030772436475],"hsluv":[210.602473757279853,66.4280770246703156,77.4756030772436475]},"#77ccee":{"lch":[78.0393687787239116,52.7144148097026246,224.531483635923479],"luv":[78.0393687787239116,-37.5782716813780482,-36.9686762837126182],"rgb":[0.466666666666666674,0.8,0.933333333333333348],"xyz":[0.446304730485123369,0.532788875568544817,0.888237083322959253],"hpluv":[224.531483635923479,97.6926138158747648,78.0393687787239116],"hsluv":[224.531483635923479,71.3781641956177282,78.0393687787239116]},"#77ccff":{"lch":[78.6512843692400736,63.5145451324089052,234.249283216901347],"luv":[78.6512843692400736,-37.1089966152940249,-51.5462880679385549],"rgb":[0.466666666666666674,0.8,1],"xyz":[0.472475778894954734,0.54325729493247743,1.0260712716147411],"hpluv":[234.249283216901347,121.749546403725816,78.6512843692400736],"hsluv":[234.249283216901347,99.9999999999968168,78.6512843692400736]},"#224400":{"lch":[25.1809799681870601,33.4179584834008523,116.999863609689683],"luv":[25.1809799681870601,-15.1713647924420147,29.7756551486773162],"rgb":[0.133333333333333331,0.266666666666666663,0],"xyz":[0.0272670407739683193,0.0447420690542179589,0.00719932696972761486],"hpluv":[116.999863609689683,168.401755360818214,25.1809799681870601],"hsluv":[116.999863609689683,100.000000000002217,25.1809799681870601]},"#224411":{"lch":[25.304760275593587,29.8643723317269938,120.153298663054528],"luv":[25.304760275593587,-15.0013316265206242,25.8232605261065515],"rgb":[0.133333333333333331,0.266666666666666663,0.0666666666666666657],"xyz":[0.0282787062736054411,0.0451467352540728117,0.0125274319344832463],"hpluv":[120.153298663054528,149.758158325470362,25.304760275593587],"hsluv":[120.153298663054528,85.5029145399767287,25.304760275593587]},"#224422":{"lch":[25.5322735505540379,24.0578500603585184,127.715012949239281],"luv":[25.5322735505540379,-14.7170130248608242,19.0312815425753499],"rgb":[0.133333333333333331,0.266666666666666663,0.133333333333333331],"xyz":[0.0301540644120824597,0.0458968785094636331,0.0224043181304624424],"hpluv":[127.715012949239281,119.565711231297882,25.5322735505540379],"hsluv":[127.715012949239281,60.8802579098014363,25.5322735505540379]},"#224433":{"lch":[25.9015299317797343,16.981905402382786,147.498859327993841],"luv":[25.9015299317797343,-14.3222120947549634,9.12465625699578098],"rgb":[0.133333333333333331,0.266666666666666663,0.2],"xyz":[0.0332418151445402,0.0471319788024467459,0.0386664719880735891],"hpluv":[147.498859327993841,83.1955939146196357,25.9015299317797343],"hsluv":[147.498859327993841,64.09678513773909,25.9015299317797343]},"#224444":{"lch":[26.423438440277998,14.1959776348833024,192.177050630061],"luv":[26.423438440277998,-13.8765746732054378,-2.99440417262938974],"rgb":[0.133333333333333331,0.266666666666666663,0.266666666666666663],"xyz":[0.0376998103887590807,0.048915176900134319,0.0621452469409602276],"hpluv":[192.177050630061,68.1734546180548762,26.423438440277998],"hsluv":[192.177050630061,67.9066037165366367,26.423438440277998]},"#224455":{"lch":[27.1020089847707979,21.1158760403194243,230.453768193421723],"luv":[27.1020089847707979,-13.4444916811297333,-16.2826860310628518],"rgb":[0.133333333333333331,0.266666666666666663,0.333333333333333315],"xyz":[0.0436622244281210728,0.0513001425158791519,0.0935472942149341291],"hpluv":[230.453768193421723,98.865995891455,27.1020089847707979],"hsluv":[230.453768193421723,71.8953118433392717,27.1020089847707979]},"#224466":{"lch":[27.935501760142138,32.6185654266362306,246.366656325875056],"luv":[27.935501760142138,-13.0762038460066634,-29.8828329224226863],"rgb":[0.133333333333333331,0.266666666666666663,0.4],"xyz":[0.0512472202016292511,0.0543341408252824634,0.133494938622078091],"hpluv":[246.366656325875056,148.165710166053657,27.935501760142138],"hsluv":[246.366656325875056,75.7322080769735351,27.935501760142138]},"#224477":{"lch":[28.9175817086007072,45.1016041758277453,253.511262930840303],"luv":[28.9175817086007072,-12.8010466495854338,-43.2468253621948548],"rgb":[0.133333333333333331,0.266666666666666663,0.466666666666666674],"xyz":[0.0605612332218311636,0.0580597460333632798,0.182548740528476],"hpluv":[253.511262930840303,197.910731630760921,28.9175817086007072],"hsluv":[253.511262930840303,79.2164102145581381,28.9175817086007072]},"#224488":{"lch":[30.0385370730522183,57.5093846577101502,257.31357801273],"luv":[30.0385370730522183,-12.6299243743950456,-56.1053859625395432],"rgb":[0.133333333333333331,0.266666666666666663,0.533333333333333326],"xyz":[0.0717016503237749847,0.0625159128741408776,0.241221603932048168],"hpluv":[257.31357801273,242.94013543841632,30.0385370730522183],"hsluv":[257.31357801273,82.2624245727818106,30.0385370730522183]},"#224499":{"lch":[31.2864747985506213,69.5224780150470139,259.59064804278853],"luv":[31.2864747985506213,-12.5612993437317204,-68.3782765807230675],"rgb":[0.133333333333333331,0.266666666666666663,0.6],"xyz":[0.084758614432847712,0.0677386985177700351,0.309988281573166102],"hpluv":[259.59064804278853,281.973268281811727,31.2864747985506213],"hsluv":[259.59064804278853,84.8626039888072796,31.2864747985506213]},"#2244aa":{"lch":[32.6483868166792277,81.0719578322086676,261.068394107427196],"luv":[32.6483868166792277,-12.5868550230291323,-80.0889095154670372],"rgb":[0.133333333333333331,0.266666666666666663,0.66666666666666663],"xyz":[0.0998163073981002402,0.0737617757038711297,0.389292131190164703],"hpluv":[261.068394107427196,315.099896322028769,32.6483868166792277],"hsluv":[261.068394107427196,87.0515845849570695,32.6483868166792277]},"#2244bb":{"lch":[34.1110146972578292,92.183713113584,262.084105297610279],"luv":[34.1110146972578292,-12.6954785449376448,-91.3053217940914266],"rgb":[0.133333333333333331,0.266666666666666663,0.733333333333333282],"xyz":[0.116953899505436887,0.0806168125468058883,0.479550116288806449],"hpluv":[262.084105297610279,342.924793116778346,34.1110146972578292],"hsluv":[262.084105297610279,88.8814901896574128,34.1110146972578292]},"#2244cc":{"lch":[35.6614866183058439,102.915147630289923,262.812952152813068],"luv":[35.6614866183058439,-12.875606592693158,-102.106544191029045],"rgb":[0.133333333333333331,0.266666666666666663,0.8],"xyz":[0.136246274949158641,0.0883337627242946899,0.58115662695907655],"hpluv":[262.812952152813068,366.200711918304478,35.6614866183058439],"hsluv":[262.812952152813068,90.4075680541016453,35.6614866183058439]},"#2244dd":{"lch":[37.2877389569632456,113.32806156453313,263.353781276912969],"luv":[37.2877389569632456,-13.1164125913708496,-112.566465959927598],"rgb":[0.133333333333333331,0.266666666666666663,0.866666666666666696],"xyz":[0.157764600499792185,0.0969410929445482239,0.694486474859082548],"hpluv":[263.353781276912969,385.665452845521429,37.2877389569632456],"hsluv":[263.353781276912969,91.6811227311716408,37.2877389569632456]},"#2244ee":{"lch":[38.9787575249373575,123.477944203962494,263.76603971616106],"luv":[38.9787575249373575,-13.4082956886680194,-122.74779147325674],"rgb":[0.133333333333333331,0.266666666666666663,0.933333333333333348],"xyz":[0.181576780765966922,0.106465965051018269,0.819897290927605771],"hpluv":[263.76603971616106,401.976556214066079,38.9787575249373575],"hsluv":[263.76603971616106,92.7467647141115208,38.9787575249373575]},"#2244ff":{"lch":[40.7246816385265333,133.410810959437413,264.087324287658078],"luv":[40.7246816385265333,-13.7429938745542355,-132.701072340123574],"rgb":[0.133333333333333331,0.266666666666666663,1],"xyz":[0.207747829175798315,0.116934384414950965,0.957731479219387616],"hpluv":[264.087324287658078,415.692943868353552,40.7246816385265333],"hsluv":[264.087324287658078,99.9999999999994174,40.7246816385265333]},"#77dd00":{"lch":[79.4046595803128525,106.500737968556749,117.886764510297155],"luv":[79.4046595803128525,-49.8131268255250319,94.1332012826045457],"rgb":[0.466666666666666674,0.866666666666666696,0],"xyz":[0.3346289810403,0.556332960666096,0.089750449547472369],"hpluv":[117.886764510297155,213.048114553231642,79.4046595803128525],"hsluv":[117.886764510297155,100.000000000002288,79.4046595803128525]},"#77dd11":{"lch":[79.427785829561941,105.558219679332908,118.124490997004173],"luv":[79.427785829561941,-49.7589732732473422,93.0944806133132801],"rgb":[0.466666666666666674,0.866666666666666696,0.0666666666666666657],"xyz":[0.335640646539937082,0.556737626865951,0.095078554512228],"hpluv":[118.124490997004173,211.44368721760469,79.427785829561941],"hsluv":[118.124490997004173,98.7993418471683498,79.427785829561941]},"#77dd22":{"lch":[79.4706261070012658,103.827566318990023,118.57359388187615],"luv":[79.4706261070012658,-49.6593926395600249,91.1817319993116],"rgb":[0.466666666666666674,0.866666666666666696,0.133333333333333331],"xyz":[0.337516004678414139,0.557487770121341764,0.104955440708207198],"hpluv":[118.57359388187615,208.49071074424171,79.4706261070012658],"hsluv":[118.57359388187615,96.5898934808467,79.4706261070012658]},"#77dd33":{"lch":[79.5410783702752582,101.02472031386101,119.337697767432388],"luv":[79.5410783702752582,-49.4976803830995067,88.0680063995226874],"rgb":[0.466666666666666674,0.866666666666666696,0.2],"xyz":[0.340603755410871845,0.55872287041432489,0.121217594565818348],"hpluv":[119.337697767432388,203.689012727245881,79.5410783702752582],"hsluv":[119.337697767432388,92.9973786049096276,79.5410783702752582]},"#77dd44":{"lch":[79.6426121547728485,97.0801788178617073,120.498016398630853],"luv":[79.6426121547728485,-49.2690191092090188,83.6488187323909642],"rgb":[0.466666666666666674,0.866666666666666696,0.266666666666666663],"xyz":[0.34506175065509076,0.560506068512012456,0.144696369518705],"hpluv":[120.498016398630853,196.890303230407255,79.6426121547728485],"hsluv":[120.498016398630853,87.9077551580221126,79.6426121547728485]},"#77dd55":{"lch":[79.7780740091910729,91.9929116678805912,122.163902680224],"luv":[79.7780740091910729,-48.9717875622404577,77.8746417012192325],"rgb":[0.466666666666666674,0.866666666666666696,0.333333333333333315],"xyz":[0.351024164694452745,0.562891034127757206,0.176098416792678902],"hpluv":[122.163902680224,188.049297266091,79.7780740091910729],"hsluv":[122.163902680224,81.2740392578912889,79.7780740091910729]},"#77dd66":{"lch":[79.9498479155991788,85.8342168020908645,124.492086237753256],"luv":[79.9498479155991788,-48.6072648253697466,70.7449403153661],"rgb":[0.466666666666666674,0.866666666666666696,0.4],"xyz":[0.35860916046796093,0.565925032437160525,0.216046061199822836],"hpluv":[124.492086237753256,177.233761467474238,79.9498479155991788],"hsluv":[124.492086237753256,73.1095665987697174,79.9498479155991788]},"#77dd77":{"lch":[80.1599403321921,78.7586110849663896,127.715012949239352],"luv":[80.1599403321921,-48.1793469594900188,62.3030444407821093],"rgb":[0.466666666666666674,0.866666666666666696,0.466666666666666674],"xyz":[0.367923173488162836,0.569650637645241376,0.265099863106220746],"hpluv":[127.715012949239352,164.652954432832814,80.1599403321921],"hsluv":[127.715012949239352,63.4818861677236654,80.1599403321921]},"#77dd88":{"lch":[80.4100305893493754,71.0258644695610855,132.183293417803185],"luv":[80.4100305893493754,-47.69419139775556,52.6301959958607597],"rgb":[0.466666666666666674,0.866666666666666696,0.533333333333333326],"xyz":[0.379063590590106636,0.574106804486018918,0.323772726509792941],"hpluv":[132.183293417803185,150.716476916292407,80.4100305893493754],"hsluv":[132.183293417803185,64.4129914780986184,80.4100305893493754]},"#77dd99":{"lch":[80.7015034668449829,63.0436351039456042,138.421724913218469],"luv":[80.7015034668449829,-47.1597772740100254,41.838443261971527],"rgb":[0.466666666666666674,0.866666666666666696,0.6],"xyz":[0.392120554699179391,0.579329590129648131,0.39253940415091082],"hpluv":[138.421724913218469,136.149613262507529,80.7015034668449829],"hsluv":[138.421724913218469,65.4455974050235909,80.7015034668449829]},"#77ddaa":{"lch":[81.0354720941451916,55.4433276111880673,147.164903113494319],"luv":[81.0354720941451916,-46.5854032558204594,30.0626475895607292],"rgb":[0.466666666666666674,0.866666666666666696,0.66666666666666663],"xyz":[0.407178247664431892,0.585352667315749198,0.471843253767909421],"hpluv":[147.164903113494319,122.204418643173668,81.0354720941451916],"hsluv":[147.164903113494319,66.5644374268903505,81.0354720941451916]},"#77ddbb":{"lch":[81.4127955433910415,49.1817473647014651,159.215751775487576],"luv":[81.4127955433910415,-45.9811599326092804,17.452140415923953],"rgb":[0.466666666666666674,0.866666666666666696,0.733333333333333282],"xyz":[0.424315839771768566,0.592207704158684,0.562101238866551167],"hpluv":[159.215751775487576,110.971854928909636,81.4127955433910415],"hsluv":[159.215751775487576,67.7527973989238461,81.4127955433910415]},"#77ddcc":{"lch":[81.8340936239464298,45.5480287935550479,174.756411210455894],"luv":[81.8340936239464298,-45.3574175840417197,4.16264304083146897],"rgb":[0.466666666666666674,0.866666666666666696,0.8],"xyz":[0.44360821521549032,0.599924654336172813,0.663707749536821323],"hpluv":[174.756411210455894,105.54602277980743,81.8340936239464298],"hsluv":[174.756411210455894,68.9933910523739371,81.8340936239464298]},"#77dddd":{"lch":[82.299760373596115,45.7538051586653296,192.177050630060847],"luv":[82.299760373596115,-44.7243656053231931,-9.65100034703627],"rgb":[0.466666666666666674,0.866666666666666696,0.866666666666666696],"xyz":[0.465126540766123808,0.60853198455642632,0.777037597436827321],"hpluv":[192.177050630060847,109.256318691998032,82.299760373596115],"hsluv":[192.177050630060847,70.2691471280789557,82.299760373596115]},"#77ddee":{"lch":[82.8099771424448221,50.1244355238275574,208.400620203695752],"luv":[82.8099771424448221,-44.0916301090396274,-23.8408722766172367],"rgb":[0.466666666666666674,0.866666666666666696,0.933333333333333348],"xyz":[0.488938721032298573,0.618056856662896337,0.902448413505350544],"hpluv":[208.400620203695752,123.794681382199428,82.8099771424448221],"hsluv":[208.400620203695752,71.5638635335918,82.8099771424448221]},"#77ddff":{"lch":[83.364725787715372,57.9146258331384161,221.361714592462022],"luv":[83.364725787715372,-43.4679842885535521,-38.2705921992655504],"rgb":[0.466666666666666674,0.866666666666666696,1],"xyz":[0.515109769442129939,0.628525276026829061,1.0402826017971325],"hpluv":[221.361714592462022,148.517135389694232,83.364725787715372],"hsluv":[221.361714592462022,99.9999999999953531,83.364725787715372]},"#225500":{"lch":[31.4325909084541877,43.9203091385023825,121.065637009975248],"luv":[31.4325909084541877,-22.6637443991712324,37.6211143459447541],"rgb":[0.133333333333333331,0.333333333333333315,0],"xyz":[0.0390802974883142848,0.0683685824829102229,0.0111370792078428239],"hpluv":[121.065637009975248,177.306450001223254,31.4325909084541877],"hsluv":[121.065637009975248,100.000000000002373,31.4325909084541877]},"#225511":{"lch":[31.5259896590935043,41.027632513747335,123.178290947815412],"luv":[31.5259896590935043,-22.452213479362328,34.3389682366875704],"rgb":[0.133333333333333331,0.333333333333333315,0.0666666666666666657],"xyz":[0.04009196298795141,0.0687732486827650757,0.0164651841725984571],"hpluv":[123.178290947815412,165.138012967735222,31.5259896590935043],"hsluv":[123.178290947815412,90.3912533003173877,31.5259896590935043]},"#225522":{"lch":[31.6981615382414716,36.1013694166085486,127.715012949239792],"luv":[31.6981615382414716,-22.0844473877159331,28.5584673491706482],"rgb":[0.133333333333333331,0.333333333333333315,0.133333333333333331],"xyz":[0.0419673211264284252,0.0695233919381558901,0.0263420703685776497],"hpluv":[127.715012949239792,144.520324593974209,31.6981615382414716],"hsluv":[127.715012949239792,73.5866039174798345,31.6981615382414716]},"#225533":{"lch":[31.9789617713411829,29.2625646618711706,137.400330584271074],"luv":[31.9789617713411829,-21.5402028917408828,19.8070025489176231],"rgb":[0.133333333333333331,0.333333333333333315,0.2],"xyz":[0.0450550718588861657,0.070758492231139,0.0426042242261888],"hpluv":[137.400330584271074,116.114739730974975,31.9789617713411829],"hsluv":[137.400330584271074,75.0932106461487,31.9789617713411829]},"#225544":{"lch":[32.3786649626227785,22.5648709259736577,157.632626155133437],"luv":[32.3786649626227785,-20.8671549807805796,8.58692278490586247],"rgb":[0.133333333333333331,0.333333333333333315,0.266666666666666663],"xyz":[0.0495130671031050462,0.072541690328826583,0.0660829991790754384],"hpluv":[157.632626155133437,88.4327727432137465,32.3786649626227785],"hsluv":[157.632626155133437,76.9882679005547459,32.3786649626227785]},"#225555":{"lch":[32.9031430542149863,20.5945867127178737,192.177050630061132],"luv":[32.9031430542149863,-20.1312179923833199,-4.34408379417313384],"rgb":[0.133333333333333331,0.333333333333333315,0.333333333333333315],"xyz":[0.0554754811424670383,0.0749266559445714159,0.0974850464530493399],"hpluv":[192.177050630061132,79.4245973683706268,32.9031430542149863],"hsluv":[192.177050630061132,79.1137061933639245,32.9031430542149863]},"#225566":{"lch":[33.5545056011551,26.6006796322727546,223.177731373198952],"luv":[33.5545056011551,-19.398136743372234,-18.2018803364993715],"rgb":[0.133333333333333331,0.333333333333333315,0.4],"xyz":[0.0630604769159752165,0.0779606542539747344,0.137432690860193302],"hpluv":[223.177731373198952,100.596116474312993,33.5545056011551],"hsluv":[223.177731373198952,81.3097794801720113,33.5545056011551]},"#225577":{"lch":[34.3316296590174,37.3644949384619807,239.932022094073261],"luv":[34.3316296590174,-18.7206257951117045,-32.3364137134245127],"rgb":[0.133333333333333331,0.333333333333333315,0.466666666666666674],"xyz":[0.0723744899361771221,0.0816862594620555438,0.186486492766591211],"hpluv":[239.932022094073261,138.103289638438355,34.3316296590174],"hsluv":[239.932022094073261,83.4469752602442298,34.3316296590174]},"#225588":{"lch":[35.230707776085,49.7211482448765594,248.610781811292384],"luv":[35.230707776085,-18.1333810040152876,-46.2965773697387775],"rgb":[0.133333333333333331,0.333333333333333315,0.533333333333333326],"xyz":[0.0835149070381209502,0.0861424263028331416,0.245159356170163378],"hpluv":[248.610781811292384,179.084957393431893,35.230707776085],"hsluv":[248.610781811292384,85.4385601139613158,35.230707776085]},"#225599":{"lch":[36.2458273864096512,62.3718238545276336,253.557833057747018],"luv":[36.2458273864096512,-17.6541819100499602,-59.8211858126123],"rgb":[0.133333333333333331,0.333333333333333315,0.6],"xyz":[0.0965718711471936775,0.0913652119464623,0.313926033811281313],"hpluv":[253.557833057747018,218.35832406203005,36.2458273864096512],"hsluv":[253.557833057747018,87.2381583586425791,36.2458273864096512]},"#2255aa":{"lch":[37.3695533294905928,74.8190204360075,256.640324292617947],"luv":[37.3695533294905928,-17.2879233745104131,-72.7943234352841841],"rgb":[0.133333333333333331,0.333333333333333315,0.66666666666666663],"xyz":[0.111629564112446206,0.0973882891325634,0.393229883428279914],"hpluv":[256.640324292617947,254.058329165629146,37.3695533294905928],"hsluv":[256.640324292617947,88.8301308270208807,37.3695533294905928]},"#2255bb":{"lch":[38.5934754222231291,86.8805221786483,258.695157685582501],"luv":[38.5934754222231291,-17.0311035792378,-85.1948745225196831],"rgb":[0.133333333333333331,0.333333333333333315,0.733333333333333282],"xyz":[0.128767156219782852,0.104243325975498152,0.48348786852692166],"hpluv":[258.695157685582501,285.658965815982469,38.5934754222231291],"hsluv":[258.695157685582501,90.2188193496234874,38.5934754222231291]},"#2255cc":{"lch":[39.9086891196534097,98.5112685419302,260.136263381096],"luv":[39.9086891196534097,-16.8755295039118458,-97.0550695930042],"rgb":[0.133333333333333331,0.333333333333333315,0.8],"xyz":[0.148059531663504607,0.111960276152986954,0.585094379197191761],"hpluv":[260.136263381096,313.22597901471056,39.9086891196534097],"hsluv":[260.136263381096,91.4196885710314433,39.9086891196534097]},"#2255dd":{"lch":[41.3061900239028503,109.727240919989157,261.187210775965298],"luv":[41.3061900239028503,-16.8109176424286737,-108.431823962952976],"rgb":[0.133333333333333331,0.333333333333333315,0.866666666666666696],"xyz":[0.16957785721413815,0.120567606373240488,0.698424227097197758],"hpluv":[261.187210775965298,337.084394380702577,41.3061900239028503],"hsluv":[261.187210775965298,92.4531471705562353,41.3061900239028503]},"#2255ee":{"lch":[42.7771763125841602,120.569176865205208,261.977669343247612],"luv":[42.7771763125841602,-16.8265186863462972,-119.389256965822398],"rgb":[0.133333333333333331,0.333333333333333315,0.933333333333333348],"xyz":[0.193390037480312887,0.130092478479710533,0.823835043165721],"hpluv":[261.977669343247612,357.654347674158601,42.7771763125841602],"hsluv":[261.977669343247612,93.3407272081067,42.7771763125841602]},"#2255ff":{"lch":[44.3132637322964129,131.084767922007643,262.587267096581058],"luv":[44.3132637322964129,-16.9120289519133,-129.989229007238322],"rgb":[0.133333333333333331,0.333333333333333315,1],"xyz":[0.219561085890144281,0.140560897843643229,0.961669231457502827],"hpluv":[262.587267096581058,375.368494421854962,44.3132637322964129],"hsluv":[262.587267096581058,99.9999999999993463,44.3132637322964129]},"#77ee00":{"lch":[84.5193058633960703,115.647601499010833,119.483871035599748],"luv":[84.5193058633960703,-56.9192667804191,100.670575649757225],"rgb":[0.466666666666666674,0.933333333333333348,0],"xyz":[0.381807757380814794,0.650690513347127,0.105476708327643554],"hpluv":[119.483871035599748,321.869538605652735,84.5193058633960703],"hsluv":[119.483871035599748,100.000000000002359,84.5193058633960703]},"#77ee11":{"lch":[84.5401392884337355,114.795422022346642,119.691827475064969],"luv":[84.5401392884337355,-56.862163274863434,99.7230329712822083],"rgb":[0.466666666666666674,0.933333333333333348,0.0666666666666666657],"xyz":[0.382819422880451898,0.651095179546981928,0.11080481329239919],"hpluv":[119.691827475064969,319.985367790437692,84.5401392884337355],"hsluv":[119.691827475064969,98.9722780394741477,84.5401392884337355]},"#77ee22":{"lch":[84.5787360835130499,113.228793274865538,120.083373039169615],"luv":[84.5787360835130499,-56.7570256545281637,97.9765260934141651],"rgb":[0.466666666666666674,0.933333333333333348,0.133333333333333331],"xyz":[0.384694781018928955,0.651845322802372729,0.120681699488378383],"hpluv":[120.083373039169615,316.512949618186383,84.5787360835130499],"hsluv":[120.083373039169615,97.0790709390529,84.5787360835130499]},"#77ee33":{"lch":[84.6422206992536275,110.686316006337648,120.745647293955486],"luv":[84.6422206992536275,-56.585921413754825,95.1288286946244313],"rgb":[0.466666666666666674,0.933333333333333348,0.2],"xyz":[0.387782531751386661,0.653080423095355855,0.136943853345989519],"hpluv":[120.745647293955486,310.853610471304819,84.6422206992536275],"hsluv":[120.745647293955486,93.9952250088888093,84.6422206992536275]},"#77ee44":{"lch":[84.7337366993681513,107.096480548503891,121.742158736883837],"luv":[84.7337366993681513,-56.3431952848259598,91.0774422728923412],"rgb":[0.466666666666666674,0.933333333333333348,0.266666666666666663],"xyz":[0.392240526995605576,0.654863621193043421,0.160422628298876158],"hpluv":[121.742158736883837,302.811644310583176,84.7337366993681513],"hsluv":[121.742158736883837,89.6144795711786628,84.7337366993681513]},"#77ee55":{"lch":[84.8558768548969766,102.444399932600575,123.154228511336783],"luv":[84.8558768548969766,-56.0262879596216621,85.7666026785261266],"rgb":[0.466666666666666674,0.933333333333333348,0.333333333333333315],"xyz":[0.398202941034967561,0.657248586808788171,0.191824675572850073],"hpluv":[123.154228511336783,292.298881153811294,84.8558768548969766],"hsluv":[123.154228511336783,83.883891015311761,84.8558768548969766]},"#77ee66":{"lch":[85.0108293450033159,96.7735040486586,125.092887734820366],"luv":[85.0108293450033159,-55.6354444449268186,79.1821217654036],"rgb":[0.466666666666666674,0.933333333333333348,0.4],"xyz":[0.405787936808475747,0.66028258511819149,0.231772319979994035],"hpluv":[125.092887734820366,279.341716913636219,85.0108293450033159],"hsluv":[125.092887734820366,76.7984153057879411,85.0108293450033159]},"#77ee77":{"lch":[85.2004556710930814,90.1918871908529667,127.71501294923965],"luv":[85.2004556710930814,-55.1734745704367882,71.3474892261312306],"rgb":[0.466666666666666674,0.933333333333333348,0.466666666666666674],"xyz":[0.415101949828677652,0.664008190326272341,0.280826121886391944],"hpluv":[127.71501294923965,264.105357222364148,85.2004556710930814],"hsluv":[127.71501294923965,68.3966317942099522,85.2004556710930814]},"#77ee88":{"lch":[85.4263369442757323,82.8846309918514521,131.246169999264879],"luv":[85.4263369442757323,-54.6454688778224167,62.3196179848555],"rgb":[0.466666666666666674,0.933333333333333348,0.533333333333333326],"xyz":[0.426242366930621452,0.668464357167049883,0.339498985289964139],"hpluv":[131.246169999264879,246.94310788397641,85.4263369442757323],"hsluv":[131.246169999264879,69.0963798671032379,85.4263369442757323]},"#77ee99":{"lch":[85.6898036798217,75.1362836057233,136.010896750223054],"luv":[85.6898036798217,-54.0584447513185395,52.1837682153016473],"rgb":[0.466666666666666674,0.933333333333333348,0.6],"xyz":[0.439299331039694207,0.673687142810679096,0.408265662931082],"hpluv":[136.010896750223054,228.489214549916312,85.6898036798217],"hsluv":[136.010896750223054,69.8780652000076827,85.6898036798217]},"#77eeaa":{"lch":[85.9919564191548602,67.3699388554866232,142.461966648640384],"luv":[85.9919564191548602,-53.4209300451477489,41.0476904892764551],"rgb":[0.466666666666666674,0.933333333333333348,0.66666666666666663],"xyz":[0.454357024004946708,0.679710219996780163,0.487569512548080619],"hpluv":[142.461966648640384,209.826142071523691,85.9919564191548602],"hsluv":[142.461966648640384,70.7318226594993575,85.9919564191548602]},"#77eebb":{"lch":[86.3336811163097337,60.2064759054885243,151.166773543866697],"luv":[86.3336811163097337,-52.7425080063862524,29.0352818163428843],"rgb":[0.466666666666666674,0.933333333333333348,0.733333333333333282],"xyz":[0.471494616112283382,0.686565256839714921,0.577827497646722366],"hpluv":[151.166773543866697,192.758378827545073,86.3336811163097337],"hsluv":[151.166773543866697,71.6464628016145895,86.3336811163097337]},"#77eecc":{"lch":[86.7156615657761449,54.5207620102438284,162.626180625161169],"luv":[86.7156615657761449,-52.0333543078463094,16.2801575438255028],"rgb":[0.466666666666666674,0.933333333333333348,0.8],"xyz":[0.490786991556005137,0.694282207017203778,0.679434008316992522],"hpluv":[162.626180625161169,180.150974339718545,86.7156615657761449],"hsluv":[162.626180625161169,72.6100300694190111,86.7156615657761449]},"#77eedd":{"lch":[87.1383902516757445,51.3868015721907483,176.742975614533037],"luv":[87.1383902516757445,-51.3037971188162771,2.91955082350760353],"rgb":[0.466666666666666674,0.933333333333333348,0.866666666666666696],"xyz":[0.512305317106638625,0.702889537237457285,0.792763856216998519],"hpluv":[176.742975614533037,175.997429168902841,87.1383902516757445],"hsluv":[176.742975614533037,73.6103328445444305,87.1383902516757445]},"#77eeee":{"lch":[87.6021784736708327,51.7277775307036,192.177050630061075],"luv":[87.6021784736708327,-50.5639263491039941,-10.9111099540033418],"rgb":[0.466666666666666674,0.933333333333333348,0.933333333333333348],"xyz":[0.536117497372813334,0.712414409343927302,0.918174672285521742],"hpluv":[192.177050630061075,184.503896016801804,87.6021784736708327],"hsluv":[192.177050630061075,74.6354143053272594,87.6021784736708327]},"#77eeff":{"lch":[88.107166277409533,55.7808213308350673,206.722210113893169],"luv":[88.107166277409533,-49.8232704905303336,-25.0826981397535107],"rgb":[0.466666666666666674,0.933333333333333348,1],"xyz":[0.562288545782644755,0.72288282870786,1.05600886057730348],"hpluv":[206.722210113893169,208.278116369071,88.107166277409533],"hsluv":[206.722210113893169,99.9999999999928804,88.107166277409533]},"#226600":{"lch":[37.5582057574881532,54.1200869321592961,123.236537452327113],"luv":[37.5582057574881532,-29.6630419039077431,45.2668505040000824],"rgb":[0.133333333333333331,0.4,0],"xyz":[0.0541083551941607538,0.0984246978946035633,0.0161464317764581713],"hpluv":[123.236537452327113,182.849162381267462,37.5582057574881532],"hsluv":[123.236537452327113,100.000000000002288,37.5582057574881532]},"#226611":{"lch":[37.6315056544729529,51.7196180195473119,124.710513292064419],"luv":[37.6315056544729529,-29.4507212427394194,42.5155725160833242],"rgb":[0.133333333333333331,0.4,0.0666666666666666657],"xyz":[0.0551200206937978721,0.0988293640944584162,0.0214745367412138],"hpluv":[124.710513292064419,174.398618448608886,37.6315056544729529],"hsluv":[124.710513292064419,93.2756924270169918,37.6315056544729529]},"#226622":{"lch":[37.7668566222969062,47.5272711912458519,127.715012949240034],"luv":[37.7668566222969062,-29.0740638670039928,37.5970785719263176],"rgb":[0.133333333333333331,0.4,0.133333333333333331],"xyz":[0.0569953788322748942,0.0995795073498492306,0.031351422937193],"hpluv":[127.715012949240034,159.687663587322874,37.7668566222969062],"hsluv":[127.715012949240034,81.309482828258183,37.7668566222969062]},"#226633":{"lch":[37.9882367851431084,41.3581300307957349,133.555287588173542],"luv":[37.9882367851431084,-28.497993426715972,29.9726423642471254],"rgb":[0.133333333333333331,0.4,0.2],"xyz":[0.0600831295647326347,0.100814607642832343,0.0476135767948041438],"hpluv":[133.555287588173542,138.150062101989391,37.9882367851431084],"hsluv":[133.555287588173542,82.0766642375396742,37.9882367851431084]},"#226644":{"lch":[38.3046909892153806,34.1393686276432291,144.379277801066621],"luv":[38.3046909892153806,-27.7515572052733894,19.8833488873617412],"rgb":[0.133333333333333331,0.4,0.266666666666666663],"xyz":[0.0645411248089515083,0.102597805740519923,0.0710923517476907824],"hpluv":[144.379277801066621,113.094855071532635,38.3046909892153806],"hsluv":[144.379277801066621,83.0794073538424414,38.3046909892153806]},"#226655":{"lch":[38.7222568592555234,28.0005039743963025,163.778220785970291],"luv":[38.7222568592555234,-26.8857357715149732,7.82211191715276755],"rgb":[0.133333333333333331,0.4,0.333333333333333315],"xyz":[0.0705035388483135073,0.104982771356264756,0.102494399021664684],"hpluv":[163.778220785970291,91.7581213405574516,38.7222568592555234],"hsluv":[163.778220785970291,84.2573678500350809,38.7222568592555234]},"#226666":{"lch":[39.2444156655659739,26.5583838540848376,192.177050630061103],"luv":[39.2444156655659739,-25.9608324434988,-5.60204710632589631],"rgb":[0.133333333333333331,0.4,0.4],"xyz":[0.0780885346218216786,0.108016769665668075,0.142442043428808646],"hpluv":[192.177050630061103,85.8742788705857691,39.2444156655659739],"hsluv":[192.177050630061103,85.5381417500271652,39.2444156655659739]},"#226677":{"lch":[39.8723950361637449,31.9118423017057466,218.325872967111877],"luv":[39.8723950361637449,-25.034725973132506,-19.7895976345933065],"rgb":[0.133333333333333331,0.4,0.466666666666666674],"xyz":[0.0874025476420236,0.111742374873748884,0.191495845335206555],"hpluv":[218.325872967111877,101.559108573692257,39.8723950361637449],"hsluv":[218.325872967111877,86.8516914397336137,39.8723950361637449]},"#226688":{"lch":[40.6054458094686836,41.8995680003496318,234.7955790683381],"luv":[40.6054458094686836,-24.1549067561574908,-34.2361545477476241],"rgb":[0.133333333333333331,0.4,0.533333333333333326],"xyz":[0.0985429647439674261,0.116198541714526482,0.250168708738778722],"hpluv":[234.7955790683381,130.937664052949941,40.6054458094686836],"hsluv":[234.7955790683381,88.1401386465251733,40.6054458094686836]},"#226699":{"lch":[41.4411308461218226,53.8933488408681782,244.319142730286046],"luv":[41.4411308461218226,-23.3551142576285748,-48.5698639826860301],"rgb":[0.133333333333333331,0.4,0.6],"xyz":[0.11159992885304014,0.12142132735815564,0.318935386379896657],"hpluv":[244.319142730286046,165.022400136876769,41.4411308461218226],"hsluv":[244.319142730286046,89.3619383181549267,41.4411308461218226]},"#2266aa":{"lch":[42.3756299296545578,66.5269840788925251,250.089735516440328],"luv":[42.3756299296545578,-22.655631138578233,-62.5504755245386193],"rgb":[0.133333333333333331,0.4,0.66666666666666663],"xyz":[0.126657621818292682,0.127444404544256734,0.398239235996895258],"hpluv":[250.089735516440328,199.214522587526545,42.3756299296545578],"hsluv":[250.089735516440328,90.4915899210210597,42.3756299296545578]},"#2266bb":{"lch":[43.404050412459263,79.1834510223872599,253.819475134999237],"luv":[43.404050412459263,-22.0656311263342282,-76.0468726432017803],"rgb":[0.133333333333333331,0.4,0.733333333333333282],"xyz":[0.143795213925629328,0.134299441387191493,0.488497221095537],"hpluv":[253.819475134999237,231.496000814517572,43.404050412459263],"hsluv":[253.819475134999237,91.5168425909476895,43.404050412459263]},"#2266cc":{"lch":[44.520728505208055,91.5877705166709,256.367788484306971],"luv":[44.520728505208055,-21.5861851194902563,-89.0076194502553193],"rgb":[0.133333333333333331,0.4,0.8],"xyz":[0.163087589369351083,0.142016391564680294,0.590103731765807105],"hpluv":[256.367788484306971,261.044502527732277,44.520728505208055],"hsluv":[256.367788484306971,92.43509558526695,44.520728505208055]},"#2266dd":{"lch":[45.7195068588792211,103.627896901795907,258.1878164043369],"luv":[45.7195068588792211,-21.2130654589597789,-101.433460308337743],"rgb":[0.133333333333333331,0.4,0.866666666666666696],"xyz":[0.184605914919984626,0.150623721784933828,0.703433579665813102],"hpluv":[258.1878164043369,287.616948003961852,45.7195068588792211],"hsluv":[258.1878164043369,93.2500413525610696,45.7195068588792211]},"#2266ee":{"lch":[46.9939777237187144,115.273293340910215,259.534328145616598],"luv":[46.9939777237187144,-20.9389771714321675,-113.35559709460216],"rgb":[0.133333333333333331,0.4,0.933333333333333348],"xyz":[0.208418095186159336,0.160148593891403873,0.828844395734336326],"hpluv":[259.534328145616598,311.261797341727515,46.9939777237187144],"hsluv":[259.534328145616598,93.969002023907521,46.9939777237187144]},"#2266ff":{"lch":[48.3376856243364728,126.534150990995641,260.559220542156197],"luv":[48.3376856243364728,-20.75515631493003,-124.820330288598825],"rgb":[0.133333333333333331,0.4,1],"xyz":[0.234589143595990757,0.170617013255336569,0.966678584026118171],"hpluv":[260.559220542156197,332.170629177470857,48.3376856243364728],"hsluv":[260.559220542156197,99.9999999999992184,48.3376856243364728]},"#77ff00":{"lch":[89.5984732569245921,124.632639236881928,120.733702851753719],"luv":[89.5984732569245921,-63.6933378884713406,107.128210438594465],"rgb":[0.466666666666666674,1,0],"xyz":[0.433660129810488626,0.754395258206476127,0.122760832470867665],"hpluv":[120.733702851753719,538.628162219261071,89.5984732569245921],"hsluv":[120.733702851753719,100.000000000002359,89.5984732569245921]},"#77ff11":{"lch":[89.6173512893739144,123.857431845856226,120.915842858481739],"luv":[89.6173512893739144,-63.635285050623331,106.260123846986147],"rgb":[0.466666666666666674,1,0.0666666666666666657],"xyz":[0.43467179531012573,0.754799924406331,0.128088937435623301],"hpluv":[120.915842858481739,536.333532616984598,89.6173512893739144],"hsluv":[120.915842858481739,99.9999999999912461,89.6173512893739144]},"#77ff22":{"lch":[89.6523282897647107,122.430860002153082,121.257903913559275],"luv":[89.6523282897647107,-63.5282943614823736,104.658832863679763],"rgb":[0.466666666666666674,1,0.133333333333333331],"xyz":[0.436547153448602787,0.755550067661721836,0.13796582363160248],"hpluv":[121.257903913559275,532.099457877515,89.6523282897647107],"hsluv":[121.257903913559275,99.9999999999912319,89.6523282897647107]},"#77ff33":{"lch":[89.7098670229763684,120.111567958755899,121.833904144252088],"luv":[89.7098670229763684,-63.3538816193187557,102.044472860004433],"rgb":[0.466666666666666674,1,0.2],"xyz":[0.439634904181060493,0.756785167954705,0.15422797748921363],"hpluv":[121.833904144252088,525.184015431200237,89.7098670229763684],"hsluv":[121.833904144252088,99.9999999999911893,89.7098670229763684]},"#77ff44":{"lch":[89.7928292607091834,116.827732221897932,122.694629127971339],"luv":[89.7928292607091834,-63.1058355300939766,98.317712230097257],"rgb":[0.466666666666666674,1,0.266666666666666663],"xyz":[0.444092899425279408,0.758568366052392529,0.177706752442100269],"hpluv":[122.694629127971339,515.324540814372313,89.7928292607091834],"hsluv":[122.694629127971339,99.9999999999912319,89.7928292607091834]},"#77ff55":{"lch":[89.9035853929870683,112.554947355203538,123.902387884937639],"luv":[89.9035853929870683,-62.7808648215699492,93.4193726503684161],"rgb":[0.466666666666666674,1,0.333333333333333315],"xyz":[0.450055313464641393,0.760953331668137278,0.209108799716074184],"hpluv":[123.902387884937639,502.374863630046946,89.9035853929870683],"hsluv":[123.902387884937639,99.9999999999911466,89.9035853929870683]},"#77ff66":{"lch":[90.0441481999633169,107.316590618570714,125.538864396596409],"luv":[90.0441481999633169,-62.3783098318914213,87.3258099562234662],"rgb":[0.466666666666666674,1,0.4],"xyz":[0.457640309238149579,0.763987329977540597,0.249056444123218146],"hpluv":[125.538864396596409,486.310350268178581,90.0441481999633169],"hsluv":[125.538864396596409,99.9999999999909193,90.0441481999633169]},"#77ff77":{"lch":[90.2162444924982,101.18761180958829,127.715012949239778],"luv":[90.2162444924982,-61.8999369112410065,80.0458031011764746],"rgb":[0.466666666666666674,1,0.466666666666666674],"xyz":[0.466954322258351484,0.767712935185621448,0.298110246029616055],"hpluv":[127.715012949239778,467.252180695244249,90.2162444924982],"hsluv":[127.715012949239778,99.9999999999908908,90.2162444924982]},"#77ff88":{"lch":[90.4213578195287084,94.3018691223763312,130.584388318929172],"luv":[90.4213578195287084,-61.3497133683486666,71.6174223886566352],"rgb":[0.466666666666666674,1,0.533333333333333326],"xyz":[0.478094739360295284,0.772169102026399,0.35678310943318825],"hpluv":[130.584388318929172,445.517691352744919,90.4213578195287084],"hsluv":[130.584388318929172,99.999999999990834,90.4213578195287084]},"#77ff99":{"lch":[90.660755936805927,86.8649116623181,134.360625617567337],"luv":[90.660755936805927,-60.7335297134313734,62.1043577106315],"rgb":[0.466666666666666674,1,0.6],"xyz":[0.491151703469368,0.777391887670028203,0.425549787074306129],"hpluv":[134.360625617567337,421.714412879972315,90.660755936805927],"hsluv":[134.360625617567337,99.9999999999904645,90.660755936805927]},"#77ffaa":{"lch":[90.9355096576679927,79.1755179707932513,139.336843070371486],"luv":[90.9355096576679927,-60.0588662825700368,51.5916197341755947],"rgb":[0.466666666666666674,1,0.66666666666666663],"xyz":[0.506209396434620595,0.78341496485612927,0.504853636691304786],"hpluv":[139.336843070371486,396.909453229520182,90.9355096576679927],"hsluv":[139.336843070371486,99.9999999999902371,90.9355096576679927]},"#77ffbb":{"lch":[91.2465066485729466,71.6593730134265599,145.894485367843032],"luv":[91.2465066485729466,-59.3344173347434776,40.1807498713488229],"rgb":[0.466666666666666674,1,0.733333333333333282],"xyz":[0.523346988541957159,0.790270001699064,0.595111621789946477],"hpluv":[145.894485367843032,372.920765055848051,91.2465066485729466],"hsluv":[145.894485367843032,99.9999999999901803,91.2465066485729466]},"#77ffcc":{"lch":[91.5944622372901591,64.9119206982031329,154.461378490718602],"luv":[91.5944622372901591,-58.5696939322881676,27.9847887504604707],"rgb":[0.466666666666666674,1,0.8],"xyz":[0.542639363985678913,0.797986951876552886,0.696718132460216633],"hpluv":[154.461378490718602,352.767904832744364,91.5944622372901591],"hsluv":[154.461378490718602,99.999999999989825,91.5944622372901591]},"#77ffdd":{"lch":[91.9799284987297,59.7212008687906604,165.331177548206284],"luv":[91.9799284987297,-57.7746296637575298,15.1232933062250314],"rgb":[0.466666666666666674,1,0.866666666666666696],"xyz":[0.564157689536312512,0.806594282096806392,0.81004798036022263],"hpluv":[165.331177548206284,341.200809564626638,91.9799284987297],"hsluv":[165.331177548206284,99.9999999999894698,91.9799284987297]},"#77ffee":{"lch":[92.4033024177180238,56.9851054432815545,178.272694676027839],"luv":[92.4033024177180238,-56.9592119034112,1.71767916801026743],"rgb":[0.466666666666666674,1,0.933333333333333348],"xyz":[0.587969869802487222,0.816119154203276409,0.935458796428745853],"hpluv":[178.272694676027839,344.865805035808421,92.4033024177180238],"hsluv":[178.272694676027839,99.9999999999889582,92.4033024177180238]},"#77ffff":{"lch":[92.8648336399367196,57.4251975820971623,192.177050630061018],"luv":[92.8648336399367196,-56.1331570721439945,-12.112885471963672],"rgb":[0.466666666666666674,1,1],"xyz":[0.614140918212318643,0.826587573567209133,1.0732929847205277],"hpluv":[192.177050630061018,371.354821198433683,92.8648336399367196],"hsluv":[192.177050630061018,99.9999999999883187,92.8648336399367196]},"#227700":{"lch":[43.5559297152692295,63.9882214930525208,124.519604676885976],"luv":[43.5559297152692295,-36.2613695379953711,52.7219647687080268],"rgb":[0.133333333333333331,0.466666666666666674,0],"xyz":[0.0725620932475783825,0.13533217400143932,0.0222976777942638753],"hpluv":[124.519604676885976,186.419817132403381,43.5559297152692295],"hsluv":[124.519604676885976,100.000000000002331,43.5559297152692295]},"#227711":{"lch":[43.6152314308602769,61.9621092027414093,125.591738779589861],"luv":[43.6152314308602769,-36.0623023987336282,50.3866383335378174],"rgb":[0.133333333333333331,0.466666666666666674,0.0666666666666666657],"xyz":[0.0735737587472155,0.135736840201294173,0.0276257827590195085],"hpluv":[125.591738779589861,180.271610265320959,43.6152314308602769],"hsluv":[125.591738779589861,95.0867888092805345,43.6152314308602769]},"#227722":{"lch":[43.7248500006056062,58.3665782213362476,127.715012949240148],"luv":[43.7248500006056062,-35.7048401974777292,46.1716562377823081],"rgb":[0.133333333333333331,0.466666666666666674,0.133333333333333331],"xyz":[0.0754491168856925298,0.136486983456685,0.0375026689549987],"hpluv":[127.715012949240148,169.385110384242353,43.7248500006056062],"hsluv":[127.715012949240148,86.2472116803111248,43.7248500006056062]},"#227733":{"lch":[43.9044636679785,52.8998675233047422,131.63685913347058],"luv":[43.9044636679785,-35.1470498804547518,39.5358175416168365],"rgb":[0.133333333333333331,0.466666666666666674,0.2],"xyz":[0.0785368676181502634,0.137722083749668101,0.0537648228126098443],"hpluv":[131.63685913347058,152.892166506547881,43.9044636679785],"hsluv":[131.63685913347058,86.6671370230467204,43.9044636679785]},"#227744":{"lch":[44.1618994548856207,46.0187725021067919,138.382113458020484],"luv":[44.1618994548856207,-34.403210499316,30.5638107889119937],"rgb":[0.133333333333333331,0.466666666666666674,0.266666666666666663],"xyz":[0.082994862862369137,0.139505281847355694,0.0772435977654964828],"hpluv":[138.382113458020484,132.228969104156789,44.1618994548856207],"hsluv":[138.382113458020484,87.230083060842972,44.1618994548856207]},"#227755":{"lch":[44.5028042963196171,38.7961505601339098,149.7341572603126],"luv":[44.5028042963196171,-33.5080868304533865,19.5537570621958743],"rgb":[0.133333333333333331,0.466666666666666674,0.333333333333333315],"xyz":[0.088957276901731136,0.141890247463100527,0.108645645039470398],"hpluv":[149.7341572603126,110.621765171639552,44.5028042963196171],"hsluv":[149.7341572603126,87.9126674499387235,44.5028042963196171]},"#227766":{"lch":[44.9310046324235657,33.2418513983527504,167.948858330193701],"luv":[44.9310046324235657,-32.5092552143098246,6.94038974417402166],"rgb":[0.133333333333333331,0.466666666666666674,0.4],"xyz":[0.0965422726752393073,0.144924245772503818,0.148593289446614346],"hpluv":[167.948858330193701,93.8811500215461,44.9310046324235657],"hsluv":[167.948858330193701,88.6822605795820778,44.9310046324235657]},"#227777":{"lch":[45.4487163896678652,32.1827345016432886,192.177050630061217],"luv":[45.4487163896678652,-31.4586377906525136,-6.7884098550242733],"rgb":[0.133333333333333331,0.466666666666666674,0.466666666666666674],"xyz":[0.105856285695441227,0.148649850980584641,0.197647091353012255],"hpluv":[192.177050630061217,89.8546686552558,45.4487163896678652],"hsluv":[192.177050630061217,89.5029511213474,45.4487163896678652]},"#227788":{"lch":[46.0567093690380389,37.0457871068229778,214.840569513336618],"luv":[46.0567093690380389,-30.4051407329018595,-21.1640676472289648],"rgb":[0.133333333333333331,0.466666666666666674,0.533333333333333326],"xyz":[0.116996702797385055,0.153106017821362239,0.256319954756584423],"hpluv":[214.840569513336618,102.066975938242322,46.0567093690380389],"hsluv":[214.840569513336618,90.3407286635711415,46.0567093690380389]},"#227799":{"lch":[46.7544651468991219,46.3079141704010908,230.605362437026685],"luv":[46.7544651468991219,-29.3896969252833173,-35.7864308006991223],"rgb":[0.133333333333333331,0.466666666666666674,0.6],"xyz":[0.130053666906457754,0.158328803464991397,0.325086632397702358],"hpluv":[230.605362437026685,125.681528260779189,46.7544651468991219],"hsluv":[230.605362437026685,91.1669787694701,46.7544651468991219]},"#2277aa":{"lch":[47.5403420753171133,57.8256716053654429,240.536105931551504],"luv":[47.5403420753171133,-28.4430017925967782,-50.3468365007961935],"rgb":[0.133333333333333331,0.466666666666666674,0.66666666666666663],"xyz":[0.14511135987171031,0.164351880651092491,0.404390482014700958],"hpluv":[240.536105931551504,154.346828351852139,47.5403420753171133],"hsluv":[240.536105931551504,91.9600907928071365,47.5403420753171133]},"#2277bb":{"lch":[48.4117490016133161,70.2708193466387172,246.886175208709233],"luv":[48.4117490016133161,-27.5854458877112236,-64.6299561103370337],"rgb":[0.133333333333333331,0.466666666666666674,0.733333333333333282],"xyz":[0.162248951979046957,0.17120691749402725,0.494648467113342705],"hpluv":[246.886175208709233,184.188949495161438,48.4117490016133161],"hsluv":[246.886175208709233,92.7055270960754427,48.4117490016133161]},"#2277cc":{"lch":[49.3653235224945348,82.9601291275659634,251.131977113837081],"luv":[49.3653235224945348,-26.8284223951791141,-78.5023488607078],"rgb":[0.133333333333333331,0.466666666666666674,0.8],"xyz":[0.181541327422768684,0.178923867671516051,0.596254977783612805],"hpluv":[251.131977113837081,213.248879712122147,49.3653235224945348],"hsluv":[251.131977113837081,93.3949294454883301,49.3653235224945348]},"#2277dd":{"lch":[50.3971082370692898,95.5506012475210156,254.100456017762497],"luv":[50.3971082370692898,-26.1762366694964186,-91.8951687118820928],"rgb":[0.133333333333333331,0.466666666666666674,0.866666666666666696],"xyz":[0.203059652973402227,0.187531197891769585,0.709584825683618803],"hpluv":[254.100456017762497,240.584217083197558,50.3971082370692898],"hsluv":[254.100456017762497,94.0248036114472399,50.3971082370692898]},"#2277ee":{"lch":[51.5027182397596448,107.874744495734575,256.256689112315712],"luv":[51.5027182397596448,-25.6280715933506258,-104.786270314512635],"rgb":[0.133333333333333331,0.466666666666666674,0.933333333333333348],"xyz":[0.226871833239577,0.19705606999823963,0.834995641752142],"hpluv":[256.256689112315712,265.784074864026707,51.5027182397596448],"hsluv":[256.256689112315712,94.5951642228933594,51.5027182397596448]},"#2277ff":{"lch":[52.6774941409559432,119.859275592882611,257.873120264558906],"luv":[52.6774941409559432,-25.1797078347732324,-117.18459053564186],"rgb":[0.133333333333333331,0.466666666666666674,1],"xyz":[0.253042881649408358,0.207524489362172326,0.972829830043923871],"hpluv":[257.873120264558906,288.725982332353851,52.6774941409559432],"hsluv":[257.873120264558906,99.9999999999990195,52.6774941409559432]},"#228800":{"lch":[49.4326013626652951,73.5543249838887903,125.335546592141156],"luv":[49.4326013626652951,-42.5411625112882845,60.0040683289365475],"rgb":[0.133333333333333331,0.533333333333333326,0],"xyz":[0.0946344629725488357,0.179476913451380865,0.0296551343692538216],"hpluv":[125.335546592141156,188.81394887832684,49.4326013626652951],"hsluv":[125.335546592141156,100.000000000002359,49.4326013626652951]},"#228811":{"lch":[49.4817413630627669,71.8188220709608,126.143293588176633],"luv":[49.4817413630627669,-42.3592238010278379,57.9968909738682825],"rgb":[0.133333333333333331,0.533333333333333326,0.0666666666666666657],"xyz":[0.0956461284721859539,0.179881579651235718,0.0349832393340094513],"hpluv":[126.143293588176633,184.175827324420425,49.4817413630627669],"hsluv":[126.143293588176633,96.2839239867753776,49.4817413630627669]},"#228822":{"lch":[49.5726392440562904,68.7061860444130161,127.715012949240233],"luv":[49.5726392440562904,-42.0299333634258545,54.3509402148249521],"rgb":[0.133333333333333331,0.533333333333333326,0.133333333333333331],"xyz":[0.097521486610662983,0.180631722906626546,0.0448601255299886509],"hpluv":[127.715012949240233,175.870551812838869,49.5726392440562904],"hsluv":[127.715012949240233,89.549457305464,49.5726392440562904]},"#228833":{"lch":[49.7217546026668913,63.8760413965615115,130.529662443073192],"luv":[49.7217546026668913,-41.5093107949551552,48.5502397710151357],"rgb":[0.133333333333333331,0.533333333333333326,0.2],"xyz":[0.100609237343120717,0.181866823199609645,0.0611222793875997941],"hpluv":[130.529662443073192,163.016240956960957,49.7217546026668913],"hsluv":[130.529662443073192,89.7937238944362122,49.7217546026668913]},"#228844":{"lch":[49.9358562328630171,57.5522088774297558,135.149605574971361],"luv":[49.9358562328630171,-40.8016788905052792,40.5891579906186308],"rgb":[0.133333333333333331,0.533333333333333326,0.266666666666666663],"xyz":[0.10506723258733959,0.183650021297297239,0.0846010543404864257],"hpluv":[135.149605574971361,146.247625060139768,49.9358562328630171],"hsluv":[135.149605574971361,90.1269016918236616,49.9358562328630171]},"#228855":{"lch":[50.2200542052193697,50.3265642713731509,142.503880569306347],"luv":[50.2200542052193697,-39.9288227743001443,30.6341669254964764],"rgb":[0.133333333333333331,0.533333333333333326,0.333333333333333315],"xyz":[0.111029646626701589,0.186034986913042072,0.116003101614460341],"hpluv":[142.503880569306347,127.162609675202816,50.2200542052193697],"hsluv":[142.503880569306347,90.5399352865824341,50.2200542052193697]},"#228866":{"lch":[50.5781035519961648,43.3062651916131074,154.006170397495453],"luv":[50.5781035519961648,-38.9254575775356315,18.9800252166796355],"rgb":[0.133333333333333331,0.533333333333333326,0.4],"xyz":[0.11861464240020976,0.189068985222445363,0.155950746021604303],"hpluv":[154.006170397495453,108.649446020320369,50.5781035519961648],"hsluv":[154.006170397495453,91.0179493017372607,50.5781035519961648]},"#228877":{"lch":[51.0125694858746357,38.3061120533697519,170.992189866461246],"luv":[51.0125694858746357,-37.8336830583721451,5.997553408179356],"rgb":[0.133333333333333331,0.533333333333333326,0.466666666666666674],"xyz":[0.12792865542041168,0.192794590430526186,0.205004547928002212],"hpluv":[170.992189866461246,95.2862426106229634,51.0125694858746357],"hsluv":[170.992189866461246,91.5427076584867621,51.0125694858746357]},"#228888":{"lch":[51.5249413470067594,37.5420496271247259,192.177050630061103],"luv":[51.5249413470067594,-36.6973707929670923,-7.91886779085127834],"rgb":[0.133333333333333331,0.533333333333333326,0.533333333333333326],"xyz":[0.139069072522355508,0.197250757271303784,0.263677411331574407],"hpluv":[192.177050630061103,92.4570004995607775,51.5249413470067594],"hsluv":[192.177050630061103,92.0950966753639761,51.5249413470067594]},"#228899":{"lch":[52.1157302062907064,42.0223592343639183,212.203992327233067],"luv":[52.1157302062907064,-35.5574728144251,-22.3951959730954577],"rgb":[0.133333333333333331,0.533333333333333326,0.6],"xyz":[0.152126036631428208,0.202473542914932941,0.332444088972692287],"hpluv":[212.203992327233067,102.317738016510475,52.1157302062907064],"hsluv":[212.203992327233067,92.6571999954113465,52.1157302062907064]},"#2288aa":{"lch":[52.784565077464336,50.6329849579481888,227.127925237574203],"luv":[52.784565077464336,-34.4488478228089221,-37.1076279143892478],"rgb":[0.133333333333333331,0.533333333333333326,0.66666666666666663],"xyz":[0.167183729596680763,0.208496620101034036,0.411747938589690887],"hpluv":[227.127925237574203,121.72111165959474,52.784565077464336],"hsluv":[227.127925237574203,93.213704377986,52.784565077464336]},"#2288bb":{"lch":[53.5302933631107294,61.6316847476891141,237.186375672219185],"luv":[53.5302933631107294,-33.3987075035381409,-51.7975955226846381],"rgb":[0.133333333333333331,0.533333333333333326,0.733333333333333282],"xyz":[0.18432132170401741,0.215351656943968794,0.502005923688332634],"hpluv":[237.186375672219185,146.097822373379188,53.5302933631107294],"hsluv":[237.186375672219185,93.7525919029994,53.5302933631107294]},"#2288cc":{"lch":[54.351086283976727,73.7818378825302261,243.928624140525301],"luv":[54.351086283976727,-32.4264148607849876,-66.274333045306733],"rgb":[0.133333333333333331,0.533333333333333326,0.8],"xyz":[0.203613697147739137,0.223068607121457596,0.60361243435860279],"hpluv":[243.928624140525301,172.258462735913952,54.351086283976727],"hsluv":[243.928624140525301,94.2652369190112864,54.351086283976727]},"#2288dd":{"lch":[55.2445474530087779,86.375042864399532,248.580085361336785],"luv":[55.2445474530087779,-31.544198041281593,-80.4090268549449831],"rgb":[0.133333333333333331,0.533333333333333326,0.866666666666666696],"xyz":[0.22513202269837268,0.23167593734171113,0.716942282258608787],"hpluv":[248.580085361336785,198.39840761978212,55.2445474530087779],"hsluv":[248.580085361336785,94.7460999996689566,55.2445474530087779]},"#2288ee":{"lch":[56.2078215466105604,99.0227420546019772,251.903461744910402],"luv":[56.2078215466105604,-30.7583451142169402,-94.1245326673496265],"rgb":[0.133333333333333331,0.533333333333333326,0.933333333333333348],"xyz":[0.248944202964547445,0.241200809448181175,0.842353098327132],"hpluv":[251.903461744910402,223.551465466634539,56.2078215466105604],"hsluv":[251.903461744910402,95.1922101623356838,56.2078215466105604]},"#2288ff":{"lch":[57.2376997180489866,111.514610807296222,254.356224713070389],"luv":[57.2376997180489866,-30.0705415498761575,-107.383755542446536],"rgb":[0.133333333333333331,0.533333333333333326,1],"xyz":[0.275115251374378811,0.251669228812113843,0.980187286618913856],"hpluv":[254.356224713070389,247.223031548482197,57.2376997180489866],"hsluv":[254.356224713070389,99.9999999999988773,57.2376997180489866]},"#229900":{"lch":[55.1973816023000694,82.8565734474734086,125.883775052172936],"luv":[55.1973816023000694,-48.5657961090338617,67.1310301704979508],"rgb":[0.133333333333333331,0.6,0],"xyz":[0.120504063425016322,0.23121611435631656,0.0382783345200760766],"hpluv":[125.883775052172936,190.479314261094402,55.1973816023000694],"hsluv":[125.883775052172936,100.000000000002331,55.1973816023000694]},"#229911":{"lch":[55.2388931006948951,81.3509781714907376,126.510168490119042],"luv":[55.2388931006948951,-48.4010205856972817,65.3859530459048273],"rgb":[0.133333333333333331,0.6,0.0666666666666666657],"xyz":[0.121515728924653441,0.231620780556171413,0.0436064394848317063],"hpluv":[126.510168490119042,186.877552842351321,55.2388931006948951],"hsluv":[126.510168490119042,97.109403045153627,55.2388931006948951]},"#229922":{"lch":[55.3157166450500739,78.6308396618125869,127.715012949240275],"luv":[55.3157166450500739,-48.1011847922964293,62.2019691609440102],"rgb":[0.133333333333333331,0.6,0.133333333333333331],"xyz":[0.12339108706313047,0.232370923811562241,0.0534833256808109059],"hpluv":[127.715012949240275,180.378053709807,55.3157166450500739],"hsluv":[127.715012949240275,91.8445791693357592,55.3157166450500739]},"#229933":{"lch":[55.4418461137647,74.3518111171957656,129.829614369777261],"luv":[55.4418461137647,-47.6228343175573201,57.0986643273697],"rgb":[0.133333333333333331,0.6,0.2],"xyz":[0.126478837795588217,0.23360602410454534,0.0697454795384220561],"hpluv":[129.829614369777261,170.173995330187722,55.4418461137647],"hsluv":[129.829614369777261,91.9941043082508827,55.4418461137647]},"#229944":{"lch":[55.6231658975890042,68.6117263626113925,133.195472742568398],"luv":[55.6231658975890042,-46.964006542137362,50.0195070344354846],"rgb":[0.133333333333333331,0.6,0.266666666666666663],"xyz":[0.130936833039807077,0.235389222202232934,0.0932242544913087],"hpluv":[133.195472742568398,156.524371813771666,55.6231658975890042],"hsluv":[133.195472742568398,92.2005608183228844,55.6231658975890042]},"#229955":{"lch":[55.8642490130281715,61.7521412094073696,138.342726405552],"luv":[55.8642490130281715,-46.1371272258517706,41.0450049980768625],"rgb":[0.133333333333333331,0.6,0.333333333333333315],"xyz":[0.136899247079169062,0.237774187817977767,0.124626301765282596],"hpluv":[138.342726405552,140.267605312348593,55.8642490130281715],"hsluv":[138.342726405552,92.4605995247666357,55.8642490130281715]},"#229966":{"lch":[56.1686206396836383,54.4254646973719787,146.085824005346524],"luv":[56.1686206396836383,-45.1662924386951516,30.3667126121210664],"rgb":[0.133333333333333331,0.6,0.4],"xyz":[0.144484242852677247,0.240808186127381058,0.164573946172426544],"hpluv":[146.085824005346524,122.955430161041207,56.1686206396836383],"hsluv":[146.085824005346524,92.7673635780271,56.1686206396836383]},"#229977":{"lch":[56.5388973522399,47.7139826201784629,157.505617321427167],"luv":[56.5388973522399,-44.0837619060267798,18.2550287233801534],"rgb":[0.133333333333333331,0.6,0.466666666666666674],"xyz":[0.153798255872879153,0.244533791335461881,0.213627748078824453],"hpluv":[157.505617321427167,107.087223886255089,56.5388973522399],"hsluv":[157.505617321427167,93.1115325865156,56.5388973522399]},"#229988":{"lch":[56.9768757530356,43.2189787336254057,173.325138204180888],"luv":[56.9768757530356,-42.9260293704251126,5.02355703331473169],"rgb":[0.133333333333333331,0.6,0.533333333333333326],"xyz":[0.164938672974823,0.248989958176239479,0.272300611482396648],"hpluv":[173.325138204180888,96.2532040641867,56.9768757530356],"hsluv":[173.325138204180888,93.4824878896153706,56.9768757530356]},"#229999":{"lch":[57.4836007022547477,42.6905833214490045,192.177050630061103],"luv":[57.4836007022547477,-41.7300648492924537,-9.00486490733903366],"rgb":[0.133333333333333331,0.6,0.6],"xyz":[0.177995637083895708,0.254212743819868636,0.341067289123514528],"hpluv":[192.177050630061103,94.2383018299879467,57.4836007022547477],"hsluv":[192.177050630061103,93.8694254698009587,57.4836007022547477]},"#2299aa":{"lch":[58.0594270662980563,46.8633307325653,210.133219640519371],"luv":[58.0594270662980563,-40.5302437993065823,-23.5259666096543114],"rgb":[0.133333333333333331,0.6,0.66666666666666663],"xyz":[0.193053330049148264,0.260235821005969759,0.420371138740513128],"hpluv":[210.133219640519371,102.423528384682896,58.0594270662980563],"hsluv":[210.133219640519371,94.2622655036202701,58.0594270662980563]},"#2299bb":{"lch":[58.704081470592044,54.8976329577059445,224.200669016044458],"luv":[58.704081470592044,-39.3562485070025474,-38.2731734745639],"rgb":[0.133333333333333331,0.6,0.733333333333333282],"xyz":[0.210190922156484883,0.267090857848904517,0.51062912383915493],"hpluv":[224.200669016044458,118.665547847191604,58.704081470592044],"hsluv":[224.200669016044458,94.6522748426748279,58.704081470592044]},"#2299cc":{"lch":[59.4167266489170771,65.3729917945351247,234.209137470411804],"luv":[59.4167266489170771,-38.231976961148348,-53.0277662532618663],"rgb":[0.133333333333333331,0.6,0.8],"xyz":[0.229483297600206637,0.274807808026393319,0.612235634509425086],"hpluv":[234.209137470411804,139.613998456385502,59.4167266489170771],"hsluv":[234.209137470411804,95.032392249276171,59.4167266489170771]},"#2299dd":{"lch":[60.1960287785942114,77.1664383037622201,241.199920521286145],"luv":[60.1960287785942114,-37.1753089722913614,-67.6214137925481],"rgb":[0.133333333333333331,0.6,0.866666666666666696],"xyz":[0.251001623150840181,0.283415138246646825,0.725565482409431084],"hpluv":[241.199920521286145,162.667181112599422,60.1960287785942114],"hsluv":[241.199920521286145,95.397300800485425,60.1960287785942114]},"#2299ee":{"lch":[61.0402269370523243,89.5733454479413211,246.163931095701571],"luv":[61.0402269370523243,-36.1984881015500051,-81.9332269222821],"rgb":[0.133333333333333331,0.6,0.933333333333333348],"xyz":[0.27481380341701489,0.292940010353116842,0.850976298477954307],"hpluv":[246.163931095701571,186.209563381880429,61.0402269370523243],"hsluv":[246.163931095701571,95.74331870201,61.0402269370523243]},"#2299ff":{"lch":[61.9472031658153384,102.178145565387652,249.783903318571561],"luv":[61.9472031658153384,-35.3088685699608078,-95.8835607989752532],"rgb":[0.133333333333333331,0.6,1],"xyz":[0.300984851826846311,0.303408429717049566,0.988810486769736152],"hpluv":[249.783903318571561,209.303089797111312,61.9472031658153384],"hsluv":[249.783903318571561,99.9999999999986,61.9472031658153384]},"#110000":{"lch":[1.07666134976862637,3.62084603829176643,12.1770506300617818],"luv":[1.07666134976862637,3.53937866928378497,0.763756943295526236],"rgb":[0.0666666666666666657,0,0],"xyz":[0.00231161193210362246,0.00119192490249095569,0.000108356809317355026],"hpluv":[12.1770506300617818,426.746789183125145,1.07666134976862637],"hsluv":[12.1770506300617818,100.000000000002203,1.07666134976862637]},"#110011":{"lch":[1.44219482929484544,3.28508596549136378,307.715012949243601],"luv":[1.44219482929484544,2.00959989444743092,-2.59871084672866193],"rgb":[0.0666666666666666657,0,0.0666666666666666657],"xyz":[0.0033232774317407442,0.00159659110234581,0.00543646177407298634],"hpluv":[307.715012949243601,289.042783730483393,1.44219482929484544],"hsluv":[307.715012949243601,99.9999999999988347,1.44219482929484544]},"#110022":{"lch":[2.1197964535087821,6.27745605271938789,280.884754167684719],"luv":[2.1197964535087821,1.18539805862553327,-6.16451830530416167],"rgb":[0.0666666666666666657,0,0.133333333333333331],"xyz":[0.00519863557021776369,0.00234673435773662814,0.0153133479700521824],"hpluv":[280.884754167684719,375.775833064690062,2.1197964535087821],"hsluv":[280.884754167684719,99.9999999999998721,2.1197964535087821]},"#110033":{"lch":[3.23545797359596321,11.0622687483975319,272.972319481398301],"luv":[3.23545797359596321,0.57361730895702967,-11.0473867065762477],"rgb":[0.0666666666666666657,0,0.2],"xyz":[0.00828638630267550247,0.00358183465071974143,0.0315755018276633256],"hpluv":[272.972319481398301,433.858158519435221,3.23545797359596321],"hsluv":[272.972319481398301,100.000000000000355,3.23545797359596321]},"#110044":{"lch":[4.84621421062803659,17.7312810137515946,269.891014646828467],"luv":[4.84621421062803659,-0.0337275934556249754,-17.7312489362161827],"rgb":[0.0666666666666666657,0,0.266666666666666663],"xyz":[0.012744381546894383,0.0053650327484073175,0.0550542767805499642],"hpluv":[269.891014646828467,464.276639746945534,4.84621421062803659],"hsluv":[269.891014646828467,100.000000000000711,4.84621421062803659]},"#110055":{"lch":[7.00054481789469563,26.532890242342738,268.413820694361107],"luv":[7.00054481789469563,-0.734444075336115332,-26.5227233992365541],"rgb":[0.0666666666666666657,0,0.333333333333333315],"xyz":[0.0187067955862563751,0.00774999836415214954,0.0864563240545238726],"hpluv":[268.413820694361107,480.941270902403687,7.00054481789469563],"hsluv":[268.413820694361107,100.000000000000682,7.00054481789469563]},"#110066":{"lch":[9.62818818466394,37.2351477319955,267.604082628906383],"luv":[9.62818818466394,-1.55659527409507947,-37.20259719127408],"rgb":[0.0666666666666666657,0,0.4],"xyz":[0.0262917913597645499,0.010783996673555462,0.126403968461667848],"hpluv":[267.604082628906383,490.735908571457742,9.62818818466394],"hsluv":[267.604082628906383,100.000000000000753,9.62818818466394]},"#110077":{"lch":[12.2928363787590555,48.1341065988899643,267.117295446388],"luv":[12.2928363787590555,-2.42073458662620622,-48.0731969202633138],"rgb":[0.0666666666666666657,0,0.466666666666666674],"xyz":[0.0356058043799664659,0.0145096018816362783,0.175457770368065757],"hpluv":[267.117295446388,496.866985521105335,12.2928363787590555],"hsluv":[267.117295446388,100.000000000000739,12.2928363787590555]},"#110088":{"lch":[14.9348588897968106,58.9551979191609803,266.804247897724281],"luv":[14.9348588897968106,-3.28660375460643372,-58.8635166928348781],"rgb":[0.0666666666666666657,0,0.533333333333333326],"xyz":[0.0467462214819102939,0.0189657687224138727,0.234130633771637925],"hpluv":[266.804247897724281,500.910695182750828,14.9348588897968106],"hsluv":[266.804247897724281,100.000000000000753,14.9348588897968106]},"#110099":{"lch":[17.5475874535139624,69.6538923837914297,266.59230255326986],"luv":[17.5475874535139624,-4.14026096141065292,-69.5307339482636],"rgb":[0.0666666666666666657,0,0.6],"xyz":[0.0598031855909830073,0.0241885543660430302,0.302897311412755832],"hpluv":[266.59230255326986,503.694607743992833,17.5475874535139624],"hsluv":[266.59230255326986,100.000000000000796,17.5475874535139624]},"#1100aa":{"lch":[20.1284543895036734,80.2134478690449,266.442863009455],"luv":[20.1284543895036734,-4.97675334080985809,-80.0589104673847203],"rgb":[0.0666666666666666657,0,0.66666666666666663],"xyz":[0.0748608785562355494,0.0302116315521441317,0.382201161029754433],"hpluv":[266.442863009455,505.680355905096519,20.1284543895036734],"hsluv":[266.442863009455,100.000000000000782,20.1284543895036734]},"#1100bb":{"lch":[22.6769756305364183,90.6302333913987894,266.3339747285724],"luv":[22.6769756305364183,-5.79494806122388795,-90.444777525002138],"rgb":[0.0666666666666666657,0,0.733333333333333282],"xyz":[0.0919984706635722,0.0370666683950788903,0.472459146128396179],"hpluv":[266.3339747285724,507.139328846885462,22.6769756305364183],"hsluv":[266.3339747285724,100.000000000001,22.6769756305364183]},"#1100cc":{"lch":[25.1937235339869332,100.906819147977927,266.252448568601267],"luv":[25.1937235339869332,-6.59531864805210422,-100.691051849175651],"rgb":[0.0666666666666666657,0,0.8],"xyz":[0.111290846107293936,0.0447836185725676919,0.574065656798666279],"hpluv":[266.252448568601267,508.238409831726415,25.1937235339869332],"hsluv":[266.252448568601267,100.000000000000824,25.1937235339869332]},"#1100dd":{"lch":[27.6797893663012289,111.048607057141055,266.189998210144608],"luv":[27.6797893663012289,-7.37896669992084409,-110.803176758488192],"rgb":[0.0666666666666666657,0,0.866666666666666696],"xyz":[0.132809171657927494,0.0533909487928212259,0.687395504698672277],"hpluv":[266.189998210144608,509.084249760461944,27.6797893663012289],"hsluv":[266.189998210144608,100.000000000000938,27.6797893663012289]},"#1100ee":{"lch":[30.1364964584496846,121.062148077250455,266.141219022825339],"luv":[30.1364964584496846,-8.14718371295858823,-120.787694301304626],"rgb":[0.0666666666666666657,0,0.933333333333333348],"xyz":[0.156621351924102231,0.0629158208992912638,0.8128063207671955],"hpluv":[266.141219022825339,509.74730741907581,30.1364964584496846],"hsluv":[266.141219022825339,100.000000000000952,30.1364964584496846]},"#1100ff":{"lch":[32.5652456752648263,130.954293728553409,266.102472093749839],"luv":[32.5652456752648263,-8.90125725083502495,-130.651424275813781],"rgb":[0.0666666666666666657,0,1],"xyz":[0.182792400333933625,0.0733842402632239599,0.950640509058977345],"hpluv":[266.102472093749839,510.275492181060656,32.5652456752648263],"hsluv":[266.102472093749839,100.000000000001108,32.5652456752648263]},"#111100":{"lch":[4.69779601336656771,5.17885327658484673,85.8743202181747307],"luv":[4.69779601336656771,0.372589941443898953,5.16543299210515716],"rgb":[0.0666666666666666657,0.0666666666666666657,0],"xyz":[0.00431601219303203148,0.00520072542434782924,0.000776490229626805866],"hpluv":[85.8743202181747307,139.887458074797621,4.69779601336656771],"hsluv":[85.8743202181747307,100.000000000002359,4.69779601336656771]},"#111111":{"lch":[5.06332949289278655,2.68159353999537178e-13,0],"luv":[5.06332949289278655,2.52120910544652531e-13,9.13481559944393266e-14],"rgb":[0.0666666666666666657,0.0666666666666666657,0.0666666666666666657],"xyz":[0.00532767769266915322,0.00560539162420268383,0.00610459519438243722],"hpluv":[0,6.72041492281092e-12,5.06332949289278655],"hsluv":[0,1.92419399944792277e-12,5.06332949289278655]},"#111122":{"lch":[5.74093111710672321,6.60006851394265048,265.874320218179719],"luv":[5.74093111710672321,-0.474838542395297381,-6.58296534605743222],"rgb":[0.0666666666666666657,0.0666666666666666657,0.133333333333333331],"xyz":[0.00720303583114617271,0.00635553487959350169,0.0159814813903616341],"hpluv":[265.874320218179719,145.883251481840432,5.74093111710672321],"hsluv":[265.874320218179719,28.41442223352254,5.74093111710672321]},"#111133":{"lch":[6.85659263719390388,14.212336546779186,265.874320218178582],"luv":[6.85659263719390388,-1.02249925976518052,-14.1755072354640976],"rgb":[0.0666666666666666657,0.0666666666666666657,0.2],"xyz":[0.0102907865636039132,0.00759063517257661455,0.0322436352479727809],"hpluv":[265.874320218178582,263.024656142887807,6.85659263719390388],"hsluv":[265.874320218178582,51.2306489028398957,6.85659263719390388]},"#111144":{"lch":[8.45853257854777141,22.7927945223118087,265.874320218178241],"luv":[8.45853257854777141,-1.63981590573345759,-22.7337301367732181],"rgb":[0.0666666666666666657,0.0666666666666666657,0.266666666666666663],"xyz":[0.0147487818078227903,0.00937383327026419105,0.0557224102008594194],"hpluv":[265.874320218178241,341.933676209697239,8.45853257854777141],"hsluv":[265.874320218178241,66.600159737267461,8.45853257854777141]},"#111155":{"lch":[10.3782295585045325,32.1242805487719707,265.874320218178127],"luv":[10.3782295585045325,-2.31116487943396587,-32.0410349033279545],"rgb":[0.0666666666666666657,0.0666666666666666657,0.333333333333333315],"xyz":[0.0207111958471847858,0.011758798886009024,0.0871244574748333278],"hpluv":[265.874320218178127,392.780088665713265,10.3782295585045325],"hsluv":[265.874320218178127,76.5037738801481453,10.3782295585045325]},"#111166":{"lch":[12.4757228248048477,41.8651930040424887,265.87432021817807],"luv":[12.4757228248048477,-3.01196982745712916,-41.7567051265328644],"rgb":[0.0666666666666666657,0.0666666666666666657,0.4],"xyz":[0.0282961916206929606,0.0147927971954123355,0.12707210188197729],"hpluv":[265.87432021817807,425.820638501567,12.4757228248048477],"hsluv":[265.87432021817807,82.9392496755345263,12.4757228248048477]},"#111177":{"lch":[14.6896895275036599,51.8467212520223697,265.874320218178],"luv":[14.6896895275036599,-3.73008575521422614,-51.7123676197837199],"rgb":[0.0666666666666666657,0.0666666666666666657,0.466666666666666674],"xyz":[0.0376102046408948731,0.0185184024034931519,0.176125903788375199],"hpluv":[265.874320218178,447.865910041391658,14.6896895275036599],"hsluv":[265.874320218178,87.2331192419333235,14.6896895275036599]},"#111188":{"lch":[16.9766940539391484,61.9476661879793511,265.874320218178],"luv":[16.9766940539391484,-4.45679305530888747,-61.7871373491236469],"rgb":[0.0666666666666666657,0.0666666666666666657,0.533333333333333326],"xyz":[0.0487506217428387,0.0229745692442707428,0.234798767191947366],"hpluv":[265.874320218178,463.03215765547759,16.9766940539391484],"hsluv":[265.874320218178,90.1871263608273495,16.9766940539391484]},"#111199":{"lch":[19.3069968916820471,72.0861980616198537,265.874320218178],"luv":[19.3069968916820471,-5.18620452834737478,-71.8993966147786],"rgb":[0.0666666666666666657,0.0666666666666666657,0.6],"xyz":[0.0618075858519114146,0.0281973548878999072,0.303565444833065246],"hpluv":[265.874320218178,473.779996738615694,19.3069968916820471],"hsluv":[265.874320218178,92.280537596895428,19.3069968916820471]},"#1111aa":{"lch":[21.6605350192491244,82.2093341223612839,265.874320218177957],"luv":[21.6605350192491244,-5.91450835752722703,-81.9962999636616274],"rgb":[0.0666666666666666657,0.0666666666666666657,0.66666666666666663],"xyz":[0.0768652788171639567,0.0342204320740010087,0.382869294450063846],"hpluv":[265.874320218177957,481.605322004481,21.6605350192491244],"hsluv":[265.874320218177957,93.8047159652847569,21.6605350192491244]},"#1111bb":{"lch":[24.0238472654082429,92.2838634174554215,265.874320218177957],"luv":[24.0238472654082429,-6.63931519789526092,-92.0447225046312241],"rgb":[0.0666666666666666657,0.0666666666666666657,0.733333333333333282],"xyz":[0.0940028709245006,0.0410754689169357673,0.473127279548705593],"hpluv":[265.874320218177957,487.441538809997496,24.0238472654082429],"hsluv":[265.874320218177957,94.9414655706975736,24.0238472654082429]},"#1111cc":{"lch":[26.3879200105999,102.289669569688542,265.874320218177957],"luv":[26.3879200105999,-7.35917778701558589,-102.024599989292597],"rgb":[0.0666666666666666657,0.0666666666666666657,0.8],"xyz":[0.113295246368222344,0.0487924190944245689,0.574733790218975749],"hpluv":[265.874320218177957,491.887677819884516,26.3879200105999],"hsluv":[265.874320218177957,95.8074626598259727,26.3879200105999]},"#1111dd":{"lch":[28.7467318202544035,112.215160110792439,265.874320218177957],"luv":[28.7467318202544035,-8.07326211070735766,-111.924369989661315],"rgb":[0.0666666666666666657,0.0666666666666666657,0.866666666666666696],"xyz":[0.134813571918855901,0.0573997493146781,0.688063638118981746],"hpluv":[265.874320218177957,495.338839734480189,28.7467318202544035],"hsluv":[265.874320218177957,96.479663003878315,28.7467318202544035]},"#1111ee":{"lch":[31.096282761883856,122.054240127147821,265.874320218177957],"luv":[31.096282761883856,-8.78112967353786367,-121.737953386246701],"rgb":[0.0666666666666666657,0.0666666666666666657,0.933333333333333348],"xyz":[0.158625752185030638,0.0669246214211481338,0.813474454187505],"hpluv":[265.874320218177957,498.062358817216193,31.096282761883856],"hsluv":[265.874320218177957,97.0101366558694451,31.096282761883856]},"#1111ff":{"lch":[33.4339475813396589,131.804336466263976,265.874320218177957],"luv":[33.4339475813396589,-9.48259535137154863,-131.462783694528071],"rgb":[0.0666666666666666657,0.0666666666666666657,1],"xyz":[0.184796800594862032,0.07739304078508083,0.951308642479286815],"hpluv":[265.874320218177957,500.243401112503761,33.4339475813396589],"hsluv":[265.874320218177957,99.9999999999995168,33.4339475813396589]},"#66aa00":{"lch":[62.9888010115071921,81.5107592316300185,114.758667910078074],"luv":[62.9888010115071921,-34.136471206054587,74.0182761493062884],"rgb":[0.4,0.66666666666666663,0],"xyz":[0.198534632170994735,0.315734905503604946,0.0504821063864305253],"hpluv":[114.758667910078074,164.206718875588678,62.9888010115071921],"hsluv":[114.758667910078074,100.000000000002245,62.9888010115071921]},"#66aa11":{"lch":[63.0225323172591345,80.1801511939703744,115.156040801232848],"luv":[63.0225323172591345,-34.0833758310267285,72.5753411114886262],"rgb":[0.4,0.66666666666666663,0.0666666666666666657],"xyz":[0.199546297670631867,0.316139571703459799,0.055810211351186155],"hpluv":[115.156040801232848,161.439702186697787,63.0225323172591345],"hsluv":[115.156040801232848,97.8915472494395,63.0225323172591345]},"#66aa22":{"lch":[63.0849851082382287,77.7526522520100372,115.919582231606014],"luv":[63.0849851082382287,-33.9864002990590066,69.9313915701248],"rgb":[0.4,0.66666666666666663,0.133333333333333331],"xyz":[0.201421655809108868,0.316889714958850599,0.0656870975471653545],"hpluv":[115.919582231606014,156.397041701241,63.0849851082382287],"hsluv":[115.919582231606014,94.0329763727763748,63.0849851082382287]},"#66aa33":{"lch":[63.1875983682703577,73.8659889058236416,117.258215410479664],"luv":[63.1875983682703577,-33.8307250746429062,65.6632801340230827],"rgb":[0.4,0.66666666666666663,0.2],"xyz":[0.20450940654156663,0.318124815251833726,0.0819492514047764908],"hpluv":[117.258215410479664,148.337854737344315,63.1875983682703577],"hsluv":[117.258215410479664,87.8175568215645228,63.1875983682703577]},"#66aa44":{"lch":[63.3352806074861121,68.495891054581449,119.389904478135335],"luv":[63.3352806074861121,-33.6143748396710436,59.6804900742209057],"rgb":[0.4,0.66666666666666663,0.266666666666666663],"xyz":[0.208967401785785489,0.319908013349521292,0.105428026357663129],"hpluv":[119.389904478135335,137.232870385557277,63.3352806074861121],"hsluv":[119.389904478135335,79.1339200396795093,63.3352806074861121]},"#66aa55":{"lch":[63.5319451116367162,61.7628687774086131,122.670093374403834],"luv":[63.5319451116367162,-33.3396585938880747,51.9915293529473],"rgb":[0.4,0.66666666666666663,0.333333333333333315],"xyz":[0.214929815825147474,0.322292978965266153,0.136830073631637045],"hpluv":[122.670093374403834,123.360077774302084,63.5319451116367162],"hsluv":[122.670093374403834,68.0252461175988401,63.5319451116367162]},"#66aa66":{"lch":[63.7807317293932101,53.9656100581627314,127.715012949238869],"luv":[63.7807317293932101,-33.0126168434810836,42.6902119706049703],"rgb":[0.4,0.66666666666666663,0.4],"xyz":[0.22251481159865566,0.325326977274669471,0.176777718038781],"hpluv":[127.715012949238869,107.366036241042551,63.7807317293932101],"hsluv":[127.715012949238869,54.6684489206366493,63.7807317293932101]},"#66aa77":{"lch":[64.0841229578331308,45.668717811445795,135.623736827110406],"luv":[64.0841229578331308,-32.6422859505805931,31.9392071670853355],"rgb":[0.4,0.66666666666666663,0.466666666666666674],"xyz":[0.231828824618857565,0.329052582482750267,0.225831519945178916],"hpluv":[135.623736827110406,90.428994130424627,64.0841229578331308],"hsluv":[135.623736827110406,56.3153951517164302,64.0841229578331308]},"#66aa88":{"lch":[64.4440140424290888,37.9133385548872752,148.25026899586868],"luv":[64.4440140424290888,-32.239785461804118,19.9503752785341248],"rgb":[0.4,0.66666666666666663,0.533333333333333326],"xyz":[0.242969241720801421,0.333508749323527864,0.284504383348751055],"hpluv":[148.25026899586868,74.65325904191441,64.4440140424290888],"hsluv":[148.25026899586868,58.1346686170252127,64.4440140424290888]},"#66aa99":{"lch":[64.861761772217136,32.5704605989434484,167.654678216446086],"luv":[64.861761772217136,-31.8173259789585323,6.96366793981576304],"rgb":[0.4,0.66666666666666663,0.6],"xyz":[0.256026205829874121,0.338731534967157,0.353271060989869],"hpluv":[167.654678216446086,63.7198120272805681,64.861761772217136],"hsluv":[167.654678216446086,60.083023100845935,64.861761772217136]},"#66aaaa":{"lch":[65.3382237636027,32.1097126044189949,192.177050630060876],"luv":[65.3382237636027,-31.387258852500235,-6.77300710648746396],"rgb":[0.4,0.66666666666666663,0.66666666666666663],"xyz":[0.271083898795126677,0.344754612153258144,0.432574910606867591],"hpluv":[192.177050630060876,62.3603323483304592,65.3382237636027],"hsluv":[192.177050630060876,62.1162357127798757,65.3382237636027]},"#66aabb":{"lch":[65.8737942906507641,37.4229485671739255,214.174175962111633],"luv":[65.8737942906507641,-30.9612713447490577,-21.020864781881972],"rgb":[0.4,0.66666666666666663,0.733333333333333282],"xyz":[0.288221490902463295,0.351609648996192903,0.522832895705509282],"hpluv":[214.174175962111633,72.0882777495769744,65.8737942906507641],"hsluv":[214.174175962111633,64.192083786910942,65.8737942906507641]},"#66aacc":{"lch":[66.4684397846860833,46.8829891397435361,229.336310284400895],"luv":[66.4684397846860833,-30.5497910563422188,-35.5629714322516],"rgb":[0.4,0.66666666666666663,0.8],"xyz":[0.30751386634618505,0.359326599173681704,0.624439406375779438],"hpluv":[229.336310284400895,89.5033179536005,66.4684397846860833],"hsluv":[229.336310284400895,66.2725553364081748,66.4684397846860833]},"#66aadd":{"lch":[67.1217354618507471,58.5746749070863473,239.007496148652194],"luv":[67.1217354618507471,-30.1616186688116876,-50.2122425285710676],"rgb":[0.4,0.66666666666666663,0.866666666666666696],"xyz":[0.329032191896818593,0.367933929393935211,0.737769254275785435],"hpluv":[239.007496148652194,110.735287258409116,67.1217354618507471],"hsluv":[239.007496148652194,68.3252248927570349,67.1217354618507471]},"#66aaee":{"lch":[67.8329035309127,71.3390505041132,245.305718817638592],"luv":[67.8329035309127,-29.803771094245274,-64.8150858627082584],"rgb":[0.4,0.66666666666666663,0.933333333333333348],"xyz":[0.352844372162993358,0.377458801500405228,0.863180070344308659],"hpluv":[245.305718817638592,133.452355648257935,67.8329035309127],"hsluv":[245.305718817638592,80.362890995181445,67.8329035309127]},"#66aaff":{"lch":[68.6008528128324144,84.5574659264264312,249.594848961048797],"luv":[68.6008528128324144,-29.4814940521041038,-79.2515397475312],"rgb":[0.4,0.66666666666666663,1],"xyz":[0.379015420572824724,0.387927220864337952,1.00101425863609061],"hpluv":[249.594848961048797,156.409011428865199,68.6008528128324144],"hsluv":[249.594848961048797,99.9999999999981,68.6008528128324144]},"#112200":{"lch":[11.0156269675282488,14.1286449823385087,113.920199516574741],"luv":[11.0156269675282488,-5.72865521459208082,12.9151507335100835],"rgb":[0.0666666666666666657,0.133333333333333331,0],"xyz":[0.00803163592779996757,0.0126319728938838038,0.00201503147454941628],"hpluv":[113.920199516574741,162.753605553330914,11.0156269675282488],"hsluv":[113.920199516574741,100.000000000002302,11.0156269675282488]},"#112211":{"lch":[11.3010826742418828,9.17677244733547,127.715012949238741],"luv":[11.3010826742418828,-5.61374683501564142,7.25940762201209555],"rgb":[0.0666666666666666657,0.133333333333333331,0.0666666666666666657],"xyz":[0.00904330142743709,0.0130366390937386584,0.00734313643930504731],"hpluv":[127.715012949238741,103.040803658029205,11.3010826742418828],"hsluv":[127.715012949238741,52.4661346244892783,11.3010826742418828]},"#112222":{"lch":[11.8149934741043623,5.60956124878379736,192.177050630060876],"luv":[11.8149934741043623,-5.48334870304322308,-1.18324317225625331],"rgb":[0.0666666666666666657,0.133333333333333331,0.133333333333333331],"xyz":[0.0109186595659141079,0.0137867823491294762,0.0172200226352842434],"hpluv":[192.177050630060876,60.2469040904941551,11.8149934741043623],"hsluv":[192.177050630060876,60.0110800331641911,11.8149934741043623]},"#112233":{"lch":[12.6219648570067733,12.7575995118883281,244.93155638428982],"luv":[12.6219648570067733,-5.40540262923445,-11.5558629154900672],"rgb":[0.0666666666666666657,0.133333333333333331,0.2],"xyz":[0.0140064102983718484,0.0150218826421125891,0.0334821764928953866],"hpluv":[244.93155638428982,128.257072990564865,12.6219648570067733],"hsluv":[244.93155638428982,68.2965554989448265,12.6219648570067733]},"#112244":{"lch":[13.7124312845167182,23.0561698733830092,256.354402060867073],"luv":[13.7124312845167182,-5.43930918870511082,-22.4053762472305387],"rgb":[0.0666666666666666657,0.133333333333333331,0.266666666666666663],"xyz":[0.0184644055425907255,0.0168050807398001656,0.0569609514457820251],"hpluv":[256.354402060867073,213.359519949101497,13.7124312845167182],"hsluv":[256.354402060867073,75.5965994738604508,13.7124312845167182]},"#112255":{"lch":[15.056320299603339,33.5848303856462849,260.40485184836416],"luv":[15.056320299603339,-5.59809589119781581,-33.114983835502386],"rgb":[0.0666666666666666657,0.133333333333333331,0.333333333333333315],"xyz":[0.024426819581952721,0.019190046355545,0.0883629987197559336],"hpluv":[260.40485184836416,283.050313811336878,15.056320299603339],"hsluv":[260.40485184836416,81.3424686793067,15.056320299603339]},"#112266":{"lch":[16.6136212231118279,43.9645077489691118,262.329755848243337],"luv":[16.6136212231118279,-5.86800935048734384,-43.5711419160865958],"rgb":[0.0666666666666666657,0.133333333333333331,0.4],"xyz":[0.0320118153554608958,0.02222404466494831,0.128310643126899909],"hpluv":[262.329755848243337,335.797328537363626,16.6136212231118279],"hsluv":[262.329755848243337,85.6428490187558396,16.6136212231118279]},"#112277":{"lch":[18.3427569840269769,54.1821774694947678,263.400149453671133],"luv":[18.3427569840269769,-6.22740469049246936,-53.8231157232341815],"rgb":[0.0666666666666666657,0.133333333333333331,0.466666666666666674],"xyz":[0.0413258283756628153,0.0259496498730291264,0.177364445033297818],"hpluv":[263.400149453671133,374.827260372181627,18.3427569840269769],"hsluv":[263.400149453671133,88.8099744527525559,18.3427569840269769]},"#112288":{"lch":[20.2056943122802366,64.2803592359499,264.056887374403459],"luv":[20.2056943122802366,-6.65565132438349316,-63.9348644242795103],"rgb":[0.0666666666666666657,0.133333333333333331,0.533333333333333326],"xyz":[0.0524662454776066434,0.0304058167138067173,0.236037308436869986],"hpluv":[264.056887374403459,403.686144257890874,20.2056943122802366],"hsluv":[264.056887374403459,91.1461001738222762,20.2056943122802366]},"#112299":{"lch":[22.17018380613613,74.2918952905243799,264.488199331991609],"luv":[22.17018380613613,-7.13579321215933149,-73.9484020185124677],"rgb":[0.0666666666666666657,0.133333333333333331,0.6],"xyz":[0.0655232095866793568,0.0356286023574358818,0.304803986077987865],"hpluv":[264.488199331991609,425.217833826531262,22.17018380613613],"hsluv":[264.488199331991609,92.8866294242426136,22.17018380613613]},"#1122aa":{"lch":[24.2101316823922517,84.2333021684004848,264.786067280823943],"luv":[24.2101316823922517,-7.6546801533155886,-83.8847725510625537],"rgb":[0.0666666666666666657,0.133333333333333331,0.66666666666666663],"xyz":[0.0805809025519319,0.0416516795435369833,0.384107835694986466],"hpluv":[264.786067280823943,441.495215422381477,24.2101316823922517],"hsluv":[264.786067280823943,94.2012423737010209,24.2101316823922517]},"#1122bb":{"lch":[26.3050242232650149,94.1101405136049891,264.999933480500431],"luv":[26.3050242232650149,-8.20234804116949334,-93.7520134935884926],"rgb":[0.0666666666666666657,0.133333333333333331,0.733333333333333282],"xyz":[0.0977184946592685455,0.0485067163864717418,0.474365820793628212],"hpluv":[264.999933480500431,453.98033637772636,26.3050242232650149],"hsluv":[264.999933480500431,95.2089691602506605,26.3050242232650149]},"#1122cc":{"lch":[28.4390102065576187,103.92243186966887,265.158337172634162],"luv":[28.4390102065576187,-8.77130520241401612,-103.551610565708117],"rgb":[0.0666666666666666657,0.133333333333333331,0.8],"xyz":[0.117010870102990286,0.0562236665639605435,0.575972331463898368],"hpluv":[265.158337172634162,463.69685512523705,28.4390102065576187],"hsluv":[265.158337172634162,95.9928942328389496,28.4390102065576187]},"#1122dd":{"lch":[30.599961250020371,113.668086087716972,265.278693166229971],"luv":[30.599961250020371,-9.35592092097037664,-113.282392888591403],"rgb":[0.0666666666666666657,0.133333333333333331,0.866666666666666696],"xyz":[0.138529195653623816,0.0648309967842140705,0.689302179363904366],"hpluv":[265.278693166229971,471.364637015548908,30.599961250020371],"hsluv":[265.278693166229971,96.6113336559982,30.599961250020371]},"#1122ee":{"lch":[32.7786459144851463,123.344693870669801,265.37211393361406],"luv":[32.7786459144851463,-9.95194954038693247,-122.942556531067964],"rgb":[0.0666666666666666657,0.133333333333333331,0.933333333333333348],"xyz":[0.162341375919798553,0.0743558688906841,0.814712995432427589],"hpluv":[265.37211393361406,477.494956838131543,32.7786459144851463],"hsluv":[265.37211393361406,97.1056530386567118,32.7786459144851463]},"#1122ff":{"lch":[34.9680553815075,132.950321242967135,265.445956583698],"luv":[34.9680553815075,-10.5561742154436597,-132.530581770930752],"rgb":[0.0666666666666666657,0.133333333333333331,1],"xyz":[0.188512424329629946,0.0848242882546168114,0.952547183724209434],"hpluv":[265.445956583698,482.455471693424897,34.9680553815075],"hsluv":[265.445956583698,99.9999999999995595,34.9680553815075]},"#66bb00":{"lch":[68.2883247343563,91.0397787832552297,117.384795663234385],"luv":[68.2883247343563,-41.875036539852637,80.8376313092488914],"rgb":[0.4,0.733333333333333282,0],"xyz":[0.232489130079593515,0.383643901320803504,0.0618002723559631373],"hpluv":[117.384795663234385,169.170277477244,68.2883247343563],"hsluv":[117.384795663234385,100.000000000002402,68.2883247343563]},"#66bb11":{"lch":[68.3179499939719079,89.8644626985519466,117.727722441428654],"luv":[68.3179499939719079,-41.8112733484955896,79.5452014710932644],"rgb":[0.4,0.733333333333333282,0.0666666666666666657],"xyz":[0.233500795579230647,0.384048567520658357,0.0671283773207187739],"hpluv":[117.727722441428654,166.91389144855998,68.3179499939719079],"hsluv":[117.727722441428654,98.2613130840239108,68.3179499939719079]},"#66bb22":{"lch":[68.3728123300379309,87.7153655991844374,118.381366327960222],"luv":[68.3728123300379309,-41.6944557120635579,77.1722600749346839],"rgb":[0.4,0.733333333333333282,0.133333333333333331],"xyz":[0.235376153717707648,0.384798710776049158,0.0770052635166979665],"hpluv":[118.381366327960222,162.791438416492724,68.3728123300379309],"hsluv":[118.381366327960222,95.072259168186676,68.3728123300379309]},"#66bb33":{"lch":[68.4629872592027766,84.2604886941914515,119.511012469656151],"luv":[68.4629872592027766,-41.5059446288263274,73.3286200296498691],"rgb":[0.4,0.733333333333333282,0.2],"xyz":[0.238463904450165409,0.386033811069032284,0.0932674173743091],"hpluv":[119.511012469656151,156.173540237969377,68.4629872592027766],"hsluv":[119.511012469656151,89.9157079277594846,68.4629872592027766]},"#66bb44":{"lch":[68.5928402387875451,79.4555052917154683,121.268984442668796],"luv":[68.5928402387875451,-41.2418962487648457,67.9137932600435761],"rgb":[0.4,0.733333333333333282,0.266666666666666663],"xyz":[0.242921899694384269,0.38781700916671985,0.116746192327195741],"hpluv":[121.268984442668796,146.988898097842537,68.5928402387875451],"hsluv":[121.268984442668796,82.6706505658268,68.5928402387875451]},"#66bb55":{"lch":[68.7658933773114711,73.3682686647690474,123.883282583110088],"luv":[68.7658933773114711,-40.9030232283392365,60.9085013577552417],"rgb":[0.4,0.733333333333333282,0.333333333333333315],"xyz":[0.248884313733746254,0.390201974782464711,0.148148239601169657],"hpluv":[123.883282583110088,135.386233996967292,68.7658933773114711],"hsluv":[123.883282583110088,73.3323147762666565,68.7658933773114711]},"#66bb66":{"lch":[68.985024233854773,66.1955602149500493,127.715012949239338],"luv":[68.985024233854773,-40.4940973290304953,52.3648763359380354],"rgb":[0.4,0.733333333333333282,0.4],"xyz":[0.256469309507254439,0.39323597309186803,0.188095884008313619],"hpluv":[127.715012949239338,121.76244699215377,68.985024233854773],"hsluv":[127.715012949239338,61.9987879490855889,68.985024233854773]},"#66bb77":{"lch":[69.2525700917713,58.3030977404443149,133.351332140289912],"luv":[69.2525700917713,-40.0233333378199134,42.395565742911792],"rgb":[0.4,0.733333333333333282,0.466666666666666674],"xyz":[0.265783322527456345,0.396961578299948825,0.237149685914711528],"hpluv":[133.351332140289912,106.830450835327468,69.2525700917713],"hsluv":[133.351332140289912,63.1630001095548,69.2525700917713]},"#66bb88":{"lch":[69.5703900447947632,50.3125315521488901,141.732198444264128],"luv":[69.5703900447947632,-39.5016033478381487,31.1604583428427624],"rgb":[0.4,0.733333333333333282,0.533333333333333326],"xyz":[0.276923739629400201,0.401417745140726423,0.295822549318283667],"hpluv":[141.732198444264128,91.7679559652102625,69.5703900447947632],"hsluv":[141.732198444264128,64.4651291783298888,69.5703900447947632]},"#66bb99":{"lch":[69.9399065468101924,43.264635747530761,154.168279853010262],"luv":[69.9399065468101924,-38.9415329854338594,18.8516767188195544],"rgb":[0.4,0.733333333333333282,0.6],"xyz":[0.2899807037384729,0.406640530784355581,0.364589226959401602],"hpluv":[154.168279853010262,78.4959645714096865,69.9399065468101924],"hsluv":[154.168279853010262,65.8787579381207848,69.9399065468101924]},"#66bbaa":{"lch":[70.3621368583926881,38.7745898249838348,171.579209782291855],"luv":[70.3621368583926881,-38.3565710720190296,5.67822786553099768],"rgb":[0.4,0.733333333333333282,0.66666666666666663],"xyz":[0.305038396703725456,0.412663607970456703,0.443893076576400203],"hpluv":[171.579209782291855,69.9274221790226278,70.3621368583926881],"hsluv":[171.579209782291855,67.37547943529961,70.3621368583926881]},"#66bbbb":{"lch":[70.8377198879813221,38.6292683935386592,192.177050630060933],"luv":[70.8377198879813221,-37.7601276376370194,-8.14819841495072161],"rgb":[0.4,0.733333333333333282,0.733333333333333282],"xyz":[0.322175988811062075,0.419518644813391461,0.534151061675042],"hpluv":[192.177050630060933,69.1976324805594629,70.8377198879813221],"hsluv":[192.177050630060933,68.9267726464228758,70.8377198879813221]},"#66bbcc":{"lch":[71.3669414392261103,43.4063518114314,211.106579982723787],"luv":[71.3669414392261103,-37.1648552128157,-22.4250956427882215],"rgb":[0.4,0.733333333333333282,0.8],"xyz":[0.341468364254783829,0.427235594990880263,0.635757572345312161],"hpluv":[211.106579982723787,77.1783568223693806,71.3669414392261103],"hsluv":[211.106579982723787,70.5055674968506736,71.3669414392261103]},"#66bbdd":{"lch":[71.9497594848613602,52.0084901368895629,225.300588521911806],"luv":[71.9497594848613602,-36.5821167433876298,-36.9679831866995059],"rgb":[0.4,0.733333333333333282,0.866666666666666696],"xyz":[0.362986689805417373,0.435842925211133769,0.749087420245318159],"hpluv":[225.300588521911806,91.724261948179759,71.9497594848613602],"hsluv":[225.300588521911806,72.0874065633031336,71.9497594848613602]},"#66bbee":{"lch":[72.5858302461357852,62.9426478584387183,235.089705553804919],"luv":[72.5858302461357852,-36.0216507769597953,-51.6160594653851135],"rgb":[0.4,0.733333333333333282,0.933333333333333348],"xyz":[0.386798870071592082,0.445367797317603786,0.874498236313841382],"hpluv":[235.089705553804919,110.035415213757233,72.5858302461357852],"hsluv":[235.089705553804919,76.908955535231712,72.5858302461357852]},"#66bbff":{"lch":[73.2745353232689638,75.1445669264803513,241.815748730615525],"luv":[73.2745353232689638,-35.4914181095182641,-66.2349241650025817],"rgb":[0.4,0.733333333333333282,1],"xyz":[0.412969918481423504,0.45583621668153651,1.01233242460562312],"hpluv":[241.815748730615525,130.131920555189879,73.2745353232689638],"hsluv":[241.815748730615525,99.9999999999976552,73.2745353232689638]},"#113300":{"lch":[17.8585390793191152,25.0449080182821966,121.332554648991049],"luv":[17.8585390793191152,-13.0234653569097247,21.3924465113644295],"rgb":[0.0666666666666666657,0.2,0],"xyz":[0.0141493580168107792,0.0248674170719056023,0.00405427217088629669],"hpluv":[121.332554648991049,177.956083469309505,17.8585390793191152],"hsluv":[121.332554648991049,100.000000000002288,17.8585390793191152]},"#113311":{"lch":[18.041211184449395,20.8015074137336562,127.715012949239792],"luv":[18.041211184449395,-12.7249964056056086,16.4553084796651738],"rgb":[0.0666666666666666657,0.2,0.0666666666666666657],"xyz":[0.015161023516447901,0.0252720832717604552,0.00938237713564192902],"hpluv":[127.715012949239792,146.308124837666583,18.041211184449395],"hsluv":[127.715012949239792,74.4969128915689254,18.041211184449395]},"#113322":{"lch":[18.3747440863758129,14.8635488733567129,145.575764327225926],"luv":[18.3747440863758129,-12.2605616690393529,8.40260154180516672],"rgb":[0.0666666666666666657,0.2,0.133333333333333331],"xyz":[0.0170363816549249196,0.0260222265271512765,0.0192592633316211251],"hpluv":[145.575764327225926,102.645648490479701,18.3747440863758129],"hsluv":[145.575764327225926,76.8412554017051,18.3747440863758129]},"#113333":{"lch":[18.910205854271,11.9516732098830207,192.177050630061075],"luv":[18.910205854271,-11.6827660646039035,-2.5210056714682163],"rgb":[0.0666666666666666657,0.2,0.2],"xyz":[0.0201241323873826601,0.0272573268201343893,0.0355214171892322683],"hpluv":[192.177050630061075,80.19952200231,18.910205854271],"hsluv":[192.177050630061075,79.885597544945341,18.910205854271]},"#113344":{"lch":[19.6554681695294136,18.5554908550806559,233.185939638237187],"luv":[19.6554681695294136,-11.1188227079461566,-14.8552355236207116],"rgb":[0.0666666666666666657,0.2,0.266666666666666663],"xyz":[0.0245821276316015372,0.0290405249178219624,0.0590001921421189068],"hpluv":[233.185939638237187,119.79215597403514,19.6554681695294136],"hsluv":[233.185939638237187,83.0941728600946163,19.6554681695294136]},"#113355":{"lch":[20.6059777210847557,29.4541985213363553,248.778672986371305],"luv":[20.6059777210847557,-10.6615827984222822,-27.4568837045772334],"rgb":[0.0666666666666666657,0.2,0.333333333333333315],"xyz":[0.0305445416709635327,0.0314254905335667953,0.0904022394160928222],"hpluv":[248.778672986371305,181.381634101163,20.6059777210847557],"hsluv":[248.778672986371305,86.0667890851332089,20.6059777210847557]},"#113366":{"lch":[21.7480278014825927,41.0513772817531262,255.392805777322508],"luv":[21.7480278014825927,-10.3527823296753354,-39.7244946445288178],"rgb":[0.0666666666666666657,0.2,0.4],"xyz":[0.0381295374444717075,0.0344594888429701068,0.130349883823236784],"hpluv":[255.392805777322508,239.522976201191227,21.7480278014825927],"hsluv":[255.392805777322508,88.6137215649990537,21.7480278014825927]},"#113377":{"lch":[23.0621320749224097,52.4639032010768602,258.793139915612699],"luv":[23.0621320749224097,-10.1964540550792755,-51.4635158514711293],"rgb":[0.0666666666666666657,0.2,0.466666666666666674],"xyz":[0.04744355046467362,0.0381850940510509232,0.179403685729634693],"hpluv":[258.793139915612699,288.669213908808,23.0621320749224097],"hsluv":[258.793139915612699,90.7010140503724926,23.0621320749224097]},"#113388":{"lch":[24.5260866455155693,63.5079254673071389,260.778240759541745],"luv":[24.5260866455155693,-10.1775299952298717,-62.6871157444433322],"rgb":[0.0666666666666666657,0.2,0.533333333333333326],"xyz":[0.0585839675666174481,0.0426412608918285141,0.238076549133206861],"hpluv":[260.778240759541745,328.5783880762134,24.5260866455155693],"hsluv":[260.778240759541745,92.3732755032704,24.5260866455155693]},"#113399":{"lch":[26.1173586094444445,74.1961224571638667,262.040130643645512],"luv":[26.1173586094444445,-10.2746398160742789,-73.4812653968914447],"rgb":[0.0666666666666666657,0.2,0.6],"xyz":[0.0716409316756901615,0.0478640465354576786,0.30684322677432474],"hpluv":[262.040130643645512,360.488391101723778,26.1173586094444445],"hsluv":[262.040130643645512,93.700931793532277,26.1173586094444445]},"#1133aa":{"lch":[27.8146812937100378,84.589542856674214,262.892366774415223],"luv":[27.8146812937100378,-10.4665753413372666,-83.9395113240792767],"rgb":[0.0666666666666666657,0.2,0.66666666666666663],"xyz":[0.0866986246409427,0.0538871237215587801,0.386147076391323341],"hpluv":[262.892366774415223,385.906342473210088,27.8146812937100378],"hsluv":[262.892366774415223,94.7540719156047544,27.8146812937100378]},"#1133bb":{"lch":[29.5989386642012917,94.7497677250031245,263.494633441352278],"luv":[29.5989386642012917,-10.734795769033445,-94.1396974912241],"rgb":[0.0666666666666666657,0.2,0.733333333333333282],"xyz":[0.10383621674827935,0.0607421605644935386,0.476405061489965087],"hpluv":[263.494633441352278,406.201330660618282,29.5989386642012917],"hsluv":[263.494633441352278,95.59270717643426,29.5989386642012917]},"#1133cc":{"lch":[31.4535171675710927,104.725970292241058,263.935552719695806],"luv":[31.4535171675710927,-11.0639900580249932,-104.139891384844844],"rgb":[0.0666666666666666657,0.2,0.8],"xyz":[0.123128592192001091,0.0684591107419823403,0.578011572160235243],"hpluv":[263.935552719695806,422.497850271701509,31.4535171675710927],"hsluv":[263.935552719695806,96.2648935085394299,31.4535171675710927]},"#1133dd":{"lch":[33.3643121953656845,114.554023382916327,264.267643395871801],"luv":[33.3643121953656845,-11.4418472625073555,-113.981175658242762],"rgb":[0.0666666666666666657,0.2,0.866666666666666696],"xyz":[0.144646917742634634,0.0770664409622358743,0.691341420060241241],"hpluv":[264.267643395871801,435.679872957086786,33.3643121953656845],"hsluv":[264.267643395871801,96.8079128297289913,33.3643121953656845]},"#1133ee":{"lch":[35.3195411096734375,124.259061611723823,264.523680461367292],"luv":[35.3195411096734375,-11.8585821660500468,-123.691909281234786],"rgb":[0.0666666666666666657,0.2,0.933333333333333348],"xyz":[0.168459098008809371,0.0865913130687059,0.816752236128764464],"hpluv":[264.523680461367292,446.428943593210363,35.3195411096734375],"hsluv":[264.523680461367292,97.2502875158067752,35.3195411096734375]},"#1133ff":{"lch":[37.3094684856901466,133.858437412957159,264.724991571549936],"luv":[37.3094684856901466,-12.3064438760062309,-133.291532760957],"rgb":[0.0666666666666666657,0.2,1],"xyz":[0.194630146418640765,0.0970597324326386,0.954586424420546309],"hpluv":[264.724991571549936,455.266836240216,37.3094684856901466],"hsluv":[264.724991571549936,99.9999999999995168,37.3094684856901466]},"#66cc00":{"lch":[73.5514640948473328,100.417876322708906,119.311479215942285],"luv":[73.5514640948473328,-49.1602904566029579,87.5614968315714322],"rgb":[0.4,0.8,0],"xyz":[0.270712873389210462,0.460091387940038399,0.0745415201258350923],"hpluv":[119.311479215942285,173.244332851636557,73.5514640948473328],"hsluv":[119.311479215942285,100.00000000000226,73.5514640948473328]},"#66cc11":{"lch":[73.5777109322390572,99.3703085818509,119.605548775623987],"luv":[73.5777109322390572,-49.0915230219986611,86.397225621155485],"rgb":[0.4,0.8,0.0666666666666666657],"xyz":[0.271724538888847567,0.460496054139893252,0.079869625090590729],"hpluv":[119.605548775623987,171.375877908330068,73.5777109322390572],"hsluv":[119.605548775623987,98.5479766016144652,73.5777109322390572]},"#66cc22":{"lch":[73.626324929263788,97.4510710028789333,120.162888823436575],"luv":[73.626324929263788,-48.965269014871545,84.2562381661406192],"rgb":[0.4,0.8,0.133333333333333331],"xyz":[0.273599897027324623,0.461246197395284052,0.0897465112865699216],"hpluv":[120.162888823436575,167.954954584373922,73.626324929263788],"hsluv":[120.162888823436575,95.8800576342850377,73.626324929263788]},"#66cc33":{"lch":[73.7062524827218084,94.3550745227874,121.116489614327122],"luv":[73.7062524827218084,-48.7607908304490252,80.779114663321],"rgb":[0.4,0.8,0.2],"xyz":[0.276687647759782329,0.462481297688267179,0.106008665144181058],"hpluv":[121.116489614327122,162.442721914772306,73.7062524827218084],"hsluv":[121.116489614327122,91.5533619475712896,73.7062524827218084]},"#66cc44":{"lch":[73.8213986639243,90.0253172969507318,122.577193203242018],"luv":[73.8213986639243,-48.472817822786439,75.8613451418811451],"rgb":[0.4,0.8,0.266666666666666663],"xyz":[0.281145643004001244,0.464264495785954745,0.129487440097067696],"hpluv":[122.577193203242018,154.746814564283426,73.8213986639243],"hsluv":[122.577193203242018,85.4474048693987527,73.8213986639243]},"#66cc55":{"lch":[73.974942724102462,84.4934421806047879,124.700104619680829],"luv":[73.974942724102462,-48.100513339115345,69.4656921655632118],"rgb":[0.4,0.8,0.333333333333333315],"xyz":[0.28710805704336323,0.466649461401699606,0.160889487371041612],"hpluv":[124.700104619680829,144.936474170198323,73.974942724102462],"hsluv":[124.700104619680829,77.5306238992907,73.974942724102462]},"#66cc66":{"lch":[74.1695172801941567,77.8884466842553564,127.715012949239551],"luv":[74.1695172801941567,-47.6470375142611218,61.6146893443493937],"rgb":[0.4,0.8,0.4],"xyz":[0.294693052816871415,0.469683459711102924,0.200837131778185574],"hpluv":[127.715012949239551,133.256044234036153,74.1695172801941567],"hsluv":[127.715012949239551,67.8510775159793,74.1695172801941567]},"#66cc77":{"lch":[74.407302734023375,70.4570986939790203,131.971622948486811],"luv":[74.407302734023375,-47.1190629819757234,52.3831715350808551],"rgb":[0.4,0.8,0.466666666666666674],"xyz":[0.30400706583707332,0.47340906491918372,0.249890933684583483],"hpluv":[131.971622948486811,120.156846155807528,74.407302734023375],"hsluv":[131.971622948486811,68.6882673601907499,74.407302734023375]},"#66cc88":{"lch":[74.6900832163393602,62.6050444414555045,138.002106903522986],"luv":[74.6900832163393602,-46.5261552249599859,41.8892404980031543],"rgb":[0.4,0.8,0.533333333333333326],"xyz":[0.315147482939017121,0.477865231759961318,0.308563797088155622],"hpluv":[138.002106903522986,106.361808066007058,74.6900832163393602],"hsluv":[138.002106903522986,69.6340873295455367,74.6900832163393602]},"#66cc99":{"lch":[75.0192831982140405,54.9734389641357382,146.572693391746668],"luv":[75.0192831982140405,-45.8800303566060634,30.2836887782922481],"rgb":[0.4,0.8,0.6],"xyz":[0.32820444704808982,0.483088017403590475,0.377330474729273557],"hpluv":[146.572693391746668,92.9863760296957338,75.0192831982140405],"hsluv":[146.572693391746668,70.6723780843603,75.0192831982140405]},"#66ccaa":{"lch":[75.3959940236094,48.5503126646653,158.569930493367366],"luv":[75.3959940236094,-45.1937477629490587,17.7386026218441692],"rgb":[0.4,0.8,0.66666666666666663],"xyz":[0.343262140013342376,0.489111094589691597,0.456634324346272158],"hpluv":[158.569930493367366,81.7114817988577187,75.3959940236094],"hsluv":[158.569930493367366,71.7849539596152368,75.3959940236094]},"#66ccbb":{"lch":[75.8209952994642,44.7015709258060667,174.304687468137473],"luv":[75.8209952994642,-44.4809102105153755,4.43610979112772],"rgb":[0.4,0.8,0.733333333333333282],"xyz":[0.360399732120679051,0.495966131432626356,0.546892309444913849],"hpluv":[174.304687468137473,74.8122352806046109,75.8209952994642],"hsluv":[174.304687468137473,72.9527506991265113,75.8209952994642]},"#66cccc":{"lch":[76.2947739303160262,44.7620652034609634,192.177050630061018],"luv":[76.2947739303160262,-43.7549393425641924,-9.44180938207391],"rgb":[0.4,0.8,0.8],"xyz":[0.379692107564400749,0.503683081610115102,0.648498820115184],"hpluv":[192.177050630061018,75.6461904464395,76.2947739303160262],"hsluv":[192.177050630061018,74.1568646821725679,76.2947739303160262]},"#66ccdd":{"lch":[76.8175423984245782,49.1342213212598082,208.868111129197587],"luv":[76.8175423984245782,-43.0284772118039101,-23.7217590764220851],"rgb":[0.4,0.8,0.866666666666666696],"xyz":[0.401210433115034348,0.512290411830368719,0.76182866801519],"hpluv":[208.868111129197587,85.3113130970085791,76.8175423984245782],"hsluv":[208.868111129197587,75.3794120212671714,76.8175423984245782]},"#66ccee":{"lch":[77.3892571801628435,57.0358051623713038,222.109360872917676],"luv":[77.3892571801628435,-42.312941633688304,-38.245235531031426],"rgb":[0.4,0.8,0.933333333333333348],"xyz":[0.425022613381209058,0.521815283936838736,0.887239484083713226],"hpluv":[222.109360872917676,102.061631830010029,77.3892571801628435],"hsluv":[222.109360872917676,76.6041682601332923,77.3892571801628435]},"#66ccff":{"lch":[78.0096377377628158,67.2874731922355664,231.792303901557148],"luv":[78.0096377377628158,-41.6182406850010267,-52.872734853430309],"rgb":[0.4,0.8,1],"xyz":[0.451193661791040479,0.53228370330077146,1.02507367237549518],"hpluv":[231.792303901557148,124.498094909356865,78.0096377377628158],"hsluv":[231.792303901557148,99.9999999999966604,78.0096377377628158]},"#114400":{"lch":[24.4916204196936391,35.767443133059956,124.131260038140155],"luv":[24.4916204196936391,-20.0687794552527912,29.6066559991685239],"rgb":[0.0666666666666666657,0.266666666666666663,0],"xyz":[0.0229819284997768124,0.0425325580378379114,0.00699846233187489172],"hpluv":[124.131260038140155,185.314627891622,24.4916204196936391],"hsluv":[124.131260038140155,100.000000000002416,24.4916204196936391]},"#114411":{"lch":[24.6196313539200702,32.2821952767626144,127.715012949240105],"luv":[24.6196313539200702,-19.7481274165088401,25.5372589646650674],"rgb":[0.0666666666666666657,0.266666666666666663,0.0666666666666666657],"xyz":[0.0239935939994139341,0.0429372242376927643,0.0123265672966305223],"hpluv":[127.715012949240105,166.387555424049935,24.6196313539200702],"hsluv":[127.715012949240105,84.7209219338948,24.6196313539200702]},"#114422":{"lch":[24.8548180969752792,26.7199561105771828,135.968420687644709],"luv":[24.8548180969752792,-19.2104947057918238,18.5718321042894203],"rgb":[0.0666666666666666657,0.266666666666666663,0.133333333333333331],"xyz":[0.0258689521378909527,0.0436873674930835856,0.0222034534926097184],"hpluv":[135.968420687644709,136.415738329938534,24.8548180969752792],"hsluv":[135.968420687644709,85.5945702875542338,24.8548180969752792]},"#114433":{"lch":[25.2362525898650887,20.3101465248311648,155.348193219538018],"luv":[25.2362525898650887,-18.4590663004995292,8.4714180143512],"rgb":[0.0666666666666666657,0.266666666666666663,0.2],"xyz":[0.0289567028703486933,0.0449224677860667,0.0384656073502208651],"hpluv":[155.348193219538018,102.123929581721498,25.2362525898650887],"hsluv":[155.348193219538018,86.8340768870874911,25.2362525898650887]},"#114444":{"lch":[25.774812755707849,18.0038630185053101,192.177050630061132],"luv":[25.774812755707849,-17.5987843886529483,-3.79761393914762779],"rgb":[0.0666666666666666657,0.266666666666666663,0.266666666666666663],"xyz":[0.0334146981145675703,0.0467056658837542715,0.0619443823031075036],"hpluv":[192.177050630061132,88.6358691141452226,25.774812755707849],"hsluv":[192.177050630061132,88.2889223192016743,25.774812755707849]},"#114455":{"lch":[26.4741010086829718,23.9697809957076196,225.699525295295985],"luv":[26.4741010086829718,-16.7410035671662349,-17.1548593857925162],"rgb":[0.0666666666666666657,0.266666666666666663,0.333333333333333315],"xyz":[0.0393771121539295693,0.0490906314994991044,0.0933464295770814],"hpluv":[225.699525295295985,114.889984549549212,26.4741010086829718],"hsluv":[225.699525295295985,89.7968555301121398,26.4741010086829718]},"#114466":{"lch":[27.3316922889079734,34.6428172107851182,242.548035964380944],"luv":[27.3316922889079734,-15.9705048052882308,-30.7419544037807526],"rgb":[0.0666666666666666657,0.266666666666666663,0.4],"xyz":[0.0469621079274377407,0.052124629808902416,0.133294073984225381],"hpluv":[242.548035964380944,160.837015687659374,27.3316922889079734],"hsluv":[242.548035964380944,91.2329185483074525,27.3316922889079734]},"#114477":{"lch":[28.3404051997208484,46.6267191674415,250.798290317077829],"luv":[28.3404051997208484,-15.3352867062553546,-44.0327142242719844],"rgb":[0.0666666666666666657,0.266666666666666663,0.466666666666666674],"xyz":[0.0562761209476396601,0.0558502350169832323,0.18234787589062329],"hpluv":[250.798290317077829,208.770018220734585,28.3404051997208484],"hsluv":[250.798290317077829,92.5248535524246734,28.3404051997208484]},"#114488":{"lch":[29.4896359978219706,58.6954673108201632,255.342505689020953],"luv":[29.4896359978219706,-14.8523182742844106,-56.7852667926718055],"rgb":[0.0666666666666666657,0.266666666666666663,0.533333333333333326],"xyz":[0.0674165380495834882,0.0603064018577608302,0.241020739294195457],"hpluv":[255.342505689020953,252.565763352450517,29.4896359978219706],"hsluv":[255.342505689020953,93.6449802292742817,29.4896359978219706]},"#114499":{"lch":[30.7666487879374699,70.4540899928233699,258.107815399211404],"luv":[30.7666487879374699,-14.5185243824624628,-68.9419411278265102],"rgb":[0.0666666666666666657,0.266666666666666663,0.6],"xyz":[0.0804735021586562,0.0655291875013899877,0.309787416935313364],"hpluv":[258.107815399211404,290.579747717257874,30.7666487879374699],"hsluv":[258.107815399211404,94.5943513350065359,30.7666487879374699]},"#1144aa":{"lch":[32.1577052090601185,81.8040240174920541,259.917940759024589],"luv":[32.1577052090601185,-14.3204852090806973,-80.5408098347099894],"rgb":[0.0666666666666666657,0.266666666666666663,0.66666666666666663],"xyz":[0.0955311951239087437,0.0715522646874911,0.389091266552311965],"hpluv":[259.917940759024589,322.796594575352628,32.1577052090601185],"hsluv":[259.917940759024589,95.3887741756132925,32.1577052090601185]},"#1144bb":{"lch":[33.6489603009756664,92.7573184463875435,261.168522985608377],"luv":[33.6489603009756664,-14.2409127099882671,-91.6576048702508928],"rgb":[0.0666666666666666657,0.266666666666666663,0.733333333333333282],"xyz":[0.11266878723124539,0.0784073015304258547,0.479349251650953712],"hpluv":[261.168522985608377,349.796823816496214,33.6489603009756664],"hsluv":[261.168522985608377,96.0495339612535872,33.6489603009756664]},"#1144cc":{"lch":[35.2271045850644597,103.362934076908545,262.068884255867147],"luv":[35.2271045850644597,-14.262270250582695,-102.374234005860515],"rgb":[0.0666666666666666657,0.266666666666666663,0.8],"xyz":[0.131961162674967131,0.0861242517079146563,0.580955762321223812],"hpluv":[262.068884255867147,372.329293739207799,35.2271045850644597],"hsluv":[262.068884255867147,96.5982694251149638,35.2271045850644597]},"#1144dd":{"lch":[36.8797734412618,113.676357292171801,262.73849416957313],"luv":[36.8797734412618,-14.3684841809298494,-112.764625967365617],"rgb":[0.0666666666666666657,0.266666666666666663,0.866666666666666696],"xyz":[0.153479488225600674,0.0947315819281681903,0.69428561022122981],"hpluv":[262.73849416957313,391.13009227787353,36.8797734412618],"hsluv":[262.73849416957313,97.0546019825808,36.8797734412618]},"#1144ee":{"lch":[38.5957670998368911,123.747928777943088,263.249741523271325],"luv":[38.5957670998368911,-14.5455638799169762,-122.890099065165245],"rgb":[0.0666666666666666657,0.266666666666666663,0.933333333333333348],"xyz":[0.177291668491775412,0.104256454034638207,0.819696426289753],"hpluv":[263.249741523271325,406.853061330967478,38.5957670998368911],"hsluv":[263.249741523271325,97.4353215147193623,38.5957670998368911]},"#1144ff":{"lch":[40.3651306844127546,133.619394536005728,263.648645306126298],"luv":[40.3651306844127546,-14.7816672391382209,-132.799265471613751],"rgb":[0.0666666666666666657,0.266666666666666663,1],"xyz":[0.203462716901606805,0.114724873398570917,0.957530614581534878],"hpluv":[263.648645306126298,420.051425771921231,40.3651306844127546],"hsluv":[263.648645306126298,99.9999999999994458,40.3651306844127546]},"#66dd00":{"lch":[78.7732081443282084,109.616469768408933,120.762072840728067],"luv":[78.7732081443282084,-56.0659919017112145,94.1932853050883],"rgb":[0.4,0.866666666666666696,0],"xyz":[0.313346863936385611,0.54535936903439,0.0887528503082264109],"hpluv":[120.762072840728067,211.559351010719155,78.7732081443282084],"hsluv":[120.762072840728067,100.000000000002444,78.7732081443282084]},"#66dd11":{"lch":[78.7966434753788576,108.675393583239966,121.014553037765893],"luv":[78.7966434753788576,-55.9956244091473678,93.1387739746547],"rgb":[0.4,0.866666666666666696,0.0666666666666666657],"xyz":[0.314358529436022716,0.545764035234244882,0.0940809552729820475],"hpluv":[121.014553037765893,210.019013530063148,78.7966434753788576],"hsluv":[121.014553037765893,98.7735218244661866,78.7966434753788576]},"#66dd22":{"lch":[78.8400557089289435,106.948443645027297,121.491090191754736],"luv":[78.8400557089289435,-55.866227309203758,91.1972271745690506],"rgb":[0.4,0.866666666666666696,0.133333333333333331],"xyz":[0.316233887574499772,0.546514178489635682,0.10395784146896124],"hpluv":[121.491090191754736,207.186246213049145,78.8400557089289435],"hsluv":[121.491090191754736,96.5169147905729,78.8400557089289435]},"#66dd33":{"lch":[78.911446872650572,104.154611952746194,122.300539429107701],"luv":[78.911446872650572,-55.6560904548950788,88.037394249850891],"rgb":[0.4,0.866666666666666696,0.2],"xyz":[0.319321638306957478,0.547749278782618809,0.120219995326572376],"hpluv":[122.300539429107701,202.586476802368111,78.911446872650572],"hsluv":[122.300539429107701,92.8487034899531807,78.911446872650572]},"#66dd44":{"lch":[79.0143300648071687,100.229492569308348,123.526451276321851],"luv":[79.0143300648071687,-55.3589437481663,83.5544045983716899],"rgb":[0.4,0.866666666666666696,0.266666666666666663],"xyz":[0.323779633551176393,0.549532476880306375,0.143698770279459015],"hpluv":[123.526451276321851,196.088207898644384,79.0143300648071687],"hsluv":[123.526451276321851,87.6539206040991843,79.0143300648071687]},"#66dd55":{"lch":[79.1515854502963,95.1800529291645603,125.27945296022996],"luv":[79.1515854502963,-54.9726586351532518,77.699737954393882],"rgb":[0.4,0.866666666666666696,0.333333333333333315],"xyz":[0.329742047590538379,0.551917442496051125,0.17510081755343293],"hpluv":[125.27945296022996,187.665730733793509,79.1515854502963],"hsluv":[125.27945296022996,80.8868034505971707,79.1515854502963]},"#66dd66":{"lch":[79.3256225689869723,89.0890908185611607,127.715012949239735],"luv":[79.3256225689869723,-54.4988561596450722,70.4751075215082921],"rgb":[0.4,0.866666666666666696,0.4],"xyz":[0.337327043364046564,0.554951440805454443,0.215048461960576892],"hpluv":[127.715012949239735,177.410630109117562,79.3256225689869723],"hsluv":[127.715012949239735,72.5638298210149,79.3256225689869723]},"#66dd77":{"lch":[79.538466322575843,82.1265081512392072,131.057978326052336],"luv":[79.538466322575843,-53.9425296262626048,61.9271090770055395],"rgb":[0.4,0.866666666666666696,0.466666666666666674],"xyz":[0.346641056384248469,0.558677046013535294,0.264102263866974774],"hpluv":[131.057978326052336,165.560886464635786,79.538466322575843],"hsluv":[131.057978326052336,73.175897046832489,79.538466322575843]},"#66dd88":{"lch":[79.7918079202835173,74.5708009722257543,135.636001638862723],"luv":[79.7918079202835173,-53.3115731427918,52.1409678341327378],"rgb":[0.4,0.866666666666666696,0.533333333333333326],"xyz":[0.35778147348619227,0.563133212854312837,0.322775127270546969],"hpluv":[135.636001638862723,152.557764790666909,79.7918079202835173],"hsluv":[135.636001638862723,73.8730513922454435,79.7918079202835173]},"#66dd99":{"lch":[80.0870378401123162,66.8478260511747919,141.915708870878916],"luv":[80.0870378401123162,-52.6162023759431392,41.2330825345609924],"rgb":[0.4,0.866666666666666696,0.6],"xyz":[0.370838437595265,0.568355998497942,0.391541804911664904],"hpluv":[141.915708870878916,139.150468179242381,80.0870378401123162],"hsluv":[141.915708870878916,74.6453790933081791,80.0870378401123162]},"#66ddaa":{"lch":[80.4252690581998877,59.592891473004542,150.502508447871207],"luv":[80.4252690581998877,-51.8682972227800931,29.3426729750825572],"rgb":[0.4,0.866666666666666696,0.66666666666666663],"xyz":[0.385896130560517525,0.574379075684043117,0.470845654528663449],"hpluv":[150.502508447871207,126.571308780245914,80.4252690581998877],"hsluv":[150.502508447871207,75.4812281571350638,80.4252690581998877]},"#66ddbb":{"lch":[80.807354973374558,53.7174771102931672,161.973645166837599],"luv":[80.807354973374558,-51.0807157732000334,16.6231111165276104],"rgb":[0.4,0.866666666666666696,0.733333333333333282],"xyz":[0.4030337226678542,0.581234112526977875,0.561103639627305251],"hpluv":[161.973645166837599,116.757770235740637,80.807354973374558],"hsluv":[161.973645166837599,76.3679029554368753,80.807354973374558]},"#66ddcc":{"lch":[81.2339045655681389,50.3705316419042148,176.319314132685548],"luv":[81.2339045655681389,-50.2666331071559256,3.23358221770368903],"rgb":[0.4,0.866666666666666696,0.8],"xyz":[0.422326098111575954,0.588951062704466732,0.662710150297575407],"hpluv":[176.319314132685548,112.393665646206941,81.2339045655681389],"hsluv":[176.319314132685548,77.2923330418296501,81.2339045655681389]},"#66dddd":{"lch":[81.7052962965957903,50.5769089008318389,192.177050630061],"luv":[81.7052962965957903,-49.4389517336029,-10.6683534552210038],"rgb":[0.4,0.866666666666666696,0.866666666666666696],"xyz":[0.443844423662209442,0.597558392924720239,0.776039998197581404],"hpluv":[192.177050630061,116.242714563462513,81.7052962965957903],"hsluv":[192.177050630061,78.2416694753709407,81.7052962965957903]},"#66ddee":{"lch":[82.2216916522674524,54.6311568672274745,207.154140846621715],"luv":[82.2216916522674524,-48.6098170936026577,-24.9328895793911158],"rgb":[0.4,0.866666666666666696,0.933333333333333348],"xyz":[0.467656603928384207,0.607083265031190256,0.901450814266104627],"hpluv":[207.154140846621715,129.793318723999505,82.2216916522674524],"hsluv":[207.154140846621715,79.2037752530793,82.2216916522674524]},"#66ddff":{"lch":[82.7830488398693376,61.9519841783888339,219.519505956683815],"luv":[82.7830488398693376,-47.7902556034158366,-39.4225799891321387],"rgb":[0.4,0.866666666666666696,1],"xyz":[0.493827652338215572,0.617551684395123,1.03928500255788636],"hpluv":[219.519505956683815,152.730665075356086,82.7830488398693376],"hsluv":[219.519505956683815,99.9999999999957,82.7830488398693376]},"#115500":{"lch":[30.9160157060817227,46.0913193883500583,125.457330883646421],"luv":[30.9160157060817227,-26.7374134918097575,37.543580579466358],"rgb":[0.0666666666666666657,0.333333333333333315,0],"xyz":[0.0347951852141227744,0.0661590714665301755,0.0109362145699901016],"hpluv":[125.457330883646421,189.179880792461034,30.9160157060817227],"hsluv":[125.457330883646421,100.000000000002402,30.9160157060817227]},"#115511":{"lch":[31.0114762783458957,43.2230667766736616,127.715012949240275],"luv":[31.0114762783458957,-26.4410342208804181,34.1921805521528697],"rgb":[0.0666666666666666657,0.333333333333333315,0.0666666666666666657],"xyz":[0.0358068507137599,0.0665637376663850283,0.0162643195347457331],"hpluv":[127.715012949240275,176.861157643680144,31.0114762783458957],"hsluv":[127.715012949240275,90.0538522348087156,31.0114762783458957]},"#115522":{"lch":[31.1874163697014737,38.3803455570512071,132.492971129528541],"luv":[31.1874163697014737,-25.925914044022,28.3001396827055132],"rgb":[0.0666666666666666657,0.333333333333333315,0.133333333333333331],"xyz":[0.0376822088522369147,0.0673138809217758427,0.0261412057307249292],"hpluv":[132.492971129528541,156.159643444286843,31.1874163697014737],"hsluv":[132.492971129528541,90.4316047034468653,31.1874163697014737]},"#115533":{"lch":[31.4742731349983,31.7764378074468219,142.363318860140765],"luv":[31.4742731349983,-25.163724938647551,19.4043538140960301],"rgb":[0.0666666666666666657,0.333333333333333315,0.2],"xyz":[0.0407699595846946553,0.0685489812147589556,0.0424033595883360759],"hpluv":[142.363318860140765,128.111709873485438,31.4742731349983],"hsluv":[142.363318860140765,90.9947325890089616,31.4742731349983]},"#115544":{"lch":[31.8824114421380642,25.5202649789159608,161.635705606154772],"luv":[31.8824114421380642,-24.2205825435089714,8.04035483341083435],"rgb":[0.0666666666666666657,0.333333333333333315,0.266666666666666663],"xyz":[0.0452279548289135358,0.0703321793124465355,0.0658821345412227144],"hpluv":[161.635705606154772,101.571845607751229,31.8824114421380642],"hsluv":[161.635705606154772,91.6999843863076194,31.8824114421380642]},"#115555":{"lch":[32.417637609391285,23.7206023942150033,192.177050630061103],"luv":[32.417637609391285,-23.1868997601056,-5.00346454561771115],"rgb":[0.0666666666666666657,0.333333333333333315,0.333333333333333315],"xyz":[0.0511903688682755278,0.0727171449281913684,0.0972841818151966159],"hpluv":[192.177050630061103,92.8503782686988899,32.417637609391285],"hsluv":[192.177050630061103,92.4869346485079,32.417637609391285]},"#115566":{"lch":[33.0818646063754045,29.1355194477524577,220.509575549450261],"luv":[33.0818646063754045,-22.1516601517912761,-18.9257085999416219],"rgb":[0.0666666666666666657,0.333333333333333315,0.4],"xyz":[0.0587753646417837061,0.0757511432375946869,0.137231826222340592],"hpluv":[220.509575549450261,111.756325010930979,33.0818646063754045],"hsluv":[220.509575549450261,93.2955878193037904,33.0818646063754045]},"#115577":{"lch":[33.8736729304774826,39.2775515041961185,237.359341141202208],"luv":[33.8736729304774826,-21.1850732372535866,-33.0744421585153958],"rgb":[0.0666666666666666657,0.333333333333333315,0.466666666666666674],"xyz":[0.0680893776619856117,0.0794767484456755,0.186285628128738501],"hpluv":[237.359341141202208,147.13684637222039,33.8736729304774826],"hsluv":[237.359341141202208,94.078253732623736,33.8736729304774826]},"#115588":{"lch":[34.7888943497230514,51.2161985161337938,246.60972521059881],"luv":[34.7888943497230514,-20.3324266151093482,-47.0073549392562455],"rgb":[0.0666666666666666657,0.333333333333333315,0.533333333333333326],"xyz":[0.0792297947639294398,0.0839329152864531,0.244958491532310668],"hpluv":[246.60972521059881,186.812546427038342,34.7888943497230514],"hsluv":[246.60972521059881,94.8038015691112719,34.7888943497230514]},"#115599":{"lch":[35.8212274371681403,63.5782184467896,252.028930114170464],"luv":[35.8212274371681403,-19.6162163870228632,-60.476391389741444],"rgb":[0.0666666666666666657,0.333333333333333315,0.6],"xyz":[0.0922867588730021671,0.0891557009300822517,0.313725169173428575],"hpluv":[252.028930114170464,225.22013661091745,35.8212274371681403],"hsluv":[252.028930114170464,95.4562831747131355,35.8212274371681403]},"#1155aa":{"lch":[36.9628521043173777,75.808874965898184,255.452401876993463],"luv":[36.9628521043173777,-19.0419916394553752,-73.3783897206670588],"rgb":[0.0666666666666666657,0.333333333333333315,0.66666666666666663],"xyz":[0.107344451838254695,0.0951787781161833601,0.393029018790427176],"hpluv":[255.452401876993463,260.251896817562397,36.9628521043173777],"hsluv":[255.452401876993463,96.0310300088164155,36.9628521043173777]},"#1155bb":{"lch":[38.2050019251475845,87.6984258792502089,257.752076786877694],"luv":[38.2050019251475845,-18.6045414354547205,-85.7023041678273216],"rgb":[0.0666666666666666657,0.333333333333333315,0.733333333333333282],"xyz":[0.124482043945591342,0.102033814959118119,0.483287003889068922],"hpluv":[257.752076786877694,291.280156181798475,38.2050019251475845],"hsluv":[257.752076786877694,96.5305142623785,38.2050019251475845]},"#1155cc":{"lch":[39.5384610498345523,99.1886562531622,259.372402836059223],"luv":[39.5384610498345523,-18.292845239891637,-97.4872368176334447],"rgb":[0.0666666666666666657,0.333333333333333315,0.8],"xyz":[0.143774419389313096,0.10975076513660692,0.584893514559339],"hpluv":[259.372402836059223,318.332933912315752,39.5384610498345523],"hsluv":[259.372402836059223,96.9610449958707,39.5384610498345523]},"#1155dd":{"lch":[40.9539668975822053,110.288480556245688,260.557616930578945],"luv":[40.9539668975822053,-18.0934548393737415,-108.7941902648341],"rgb":[0.0666666666666666657,0.333333333333333315,0.866666666666666696],"xyz":[0.16529274493994664,0.118358095356860454,0.698223362459345],"hpluv":[260.557616930578945,341.722445031840948,40.9539668975822053],"hsluv":[260.557616930578945,97.330522563257,40.9539668975822053]},"#1155ee":{"lch":[42.4425141949683038,121.034132372772049,261.450904748640312],"luv":[42.4425141949683038,-17.992549051743687,-119.689303523123172],"rgb":[0.0666666666666666657,0.333333333333333315,0.933333333333333348],"xyz":[0.189104925206121377,0.127882967463330471,0.823634178527868244],"hpluv":[261.450904748640312,361.864588035447412,42.4425141949683038],"hsluv":[261.450904748640312,97.6470858685672596,42.4425141949683038]},"#1155ff":{"lch":[43.9955669218353762,131.469960671873054,262.140820458865903],"luv":[43.9955669218353762,-17.9770474653633769,-130.235081001594637],"rgb":[0.0666666666666666657,0.333333333333333315,1],"xyz":[0.21527597361595277,0.138351386827263168,0.961468366819650089],"hpluv":[262.140820458865903,379.190057269809415,43.9955669218353762],"hsluv":[262.140820458865903,99.9999999999993321,43.9955669218353762]},"#66ee00":{"lch":[83.9510288300903511,118.631054776009961,121.878900606421581],"luv":[83.9510288300903511,-62.6521043104729145,100.737485489455693],"rgb":[0.4,0.933333333333333348,0],"xyz":[0.360525640276900428,0.639716921715420939,0.104479109088397595],"hpluv":[121.878900606421581,316.932305812441825,83.9510288300903511],"hsluv":[121.878900606421581,100.000000000002245,83.9510288300903511]},"#66ee11":{"lch":[83.9720997528394406,117.779830021225337,122.096631719604488],"luv":[83.9720997528394406,-62.5821687959979371,99.7775551344988401],"rgb":[0.4,0.933333333333333348,0.0666666666666666657],"xyz":[0.361537305776537532,0.640121587915275847,0.109807214053153232],"hpluv":[122.096631719604488,315.12898496103287,83.9720997528394406],"hsluv":[122.096631719604488,98.9534187198870825,83.9720997528394406]},"#66ee22":{"lch":[84.0111361497279461,116.215639794016113,122.506307539641156],"luv":[84.0111361497279461,-62.4534076072217061,98.0084017366813498],"rgb":[0.4,0.933333333333333348,0.133333333333333331],"xyz":[0.363412663915014589,0.640871731170666648,0.119684100249132425],"hpluv":[122.506307539641156,311.807725961995743,84.0111361497279461],"hsluv":[122.506307539641156,97.0256918708191,84.0111361497279461]},"#66ee33":{"lch":[84.0753427139745213,113.679067087327056,123.198426402241765],"luv":[84.0753427139745213,-62.2438639038254564,95.1242960560921],"rgb":[0.4,0.933333333333333348,0.2],"xyz":[0.366500414647472295,0.642106831463649774,0.135946254106743575],"hpluv":[123.198426402241765,306.400922934277446,84.0753427139745213],"hsluv":[123.198426402241765,93.8862320250161133,84.0753427139745213]},"#66ee44":{"lch":[84.1678970009459704,110.10189342016568,124.237870325737177],"luv":[84.1678970009459704,-61.946619900698991,91.0222127702015626],"rgb":[0.4,0.933333333333333348,0.266666666666666663],"xyz":[0.37095840989169121,0.64389002956133734,0.159425029059630213],"hpluv":[124.237870325737177,298.731636810455427,84.1678970009459704],"hsluv":[124.237870325737177,89.4277949312148337,84.1678970009459704]},"#66ee55":{"lch":[84.2914184237995414,105.474359140243067,125.706632503417083],"luv":[84.2914184237995414,-61.5585501093914829,85.6468641835444657],"rgb":[0.4,0.933333333333333348,0.333333333333333315],"xyz":[0.376920823931053195,0.64627499517708209,0.190827076333604129],"hpluv":[125.706632503417083,288.732343582820249,84.2914184237995414],"hsluv":[125.706632503417083,83.5978964235977315,84.2914184237995414]},"#66ee66":{"lch":[84.4481159447294374,99.8471979874678652,127.715012949239849],"luv":[84.4481159447294374,-61.0799597466417339,78.9854509596370633],"rgb":[0.4,0.933333333333333348,0.4],"xyz":[0.38450581970456138,0.649308993486485408,0.230774720740748063],"hpluv":[127.715012949239849,276.453302697114395,84.4481159447294374],"hsluv":[127.715012949239849,76.3932656313124454,84.4481159447294374]},"#66ee77":{"lch":[84.6398667383604391,93.3381964812165,130.416076861551431],"luv":[84.6398667383604391,-60.5142850922984863,71.0636350191446127],"rgb":[0.4,0.933333333333333348,0.466666666666666674],"xyz":[0.393819832724763286,0.65303459869456626,0.279828522647145972],"hpluv":[130.416076861551431,262.087365127001192,84.6398667383604391],"hsluv":[130.416076861551431,76.8478121958162461,84.6398667383604391]},"#66ee88":{"lch":[84.8682629083727704,86.1443361377895513,134.024834696689027],"luv":[84.8682629083727704,-59.8677379892917187,61.9411058721588503],"rgb":[0.4,0.933333333333333348,0.533333333333333326],"xyz":[0.404960249826707086,0.657490765535343802,0.338501386050718167],"hpluv":[134.024834696689027,246.018013362770375,84.8682629083727704],"hsluv":[134.024834696689027,77.3690194462974858,84.8682629083727704]},"#66ee99":{"lch":[85.1346415661787432,78.5628931277068,138.840952739605655],"luv":[85.1346415661787432,-59.1488647733143296,51.7062856200641718],"rgb":[0.4,0.933333333333333348,0.6],"xyz":[0.418017213935779841,0.662713551178973,0.407268063691836046],"hpluv":[138.840952739605655,228.905884969324347,85.1346415661787432],"hsluv":[138.840952739605655,77.9507906120806,85.1346415661787432]},"#66eeaa":{"lch":[85.4401056772853451,71.025817565124143,145.263991147699045],"luv":[85.4401056772853451,-58.3680297483556387,40.4702342974360576],"rgb":[0.4,0.933333333333333348,0.66666666666666663],"xyz":[0.433074906901032342,0.668736628365074082,0.486571913308834647],"hpluv":[145.263991147699045,211.83630636980061,85.4401056772853451],"hsluv":[145.263991147699045,78.5856392083502868,85.4401056772853451]},"#66eebb":{"lch":[85.7855396574798448,64.1465768711300228,153.7611846199909],"luv":[85.7855396574798448,-57.5368534805651,28.3600743271201026],"rgb":[0.4,0.933333333333333348,0.733333333333333282],"xyz":[0.450212499008369,0.67559166520800884,0.576829898407476449],"hpluv":[153.7611846199909,196.542528595596508,85.7855396574798448],"hsluv":[153.7611846199909,79.2651091664321683,85.7855396574798448]},"#66eecc":{"lch":[86.1716220205593,58.7524914026155827,164.690737532459508],"luv":[86.1716220205593,-56.6676444389915517,15.5123602250092176],"rgb":[0.4,0.933333333333333348,0.8],"xyz":[0.46950487445209077,0.683308615385497697,0.678436409077746605],"hpluv":[164.690737532459508,185.645341664818176,86.1716220205593],"hsluv":[164.690737532459508,79.9801993176568118,86.1716220205593]},"#66eedd":{"lch":[86.5988364705929285,55.8111450312658164,177.877712634427581],"luv":[86.5988364705929285,-55.7728621696499403,2.06682246606168096],"rgb":[0.4,0.933333333333333348,0.866666666666666696],"xyz":[0.491023200002724258,0.691915945605751204,0.791766256977752603],"hpluv":[177.877712634427581,182.628088950326941,86.5988364705929285],"hsluv":[177.877712634427581,80.7217641095277543,86.5988364705929285]},"#66eeee":{"lch":[87.0674822997282263,56.1274864183573783,192.177050630061075],"luv":[87.0674822997282263,-54.8646438121880493,-11.8391549953798521],"rgb":[0.4,0.933333333333333348,0.933333333333333348],"xyz":[0.514835380268899,0.701440817712221221,0.917177073046275826],"hpluv":[192.177050630061075,191.066910285097691,87.0674822997282263],"hsluv":[192.177050630061075,81.4808670778618165,87.0674822997282263]},"#66eeff":{"lch":[87.5776846199412518,59.9248574237073512,205.793536431897621],"luv":[87.5776846199412518,-53.9544158989052178,-26.0750751151289606],"rgb":[0.4,0.933333333333333348,1],"xyz":[0.541006428678730389,0.711909237076154,1.05501126133805756],"hpluv":[205.793536431897621,213.276590696447101,87.5776846199412518],"hsluv":[205.793536431897621,99.9999999999933351,87.5776846199412518]},"#116600":{"lch":[37.1543973335168118,56.0416844920186463,126.180156646926719],"luv":[37.1543973335168118,-33.0828721903909511,45.2348755755691201],"rgb":[0.0666666666666666657,0.4,0],"xyz":[0.0498232429199692434,0.0962151868782235159,0.0159455671386054508],"hpluv":[126.180156646926719,191.399273993181851,37.1543973335168118],"hsluv":[126.180156646926719,100.000000000002359,37.1543973335168118]},"#116611":{"lch":[37.2288128297302237,53.6508389550451668,127.715012949240304],"luv":[37.2288128297302237,-32.820060550512963,42.4412081124095124],"rgb":[0.0666666666666666657,0.4,0.0666666666666666657],"xyz":[0.0508349084196063616,0.0966198530780783688,0.021273672103361084],"hpluv":[127.715012949240304,182.867554307566394,37.2288128297302237],"hsluv":[127.715012949240304,93.1121786917857719,37.2288128297302237]},"#116622":{"lch":[37.366211587350719,49.4912288674311,130.823584918521846],"luv":[37.366211587350719,-32.3540076461773722,37.4513006989015125],"rgb":[0.0666666666666666657,0.4,0.133333333333333331],"xyz":[0.0527102665580833837,0.0973699963334691831,0.0311505582993402766],"hpluv":[130.823584918521846,168.069340269208539,37.366211587350719],"hsluv":[130.823584918521846,93.2954788878505639,37.366211587350719]},"#116633":{"lch":[37.5909073580641291,43.4152735453156,136.786924005406348],"luv":[37.5909073580641291,-31.6415889136076061,29.7270218494359924],"rgb":[0.0666666666666666657,0.4,0.2],"xyz":[0.0557980172905411242,0.0986050966264523,0.0474127121569514198],"hpluv":[136.786924005406348,146.554466726503705,37.5909073580641291],"hsluv":[136.786924005406348,93.5769168130898095,37.5909073580641291]},"#116644":{"lch":[37.9120295698984506,36.3990668435195417,147.559563985674146],"luv":[37.9120295698984506,-30.7189764474867033,19.525279846848818],"rgb":[0.0666666666666666657,0.4,0.266666666666666663],"xyz":[0.0602560125347600048,0.100388294724139876,0.0708914871098380583],"hpluv":[147.559563985674146,121.829522477327146,37.9120295698984506],"hsluv":[147.559563985674146,93.9439470857740559,37.9120295698984506]},"#116655":{"lch":[38.335629212958338,30.5483862618043851,166.063087397862887],"luv":[38.335629212958338,-29.6490880228798659,7.35768187759708869],"rgb":[0.0666666666666666657,0.4,0.333333333333333315],"xyz":[0.066218426574122,0.102773260339884709,0.102293534383811974],"hpluv":[166.063087397862887,101.117192726530064,38.335629212958338],"hsluv":[166.063087397862887,94.3739252192313529,38.335629212958338]},"#116666":{"lch":[38.8651381017916293,29.1618890828208741,192.177050630061217],"luv":[38.8651381017916293,-28.5057600031098204,-6.15121301239451324],"rgb":[0.0666666666666666657,0.4,0.4],"xyz":[0.0738034223476301682,0.105807258649288027,0.142241178790955936],"hpluv":[192.177050630061217,95.2126746116157392,38.8651381017916293],"hsluv":[192.177050630061217,94.8399842705083245,38.8651381017916293]},"#116677":{"lch":[39.5016809883423079,34.1234106492309124,216.700227589977857],"luv":[39.5016809883423079,-27.3592385518708738,-20.3931169809293316],"rgb":[0.0666666666666666657,0.4,0.466666666666666674],"xyz":[0.0831174353678320876,0.109532863857368837,0.191294980697353845],"hpluv":[216.700227589977857,109.616563248578402,39.5016809883423079],"hsluv":[216.700227589977857,95.3164106037614687,39.5016809883423079]},"#116688":{"lch":[40.2443638992953723,43.6497103352843823,233.004065811630028],"luv":[40.2443638992953723,-26.2665776267255495,-34.862072688430807],"rgb":[0.0666666666666666657,0.4,0.533333333333333326],"xyz":[0.0942578524697759157,0.113989030698146435,0.249967844100926],"hpluv":[233.004065811630028,137.630797119362086,40.2443638992953723],"hsluv":[233.004065811630028,95.7822055324918864,40.2443638992953723]},"#116699":{"lch":[41.090575936542443,55.3002439505846866,242.81143298809],"luv":[41.090575936542443,-25.2678118474637223,-49.189985418125],"rgb":[0.0666666666666666657,0.4,0.6],"xyz":[0.107314816578848629,0.119211816341775592,0.318734521742043919],"hpluv":[242.81143298809,170.774941475023041,41.090575936542443],"hsluv":[242.81143298809,96.2225162944548202,41.090575936542443]},"#1166aa":{"lch":[42.0363074660961757,67.6887016451143,248.882871092507173],"luv":[42.0363074660961757,-24.3865946332867658,-63.1431257746482615],"rgb":[0.0666666666666666657,0.4,0.66666666666666663],"xyz":[0.122372509544101171,0.125234893527876701,0.39803837135904252],"hpluv":[248.882871092507173,204.329442679703192,42.0363074660961757],"hsluv":[248.882871092507173,96.6284204735347885,42.0363074660961757]},"#1166bb":{"lch":[43.0764730814379746,80.16050208662584,252.853006907061769],"luv":[43.0764730814379746,-23.6332520973097289,-76.5974901030376429],"rgb":[0.0666666666666666657,0.4,0.733333333333333282],"xyz":[0.139510101651437818,0.132089930370811459,0.488296356457684266],"hpluv":[252.853006907061769,236.134594524550181,43.0764730814379746],"hsluv":[252.853006907061769,96.9958197331145,43.0764730814379746]},"#1166cc":{"lch":[44.2052232400861271,92.4179309088515737,255.583916344807051],"luv":[44.2052232400861271,-23.008531750755072,-89.5079964033815259],"rgb":[0.0666666666666666657,0.4,0.8],"xyz":[0.158802477095159544,0.139806880548300261,0.589902867127954367],"hpluv":[255.583916344807051,265.290671800528912,44.2052232400861271],"hsluv":[255.583916344807051,97.3240770235992159,44.2052232400861271]},"#1166dd":{"lch":[45.4162296513266455,104.336857924373376,257.542523527564185],"luv":[45.4162296513266455,-22.507022318245486,-101.880390006599782],"rgb":[0.0666666666666666657,0.4,0.866666666666666696],"xyz":[0.180320802645793088,0.148414210768553795,0.703232715027960364],"hpluv":[257.542523527564185,291.518421142394175,45.4162296513266455],"hsluv":[257.542523527564185,97.6147741074162,45.4162296513266455]},"#1166ee":{"lch":[46.7029335650228674,115.880201424536907,258.995545526323895],"luv":[46.7029335650228674,-22.1198283610194721,-113.74943637429719],"rgb":[0.0666666666666666657,0.4,0.933333333333333348],"xyz":[0.204132982911967853,0.157939082875023812,0.828643531096483588],"hpluv":[258.995545526323895,314.850514307077333,46.7029335650228674],"hsluv":[258.995545526323895,97.870742288996567,46.7029335650228674]},"#1166ff":{"lch":[48.0587511138394348,127.054293237547355,260.103604495506659],"luv":[48.0587511138394348,-21.8364562757409573,-125.163743182322264],"rgb":[0.0666666666666666657,0.4,1],"xyz":[0.230304031321799219,0.168407502238956508,0.966477719388265433],"hpluv":[260.103604495506659,335.471932494038299,48.0587511138394348],"hsluv":[260.103604495506659,99.9999999999992184,48.0587511138394348]},"#66ff00":{"lch":[89.0839511722278417,127.467952451328657,122.755484474710229],"luv":[89.0839511722278417,-68.9671698198214074,107.198919720201],"rgb":[0.4,1,0],"xyz":[0.41237801270657426,0.74342166657477,0.121763233231621706],"hpluv":[122.755484474710229,522.717702913530729,89.0839511722278417],"hsluv":[122.755484474710229,100.000000000002402,89.0839511722278417]},"#66ff11":{"lch":[89.1030144718140917,126.693355761899767,122.944319876693868],"luv":[89.1030144718140917,-68.8988566751164342,106.320994836735167],"rgb":[0.4,1,0.0666666666666666657],"xyz":[0.413389678206211364,0.743826332774625,0.127091338196377329],"hpluv":[122.944319876693868,520.53129302948,89.1030144718140917],"hsluv":[122.944319876693868,99.9999999999913456,89.1030144718140917]},"#66ff22":{"lch":[89.1383344673707825,125.268361506965746,123.29878008449495],"luv":[89.1383344673707825,-68.7729595958538482,104.70168300016438],"rgb":[0.4,1,0.133333333333333331],"xyz":[0.415265036344688421,0.744576476030015755,0.136968224392356536],"hpluv":[123.29878008449495,516.49933125362179,89.1383344673707825],"hsluv":[123.29878008449495,99.9999999999914877,89.1383344673707825]},"#66ff33":{"lch":[89.1964366933732,122.952924407393425,123.895139690212403],"luv":[89.1964366933732,-68.5677350303770368,102.0582546055644],"rgb":[0.4,1,0.2],"xyz":[0.418352787077146127,0.745811576322998881,0.153230378249967686],"hpluv":[123.895139690212403,509.920932540516333,89.1964366933732],"hsluv":[123.895139690212403,99.9999999999913456,89.1964366933732]},"#66ff44":{"lch":[89.2802097655713,119.677402261160566,124.785058224819977],"luv":[89.2802097655713,-68.2758869475835439,98.2908127624369143],"rgb":[0.4,1,0.266666666666666663],"xyz":[0.422810782321365042,0.747594774420686448,0.176709153202854324],"hpluv":[124.785058224819977,500.557479589511445,89.2802097655713],"hsluv":[124.785058224819977,99.9999999999914451,89.2802097655713]},"#66ff55":{"lch":[89.392045372062455,115.420778437487911,126.031255758612545],"luv":[89.392045372062455,-67.8935601171189802,93.3403481337991536],"rgb":[0.4,1,0.333333333333333315],"xyz":[0.428773196360727,0.749979740036431197,0.20811120047682824],"hpluv":[126.031255758612545,488.288652672415253,89.392045372062455],"hsluv":[126.031255758612545,99.9999999999912177,89.392045372062455]},"#66ff66":{"lch":[89.5339732348528088,110.211236984550467,127.715012949239977],"luv":[89.5339732348528088,-67.4199983006921428,87.1840615410833664],"rgb":[0.4,1,0.4],"xyz":[0.436358192134235212,0.753013738345834516,0.248058844883972174],"hpluv":[127.715012949239977,473.1190638884799,89.5339732348528088],"hsluv":[127.715012949239977,99.9999999999912177,89.5339732348528088]},"#66ff77":{"lch":[89.7077333531255,104.130085615398272,129.945267186452298],"luv":[89.7077333531255,-66.8572982376138754,79.8321764869086223],"rgb":[0.4,1,0.466666666666666674],"xyz":[0.445672205154437118,0.756739343553915367,0.297112646790370083],"hpluv":[129.945267186452298,455.203211628206077,89.7077333531255],"hsluv":[129.945267186452298,99.9999999999911466,89.7077333531255]},"#66ff88":{"lch":[89.9148190538961529,97.3190386909276413,132.870301628739924],"luv":[89.9148190538961529,-66.2101394375234378,71.3246992800528687],"rgb":[0.4,1,0.533333333333333326],"xyz":[0.456812622256380918,0.761195510394692909,0.355785510193942278],"hpluv":[132.870301628739924,434.894743355908361,89.9148190538961529],"hsluv":[132.870301628739924,99.999999999990834,89.9148190538961529]},"#66ff99":{"lch":[90.1565046807361,89.9924560427222247,136.692010716646195],"luv":[90.1565046807361,-65.4854512845448795,61.7276098246221707],"rgb":[0.4,1,0.6],"xyz":[0.469869586365453618,0.766418296038322122,0.424552187835060157],"hpluv":[136.692010716646195,412.835114866532763,90.1565046807361],"hsluv":[136.692010716646195,99.9999999999909903,90.1565046807361]},"#66ffaa":{"lch":[90.4338646074596113,82.4570841698328678,141.679424663280656],"luv":[90.4338646074596113,-64.6920148236146,51.1284064669742264],"rgb":[0.4,1,0.66666666666666663],"xyz":[0.484927279330706174,0.772441373224423189,0.503856037452058758],"hpluv":[141.679424663280656,390.10709074414774,90.4338646074596113],"hsluv":[141.679424663280656,99.9999999999905924,90.4338646074596113]},"#66ffbb":{"lch":[90.747787175062669,75.1410408914244101,148.168460326052468],"luv":[90.747787175062669,-63.84001546278364,39.631155067172358],"rgb":[0.4,1,0.733333333333333282],"xyz":[0.502064871438042792,0.779296410067358,0.59411402255070056],"hpluv":[148.168460326052468,368.486167720556807,90.747787175062669],"hsluv":[148.168460326052468,99.9999999999904077,90.747787175062669]},"#66ffcc":{"lch":[91.0989856399247486,68.6265957122477,156.512275503644645],"luv":[91.0989856399247486,-62.9405723747737085,27.3513068826366492],"rgb":[0.4,1,0.8],"xyz":[0.521357246881764547,0.787013360244846805,0.695720533220970716],"hpluv":[156.512275503644645,350.804850059399143,91.0989856399247486],"hsluv":[156.512275503644645,99.9999999999903508,91.0989856399247486]},"#66ffdd":{"lch":[91.4880074096490716,63.6578272942329875,166.916209854529029],"luv":[91.4880074096490716,-62.0052733715472826,14.410588119229697],"rgb":[0.4,1,0.866666666666666696],"xyz":[0.542875572432398146,0.795620690465100311,0.809050381120976714],"hpluv":[166.916209854529029,341.336295176875581,91.4880074096490716],"hsluv":[166.916209854529029,99.9999999999898819,91.4880074096490716]},"#66ffee":{"lch":[91.9152423718395113,61.0528599966611765,179.125088100836763],"luv":[91.9152423718395113,-61.045742111776633,0.93224663816584552],"rgb":[0.4,1,0.933333333333333348],"xyz":[0.566687752698572855,0.805145562571570328,0.934461197189499937],"hpluv":[179.125088100836763,345.840646438583576,91.9152423718395113],"hsluv":[179.125088100836763,99.9999999999894,91.9152423718395113]},"#66ffff":{"lch":[92.3809308294128,61.4559907165056,192.17705063006116],"luv":[92.3809308294128,-60.0732592166006256,-12.9631139022354667],"rgb":[0.4,1,1],"xyz":[0.592858801108404276,0.815613981935503,1.07229538548128178],"hpluv":[192.17705063006116,370.76546272919029,92.3809308294128],"hsluv":[192.17705063006116,99.9999999999889866,92.3809308294128]},"#117700":{"lch":[43.2300348418233042,65.6725964696673685,126.613348243544976],"luv":[43.2300348418233042,-39.1679175007181684,52.7139845365981],"rgb":[0.0666666666666666657,0.466666666666666674,0],"xyz":[0.0682769809733868721,0.133122662985059287,0.0220968131564111547],"hpluv":[126.613348243544976,192.769325646383436,43.2300348418233042],"hsluv":[126.613348243544976,100.000000000002359,43.2300348418233042]},"#117711":{"lch":[43.289989941732955,63.6505577690815443,127.715012949240403],"luv":[43.289989941732955,-38.9372319378938414,50.351618378457772],"rgb":[0.0666666666666666657,0.466666666666666674,0.0666666666666666657],"xyz":[0.0692886464730239904,0.13352732918491414,0.0274249181211667845],"hpluv":[127.715012949240403,186.57525992916959,43.289989941732955],"hsluv":[127.715012949240403,95.0000616991484321,43.289989941732955]},"#117722":{"lch":[43.400811094951429,60.069144786817489,129.889765673233825],"luv":[43.400811094951429,-38.5230987158151308,46.089836414888758],"rgb":[0.0666666666666666657,0.466666666666666674,0.133333333333333331],"xyz":[0.0711640046115010194,0.134277472440304968,0.037301804317145984],"hpluv":[129.889765673233825,175.627665872500842,43.400811094951429],"hsluv":[129.889765673233825,95.0973605906006725,43.400811094951429]},"#117733":{"lch":[43.5823807888255317,54.6433249694405205,133.881596062605809],"luv":[43.5823807888255317,-37.8771324094584756,39.3854770715327476],"rgb":[0.0666666666666666657,0.466666666666666674,0.2],"xyz":[0.074251755343958753,0.135512572733288067,0.0535639581747571272],"hpluv":[133.881596062605809,159.098283206795713,43.5823807888255317],"hsluv":[133.881596062605809,95.249567515942033,43.5823807888255317]},"#117744":{"lch":[43.8425891980029,47.8554364611196803,140.669149905405504],"luv":[43.8425891980029,-37.0161352468332083,30.3306533110056051],"rgb":[0.0666666666666666657,0.466666666666666674,0.266666666666666663],"xyz":[0.0787097505881776266,0.137295770830975661,0.0770427331276437588],"hpluv":[140.669149905405504,138.507858249946878,43.8425891980029],"hsluv":[140.669149905405504,95.4533619015585373,43.8425891980029]},"#117755":{"lch":[44.18711059062651,40.7988283335817243,151.872601466806259],"luv":[44.18711059062651,-35.9805491223838843,19.2339407882209947],"rgb":[0.0666666666666666657,0.466666666666666674,0.333333333333333315],"xyz":[0.0846721646275396256,0.139680736446720494,0.108444780401617674],"hpluv":[151.872601466806259,117.163251003272293,44.18711059062651],"hsluv":[151.872601466806259,95.7000805167539426,44.18711059062651]},"#117766":{"lch":[44.6197667240920879,35.4343089397309186,169.362936023125116],"luv":[44.6197667240920879,-34.8254110013137463,6.54071850990925796],"rgb":[0.0666666666666666657,0.466666666666666674,0.4],"xyz":[0.0922571604010478,0.142714734756123784,0.148392424808761636],"hpluv":[169.362936023125116,100.771099800457392,44.6197667240920879],"hsluv":[169.362936023125116,95.9777414193434453,44.6197667240920879]},"#117777":{"lch":[45.1427402486772138,34.384087641882445,192.177050630061217],"luv":[45.1427402486772138,-33.6104614986274584,-7.25274850066749],"rgb":[0.0666666666666666657,0.466666666666666674,0.466666666666666674],"xyz":[0.101571173421249716,0.146440339964204608,0.197446226715159545],"hpluv":[192.177050630061217,96.651570122263351,45.1427402486772138],"hsluv":[192.177050630061217,96.2732475219964385,45.1427402486772138]},"#117788":{"lch":[45.7567431438856502,38.9735922704815891,213.78628123605418],"luv":[45.7567431438856502,-32.3916401681270685,-21.6730833451154119],"rgb":[0.0666666666666666657,0.466666666666666674,0.533333333333333326],"xyz":[0.112711590523193544,0.150896506804982206,0.256119090118731685],"hpluv":[213.78628123605418,108.082320192335175,45.7567431438856502],"hsluv":[213.78628123605418,96.5742797371803192,45.7567431438856502]},"#117799":{"lch":[46.4611794427891169,47.8902134896154763,229.321579893426758],"luv":[46.4611794427891169,-31.2154548044213769,-36.3189747850083791],"rgb":[0.0666666666666666657,0.466666666666666674,0.6],"xyz":[0.125768554632266272,0.156119292448611363,0.32488576775984962],"hpluv":[229.321579893426758,130.796423620493698,46.4611794427891169],"hsluv":[229.321579893426758,96.8705519561321,46.4611794427891169]},"#1177aa":{"lch":[47.254315604307827,59.1280670765604199,239.379878554404911],"luv":[47.254315604307827,-30.1165063567495856,-50.8834389666627231],"rgb":[0.0666666666666666657,0.466666666666666674,0.66666666666666663],"xyz":[0.1408262475975188,0.162142369634712458,0.40418961737684822],"hpluv":[239.379878554404911,158.77844008322549,47.254315604307827],"hsluv":[239.379878554404911,97.1543662497403488,47.254315604307827]},"#1177bb":{"lch":[48.1334597651774914,71.3648635001192133,245.920143546346225],"luv":[48.1334597651774914,-29.1175429122131746,-65.1545273725937761],"rgb":[0.0666666666666666657,0.466666666666666674,0.733333333333333282],"xyz":[0.157963839704855447,0.168997406477647216,0.494447602475489967],"hpluv":[245.920143546346225,188.138070935962588,48.1334597651774914],"hsluv":[245.920143546346225,97.4206074841270464,48.1334597651774914]},"#1177cc":{"lch":[49.0951452720171488,83.8954152066927463,250.336037436893122],"luv":[49.0951452720171488,-28.2310616920000612,-79.0028344329863756],"rgb":[0.0666666666666666657,0.466666666666666674,0.8],"xyz":[0.177256215148577201,0.176714356655136018,0.596054113145760178],"hpluv":[250.336037436893122,216.83980339157776,49.0951452720171488],"hsluv":[250.336037436893122,97.666394869173061,49.0951452720171488]},"#1177dd":{"lch":[50.1353116048344702,96.3594544857749,253.441700788778064],"luv":[50.1353116048344702,-27.4615589113116805,-92.3634519220491512],"rgb":[0.0666666666666666657,0.466666666666666674,0.866666666666666696],"xyz":[0.198774540699210744,0.185321686875389552,0.709383961045766176],"hpluv":[253.441700788778064,243.887723915279508,50.1353116048344702],"hsluv":[253.441700788778064,97.8905898818146341,50.1353116048344702]},"#1177ee":{"lch":[51.2494756916451593,108.579054392530807,255.706052301270915],"luv":[51.2494756916451593,-26.8078049752198453,-105.217644172385562],"rgb":[0.0666666666666666657,0.466666666666666674,0.933333333333333348],"xyz":[0.222586720965385454,0.194846558981859597,0.834794777114289399],"hpluv":[255.706052301270915,268.841280267375566,51.2494756916451593],"hsluv":[255.706052301270915,98.0932983984315,51.2494756916451593]},"#1177ff":{"lch":[52.4328877873246739,120.474912105814852,257.407785454377859],"luv":[52.4328877873246739,-26.2648114927385947,-117.577056112809359],"rgb":[0.0666666666666666657,0.466666666666666674,1],"xyz":[0.248757769375216875,0.205314978345792293,0.972628965406071133],"hpluv":[257.407785454377859,291.562836812545811,52.4328877873246739],"hsluv":[257.407785454377859,99.9999999999990905,52.4328877873246739]},"#118800":{"lch":[49.1629818744817157,75.0325981068150725,126.891404302910644],"luv":[49.1629818744817157,-45.0420871994947447,60.0091756264985],"rgb":[0.0666666666666666657,0.533333333333333326,0],"xyz":[0.0903493506983573252,0.177267402435000831,0.0294542697314011],"hpluv":[126.891404302910644,193.664979881129256,49.1629818744817157],"hsluv":[126.891404302910644,100.000000000002487,49.1629818744817157]},"#118811":{"lch":[49.2125288978643,73.2988946552939211,127.715012949240403],"luv":[49.2125288978643,-44.8394509336223663,57.9840633075946883],"rgb":[0.0666666666666666657,0.533333333333333326,0.0666666666666666657],"xyz":[0.0913610161979944435,0.177672068634855684,0.0347823746961567343],"hpluv":[127.715012949240403,188.999680167490567,49.2125288978643],"hsluv":[127.715012949240403,96.2345237189928326,49.2125288978643]},"#118822":{"lch":[49.3041772439320312,70.1927728141533,129.31476933948187],"luv":[49.3041772439320312,-44.4727599639014315,54.3065279366352556],"rgb":[0.0666666666666666657,0.533333333333333326,0.133333333333333331],"xyz":[0.0932363743364714725,0.178422211890246513,0.0446592608921359269],"hpluv":[129.31476933948187,180.6541776618526,49.3041772439320312],"hsluv":[129.31476933948187,96.2899748067816859,49.3041772439320312]},"#118833":{"lch":[49.454516912369769,65.3819990709954766,132.170105234646456],"luv":[49.454516912369769,-43.8931572746598917,48.4581938064309767],"rgb":[0.0666666666666666657,0.533333333333333326,0.2],"xyz":[0.0963241250689292,0.179657312183229612,0.060921414749747077],"hpluv":[132.170105234646456,167.761213036429979,49.454516912369769],"hsluv":[132.170105234646456,96.3778002926358,49.454516912369769]},"#118844":{"lch":[49.6703617695526,59.1036258375550787,136.829676092870073],"luv":[49.6703617695526,-43.1056388924535057,40.4368950689726887],"rgb":[0.0666666666666666657,0.533333333333333326,0.266666666666666663],"xyz":[0.10078212031314808,0.181440510280917205,0.0844001897026337156],"hpluv":[136.829676092870073,150.9927614306973,49.6703617695526],"hsluv":[136.829676092870073,96.4975069627829356,49.6703617695526]},"#118855":{"lch":[49.9568473676091145,51.9652717779864091,144.176427678513875],"luv":[49.9568473676091145,-42.1346422468413806,30.4148219408018328],"rgb":[0.0666666666666666657,0.533333333333333326,0.333333333333333315],"xyz":[0.106744534352510079,0.183825475896662038,0.115802236976607617],"hpluv":[144.176427678513875,131.995007799011802,49.9568473676091145],"hsluv":[144.176427678513875,96.6457662191899658,49.9568473676091145]},"#118866":{"lch":[50.3177367885428879,45.0776565581224133,155.49998607369966],"luv":[50.3177367885428879,-41.0189171061503615,18.6934095394821433],"rgb":[0.0666666666666666657,0.533333333333333326,0.4],"xyz":[0.11432953012601825,0.186859474206065329,0.155749881383751593],"hpluv":[155.49998607369966,113.67882025976219,50.3177367885428879],"hsluv":[155.49998607369966,96.8171590628882512,50.3177367885428879]},"#118877":{"lch":[50.7555873970602391,40.2042284802375036,171.921706717236162],"luv":[50.7555873970602391,-39.8052806191025255,5.64974535051283322],"rgb":[0.0666666666666666657,0.533333333333333326,0.466666666666666674],"xyz":[0.12364354314622017,0.190585079414146152,0.204803683290149502],"hpluv":[171.921706717236162,100.514149141729121,50.7555873970602391],"hsluv":[171.921706717236162,97.0050762990714333,50.7555873970602391]},"#118888":{"lch":[51.2718664023781088,39.4294820301430349,192.17705063006116],"luv":[51.2718664023781088,-38.5423368357954814,-8.3169901046866368],"rgb":[0.0666666666666666657,0.533333333333333326,0.533333333333333326],"xyz":[0.134783960248164,0.19504124625492375,0.263476546693721669],"hpluv":[192.17705063006116,97.5845966821491118,51.2718664023781088],"hsluv":[192.17705063006116,97.2026219422035,51.2718664023781088]},"#118899":{"lch":[51.8670503792929907,43.7110075029310678,211.486174513119295],"luv":[51.8670503792929907,-37.2752705782940623,-22.8299448145688864],"rgb":[0.0666666666666666657,0.533333333333333326,0.6],"xyz":[0.147840924357236725,0.200264031898552908,0.332243224334839549],"hpluv":[211.486174513119295,106.93960912970239,51.8670503792929907],"hsluv":[211.486174513119295,97.4033619208845,51.8670503792929907]},"#1188aa":{"lch":[52.5407237145479371,52.059033028958666,226.184651315961702],"luv":[52.5407237145479371,-36.0423686073764102,-37.5644856890150507],"rgb":[0.0666666666666666657,0.533333333333333326,0.66666666666666663],"xyz":[0.162898617322489253,0.206287109084654,0.411547073951838149],"hpluv":[226.184651315961702,125.730132415512543,52.5407237145479371],"hsluv":[226.184651315961702,97.6018250350267,52.5407237145479371]},"#1188bb":{"lch":[53.2916815113449047,62.8295543710454396,236.286042109927791],"luv":[53.2916815113449047,-34.8733609598062557,-52.2628127623381573],"rgb":[0.0666666666666666657,0.533333333333333326,0.733333333333333282],"xyz":[0.1800362094298259,0.213142145927588761,0.501805059050479896],"hpluv":[236.286042109927791,149.604233097343041,53.2916815113449047],"hsluv":[236.286042109927791,97.7937430875757201,53.2916815113449047]},"#1188cc":{"lch":[54.1180375597057548,74.8024459991104607,243.146336149822275],"luv":[54.1180375597057548,-33.7892633498457826,-66.735984369188742],"rgb":[0.0666666666666666657,0.533333333333333326,0.8],"xyz":[0.199328584873547654,0.220859096105077563,0.60341156972075],"hpluv":[243.146336149822275,175.393335022858878,54.1180375597057548],"hsluv":[243.146336149822275,97.9760759990174819,54.1180375597057548]},"#1188dd":{"lch":[55.0173353812408266,87.2581949437380331,247.918019831454984],"luv":[55.0173353812408266,-32.8032215872693484,-80.8575366823396138],"rgb":[0.0666666666666666657,0.533333333333333326,0.866666666666666696],"xyz":[0.220846910424181198,0.229466426325331097,0.716741417620756],"hpluv":[247.918019831454984,201.254684785248685,55.0173353812408266],"hsluv":[247.918019831454984,98.1468934162311513,55.0173353812408266]},"#1188ee":{"lch":[55.9866591638471363,99.7959623087877645,251.344854654704591],"luv":[55.9866591638471363,-31.921869990719685,-94.5527805483930734],"rgb":[0.0666666666666666657,0.533333333333333326,0.933333333333333348],"xyz":[0.244659090690355907,0.238991298431801141,0.842152233689279273],"hpluv":[251.344854654704591,226.187053837960264,55.9866591638471363],"hsluv":[251.344854654704591,98.3051827042817,55.9866591638471363]},"#1188ff":{"lch":[57.0227411270994082,112.196885547184024,253.882464988485651],"luv":[57.0227411270994082,-31.1468293758358783,-107.786901552649141],"rgb":[0.0666666666666666657,0.533333333333333326,1],"xyz":[0.270830139100187328,0.249459717795733837,0.979986421981061118],"hpluv":[253.882464988485651,249.673263359937977,57.0227411270994082],"hsluv":[253.882464988485651,99.9999999999988916,57.0227411270994082]},"#119900":{"lch":[54.9698669410824721,84.160615619067471,127.079428544988929],"luv":[54.9698669410824721,-50.7422517332937772,67.1433772639973],"rgb":[0.0666666666666666657,0.6,0],"xyz":[0.116218951150824812,0.229006603339936526,0.0380774698822233526],"hpluv":[127.079428544988929,194.277964405092661,54.9698669410824721],"hsluv":[127.079428544988929,100.000000000002373,54.9698669410824721]},"#119911":{"lch":[55.0116447857556494,82.6558224500047,127.715012949240403],"luv":[55.0116447857556494,-50.563404981135136,65.3859852078442],"rgb":[0.0666666666666666657,0.6,0.0666666666666666657],"xyz":[0.11723061665046193,0.229411269539791379,0.0434055748469789823],"hpluv":[127.715012949240403,190.659367551848248,55.0116447857556494],"hsluv":[127.715012949240403,97.0796004133795094,55.0116447857556494]},"#119922":{"lch":[55.0889600096002852,79.9388272851777657,128.936266554168185],"luv":[55.0889600096002852,-50.237998627918941,62.1800579091938204],"rgb":[0.0666666666666666657,0.6,0.133333333333333331],"xyz":[0.119105974788938959,0.230161412795182208,0.0532824610429581819],"hpluv":[128.936266554168185,184.133380166819137,55.0889600096002852],"hsluv":[128.936266554168185,97.113065541928691,55.0889600096002852]},"#119933":{"lch":[55.215893256771821,75.6695179958245916,131.075562701176153],"luv":[55.215893256771821,-49.7189430335536,57.0429895547794175],"rgb":[0.0666666666666666657,0.6,0.2],"xyz":[0.122193725521396693,0.231396513088165307,0.0695446149005693182],"hpluv":[131.075562701176153,173.898642472918851,55.215893256771821],"hsluv":[131.075562701176153,97.1665253707361,55.215893256771821]},"#119944":{"lch":[55.398361036949,69.9528706873860671,134.469703140623466],"luv":[55.398361036949,-49.0042253731102591,49.9198358669935303],"rgb":[0.0666666666666666657,0.6,0.266666666666666663],"xyz":[0.126651720765615566,0.2331797111858529,0.0930233898534559567],"hpluv":[134.469703140623466,160.231519707698453,55.398361036949],"hsluv":[134.469703140623466,97.2403070889690184,55.398361036949]},"#119955":{"lch":[55.6409569880907497,63.1400511875114887,139.633471194580181],"luv":[55.6409569880907497,-48.1074656204671172,40.8942271664002206],"rgb":[0.0666666666666666657,0.6,0.333333333333333315],"xyz":[0.132614134804977579,0.235564676801597733,0.124425437127429872],"hpluv":[139.633471194580181,143.995747016857166,55.6409569880907497],"hsluv":[139.633471194580181,97.3331834328701575,55.6409569880907497]},"#119966":{"lch":[55.9472168173363,55.8918514512489466,147.340496807064056],"luv":[55.9472168173363,-47.0549257965888,30.1617807320125095],"rgb":[0.0666666666666666657,0.6,0.4],"xyz":[0.140199130578485737,0.238598675111001024,0.164373081534573834],"hpluv":[147.340496807064056,126.76791164907155,55.9472168173363],"hsluv":[147.340496807064056,97.4426708460479,55.9472168173363]},"#119977":{"lch":[56.319758368673476,49.2851425936320169,158.582299284916047],"luv":[56.319758368673476,-45.8816608646539308,17.9971796894826],"rgb":[0.0666666666666666657,0.6,0.466666666666666674],"xyz":[0.14951314359868767,0.242324280319081847,0.213426883440971743],"hpluv":[158.582299284916047,111.043862853999471,56.319758368673476],"hsluv":[158.582299284916047,97.5654087237770398,56.319758368673476]},"#119988":{"lch":[56.7603710001512951,44.8759084930006864,173.96527373508107],"luv":[56.7603710001512951,-44.6272223318454451,4.71785862613608131],"rgb":[0.0666666666666666657,0.6,0.533333333333333326],"xyz":[0.16065356070063147,0.246780447159859445,0.27209974684454391],"hpluv":[173.96527373508107,100.324581054675164,56.7603710001512951],"hsluv":[173.96527373508107,97.6975811674153647,56.7603710001512951]},"#119999":{"lch":[57.2700846473106822,44.3289506401906692,192.177050630061103],"luv":[57.2700846473106822,-43.3315696575835219,-9.35045110518458422],"rgb":[0.0666666666666666657,0.6,0.6],"xyz":[0.173710524809704198,0.252003232803488575,0.340866424485661845],"hpluv":[192.177050630061103,98.2197789195824384,57.2700846473106822],"hsluv":[192.177050630061103,97.8353178900151903,57.2700846473106822]},"#1199aa":{"lch":[57.849232550626823,48.3524707931101716,209.625127722111756],"luv":[57.849232550626823,-42.0317498411296384,-23.9017454821038378],"rgb":[0.0666666666666666657,0.6,0.66666666666666663],"xyz":[0.188768217774956726,0.258026309989589697,0.42017027410266039],"hpluv":[209.625127722111756,106.062142541807418,57.849232550626823],"hsluv":[209.625127722111756,97.9750198241805492,57.849232550626823]},"#1199bb":{"lch":[58.4975141278551263,56.1838887208170235,223.492153209811363],"luv":[58.4975141278551263,-40.7596491137071553,-38.6688551152037832],"rgb":[0.0666666666666666657,0.6,0.733333333333333282],"xyz":[0.2059058098822934,0.264881346832524456,0.510428259201302192],"hpluv":[223.492153209811363,121.8747424026255,58.4975141278551263],"hsluv":[223.492153209811363,98.1135798876595686,58.4975141278551263]},"#1199cc":{"lch":[59.2140605434028515,66.4726101728698211,233.498474693243395],"luv":[59.2140605434028515,-39.5408457239066138,-53.4334111079625274],"rgb":[0.0666666666666666657,0.6,0.8],"xyz":[0.225198185326015127,0.272598297010013257,0.612034769871572348],"hpluv":[233.498474693243395,142.448281943894045,59.2140605434028515],"hsluv":[233.498474693243395,98.2484961488154482,59.2140605434028515]},"#1199dd":{"lch":[59.9975033067865553,78.1149919905427907,240.560044488236258],"luv":[59.9975033067865553,-38.3943918665613637,-68.0281018909060151],"rgb":[0.0666666666666666657,0.6,0.866666666666666696],"xyz":[0.24671651087664867,0.281205627230266819,0.725364617771578346],"hpluv":[240.560044488236258,165.211601361935521,59.9975033067865553],"hsluv":[240.560044488236258,98.3778942246892285,59.9975033067865553]},"#1199ee":{"lch":[60.8460449735814706,90.4022578402124,245.60857134482],"luv":[60.8460449735814706,-37.3332566635070862,-82.3334450239084106],"rgb":[0.0666666666666666657,0.6,0.933333333333333348],"xyz":[0.270528691142823408,0.290730499336736836,0.850775433840101569],"hpluv":[245.60857134482,188.532510112076068,60.8460449735814706],"hsluv":[245.60857134482,98.5004851129029788,60.8460449735814706]},"#1199ff":{"lch":[61.7575303771721877,102.910627792409826,249.306643617498082],"luv":[61.7575303771721877,-36.3651553748586,-96.2713497733895167],"rgb":[0.0666666666666666657,0.6,1],"xyz":[0.296699739552654829,0.301198918700669505,0.988609622131883414],"hpluv":[249.306643617498082,211.450946466820028,61.7575303771721877],"hsluv":[249.306643617498082,99.9999999999986215,61.7575303771721877]},"#000000":{"lch":[0,0,0],"luv":[0,0,0],"rgb":[0,0,0],"xyz":[0,0,0],"hpluv":[0,0,0],"hsluv":[0,0,0]},"#000011":{"lch":[0.365533479526218952,1.47895322486610792,265.8743202181779],"luv":[0.365533479526218952,-0.106402530834795422,-1.47512072142377915],"rgb":[0,0,0.0666666666666666657],"xyz":[0.00101166549963712174,0.000404666199854854377,0.00532810496475563146],"hpluv":[265.8743202181779,513.41269684428039,0.365533479526218952],"hsluv":[265.8743202181779,100.000000000000867,0.365533479526218952]},"#000022":{"lch":[1.04313510374015572,4.22053823263236,265.8743202181779],"luv":[1.04313510374015572,-0.303644457367982512,-4.20960128950726],"rgb":[0,0,0.133333333333333331],"xyz":[0.0028870236381141408,0.00115480945524567245,0.0152049911607348275],"hpluv":[265.8743202181779,513.41269684428039,1.04313510374015572],"hsluv":[265.8743202181779,100.000000000000838,1.04313510374015572]},"#000033":{"lch":[2.15879662382733661,8.73451929157831,265.8743202181779],"luv":[2.15879662382733661,-0.62840050829424543,-8.71188498868810868],"rgb":[0,0,0.2],"xyz":[0.00597477437057188088,0.00238990974822878574,0.0314671450183459725],"hpluv":[265.8743202181779,513.412696844280276,2.15879662382733661],"hsluv":[265.8743202181779,100.000000000000838,2.15879662382733661]},"#000044":{"lch":[3.76955286085941,15.251660031516769,265.874320218177957],"luv":[3.76955286085941,-1.0972728545435857,-15.2121374566379668],"rgb":[0,0,0.266666666666666663],"xyz":[0.0104327696147907597,0.00417310784591636182,0.054945919971232611],"hpluv":[265.874320218177957,513.41269684428039,3.76955286085941],"hsluv":[265.874320218177957,100.000000000000981,3.76955286085941]},"#000055":{"lch":[5.92388346812606947,23.9681097618519345,265.8743202181779],"luv":[5.92388346812606947,-1.7243733575266309,-23.905999708860417],"rgb":[0,0,0.333333333333333315],"xyz":[0.0163951836541527535,0.00655807346166119385,0.0863479672452065194],"hpluv":[265.8743202181779,513.41269684428039,5.92388346812606947],"hsluv":[265.8743202181779,100.000000000000838,5.92388346812606947]},"#000066":{"lch":[8.64689012997685,34.9854302247980513,265.8743202181779],"luv":[8.64689012997685,-2.51700882467034193,-34.8947703043127149],"rgb":[0,0,0.4],"xyz":[0.0239801794276609283,0.00959207177106450627,0.126295611652350481],"hpluv":[265.8743202181779,513.412696844280276,8.64689012997685],"hsluv":[265.8743202181779,100.000000000000838,8.64689012997685]},"#000077":{"lch":[11.4958709948623863,46.5124439559768703,265.874320218177957],"luv":[11.4958709948623863,-3.34631391244679577,-46.3919133681426672],"rgb":[0,0,0.466666666666666674],"xyz":[0.0332941924478628443,0.0133176769791453226,0.17534941355874839],"hpluv":[265.874320218177957,513.412696844280276,11.4958709948623863],"hsluv":[265.874320218177957,100.000000000001,11.4958709948623863]},"#000088":{"lch":[14.2727431262745554,57.7477048111956535,265.874320218177957],"luv":[14.2727431262745554,-4.15462898927595781,-57.598059593379169],"rgb":[0,0,0.533333333333333326],"xyz":[0.0444346095498066723,0.0177738438199229153,0.234022276962320558],"hpluv":[265.874320218177957,513.41269684428039,14.2727431262745554],"hsluv":[265.874320218177957,100.000000000000952,14.2727431262745554]},"#000099":{"lch":[16.9872454361813823,68.7306165552763701,265.874320218177957],"luv":[16.9872454361813823,-4.94478893879780923,-68.5525106354185567],"rgb":[0,0,0.6],"xyz":[0.0574915736588793858,0.0229966294635520763,0.302788954603438465],"hpluv":[265.874320218177957,513.412696844280163,16.9872454361813823],"hsluv":[265.874320218177957,100.000000000000952,16.9872454361813823]},"#0000aa":{"lch":[19.6469460262523299,79.4917998262647529,265.8743202181779],"luv":[19.6469460262523299,-5.71899674710351302,-79.2858077831434116],"rgb":[0,0,0.66666666666666663],"xyz":[0.0725492666241319278,0.0290197066496531778,0.382092804220437066],"hpluv":[265.8743202181779,513.41269684428039,19.6469460262523299],"hsluv":[265.8743202181779,100.000000000000824,19.6469460262523299]},"#0000bb":{"lch":[22.2578820656552736,90.0556810893410926,265.8743202181779],"luv":[22.2578820656552736,-6.47900976369593895,-89.8223142039161644],"rgb":[0,0,0.733333333333333282],"xyz":[0.0896868587314685745,0.0358747434925879363,0.472350789319078812],"hpluv":[265.8743202181779,513.41269684428039,22.2578820656552736],"hsluv":[265.8743202181779,100.000000000000796,22.2578820656552736]},"#0000cc":{"lch":[24.8249727536546274,100.442163488877583,265.874320218177957],"luv":[24.8249727536546274,-7.22625991008361535,-100.18188146585355],"rgb":[0,0,0.8],"xyz":[0.108979234175190315,0.043591693670076738,0.573957299989349],"hpluv":[265.874320218177957,513.41269684428039,24.8249727536546274],"hsluv":[265.874320218177957,100.000000000001,24.8249727536546274]},"#0000dd":{"lch":[27.3522973211786535,110.667751646404724,265.8743202181779],"luv":[27.3522973211786535,-7.96193460279319343,-110.380971421034161],"rgb":[0,0,0.866666666666666696],"xyz":[0.130497559725823858,0.052199023890330272,0.687287147889355],"hpluv":[265.8743202181779,513.412696844280276,27.3522973211786535],"hsluv":[265.8743202181779,100.000000000000824,27.3522973211786535]},"#0000ee":{"lch":[29.8432887766479737,120.746335558760222,265.8743202181779],"luv":[29.8432887766479737,-8.68703315051946,-120.433438072283309],"rgb":[0,0,0.933333333333333348],"xyz":[0.154309739991998596,0.0617238959968003,0.812697963957878189],"hpluv":[265.8743202181779,513.41269684428039,29.8432887766479737],"hsluv":[265.8743202181779,100.000000000000838,29.8432887766479737]},"#0000ff":{"lch":[32.3008729039800215,130.68975298582734,265.8743202181779],"luv":[32.3008729039800215,-9.40240721482262,-130.351088503561101],"rgb":[0,0,1],"xyz":[0.18048078840183,0.072192315360733,0.95053215224966],"hpluv":[265.8743202181779,513.41269684428039,32.3008729039800215],"hsluv":[265.8743202181779,100.000000000000824,32.3008729039800215]},"#001100":{"lch":[3.62113466359794112,5.60448249758782424,127.715012949240474],"luv":[3.62113466359794112,-3.42845440085753106,4.43350025228474376],"rgb":[0,0.0666666666666666657,0],"xyz":[0.00200440026092840902,0.00400880052185687355,0.00066813342030945088],"hpluv":[127.715012949240474,196.394882900214469,3.62113466359794112],"hsluv":[127.715012949240474,100.000000000002217,3.62113466359794112]},"#001111":{"lch":[3.9866681431241604,3.15408977882195618,192.17705063006116],"luv":[3.9866681431241604,-3.08312421078118115,-0.665302512969894178],"rgb":[0,0.0666666666666666657,0.0666666666666666657],"xyz":[0.00301606576056553076,0.00441346672171172814,0.00599623838506508234],"hpluv":[192.17705063006116,100.392967527320764,3.9866681431241604],"hsluv":[192.17705063006116,99.9999999999914,3.9866681431241604]},"#001122":{"lch":[4.66426976733809706,7.30142401028103372,246.87889630792742],"luv":[4.66426976733809706,-2.86709314837997242,-6.71495118794031054],"rgb":[0,0.0666666666666666657,0.133333333333333331],"xyz":[0.00489142389904254939,0.005163609977102546,0.0158731245810442775],"hpluv":[246.87889630792742,198.638412351210178,4.66426976733809706],"hsluv":[246.87889630792742,99.9999999999921414,4.66426976733809706]},"#001133":{"lch":[5.77993128742527773,13.8979406242137369,257.974087263939282],"luv":[5.77993128742527773,-2.89569220292521434,-13.5929290537429299],"rgb":[0,0.0666666666666666657,0.2],"xyz":[0.00797917463150029,0.00639871027008565886,0.0321352784386554208],"hpluv":[257.974087263939282,305.117489912579458,5.77993128742527773],"hsluv":[257.974087263939282,99.9999999999925,5.77993128742527773]},"#001144":{"lch":[7.39068752445735111,21.802452480470059,261.611708702028636],"luv":[7.39068752445735111,-3.1805605696034065,-21.569213444774455],"rgb":[0,0.0666666666666666657,0.266666666666666663],"xyz":[0.0124371698757191687,0.00818190836777323537,0.0556140533915420593],"hpluv":[261.611708702028636,374.334482048802613,7.39068752445735111],"hsluv":[261.611708702028636,99.9999999999929656,7.39068752445735111]},"#001155":{"lch":[9.4550232844459714,31.0886305445366773,263.238579866128873],"luv":[9.4550232844459714,-3.6602302532303379,-30.8724094237562916],"rgb":[0,0.0666666666666666657,0.333333333333333315],"xyz":[0.0183995839150811608,0.0105668739835180665,0.0870161006655159747],"hpluv":[263.238579866128873,417.232678203522596,9.4550232844459714],"hsluv":[263.238579866128873,99.9999999999929514,9.4550232844459714]},"#001166":{"lch":[11.6894020192987682,40.9340765206813302,264.100423242359113],"luv":[11.6894020192987682,-4.20741678933990659,-40.7172723123955791],"rgb":[0,0.0666666666666666657,0.4],"xyz":[0.025984579688589339,0.0136008722929213798,0.126963745072659923],"hpluv":[264.100423242359113,444.357002567308371,11.6894020192987682],"hsluv":[264.100423242359113,99.9999999999928235,11.6894020192987682]},"#001177":{"lch":[14.0165943101603965,51.0460922578313898,264.608714664977526],"luv":[14.0165943101603965,-4.79613195559092276,-50.8202779710972621],"rgb":[0,0.0666666666666666657,0.466666666666666674],"xyz":[0.0352985927087912515,0.0173264775010021979,0.176017546979057832],"hpluv":[264.608714664977526,462.124851551559573,14.0165943101603965],"hsluv":[264.608714664977526,99.9999999999931504,14.0165943101603965]},"#001188":{"lch":[16.3962585295353378,61.2721603523949625,264.931782730652174],"luv":[16.3962585295353378,-5.41289085195630371,-61.0325998698597871],"rgb":[0,0.0666666666666666657,0.533333333333333326],"xyz":[0.0464390098107350796,0.0217826443417797888,0.23469041038263],"hpluv":[264.931782730652174,474.195864485329537,16.3962585295353378],"hsluv":[264.931782730652174,99.9999999999933209,16.3962585295353378]},"#001199":{"lch":[18.8023327262484941,71.5200065602600148,265.148843888859801],"luv":[18.8023327262484941,-6.04826966448705239,-71.2638040834565771],"rgb":[0,0.0666666666666666657,0.6],"xyz":[0.059495973919807793,0.0270054299854089498,0.303457088023747934],"hpluv":[265.148843888859801,482.675370310212884,18.8023327262484941],"hsluv":[265.148843888859801,99.9999999999930651,18.8023327262484941]},"#0011aa":{"lch":[21.2181090603332123,81.7349311996174919,265.301088447161305],"luv":[21.2181090603332123,-6.69569086805443892,-81.4602154551880488],"rgb":[0,0.0666666666666666657,0.66666666666666663],"xyz":[0.0745536668850603351,0.0330285071715100548,0.382760937640746535],"hpluv":[265.301088447161305,488.81030222212587,21.2181090603332123],"hsluv":[265.301088447161305,99.9999999999931788,21.2181090603332123]},"#0011bb":{"lch":[23.6329047323064216,91.8852368853417,265.411605614461337],"luv":[23.6329047323064216,-7.35054503717070418,-91.590754146539723],"rgb":[0,0.0666666666666666657,0.733333333333333282],"xyz":[0.0916912589923969817,0.0398835440144448133,0.473018922739388281],"hpluv":[265.411605614461337,493.364573724961247,23.6329047323064216],"hsluv":[265.411605614461337,99.999999999993,23.6329047323064216]},"#0011cc":{"lch":[26.0399131129061345,101.953231398784169,265.494123438592396],"luv":[26.0399131129061345,-8.00958293333115,-101.638122640513785],"rgb":[0,0.0666666666666666657,0.8],"xyz":[0.110983634436118722,0.047600494191933615,0.574625433409658437],"hpluv":[265.494123438592396,496.821968194535657,26.0399131129061345],"hsluv":[265.494123438592396,99.9999999999927383,26.0399131129061345]},"#0011dd":{"lch":[28.43483595206839,111.929749681002491,265.557201901085818],"luv":[28.43483595206839,-8.67050070949402496,-111.593419524175076],"rgb":[0,0.0666666666666666657,0.866666666666666696],"xyz":[0.132501959986752266,0.056207824412187149,0.687955281309664435],"hpluv":[265.557201901085818,499.498435149301031,28.43483595206839],"hsluv":[265.557201901085818,99.9999999999932214,28.43483595206839]},"#0011ee":{"lch":[30.8150119654139019,121.810820553676152,265.60639254385444],"luv":[30.8150119654139019,-9.33165721729429798,-121.452855781734542],"rgb":[0,0.0666666666666666657,0.933333333333333348],"xyz":[0.156314140252927,0.0657326965186571799,0.813366097378187658],"hpluv":[265.60639254385444,501.606152289563909,30.8150119654139019],"hsluv":[265.60639254385444,99.9999999999933635,30.8150119654139019]},"#0011ff":{"lch":[33.1788572452669683,131.59562707663585,265.645416939351662],"luv":[33.1788572452669683,-9.99188030865750321,-131.215743695604147],"rgb":[0,0.0666666666666666657,1],"xyz":[0.182485188662758396,0.076201115882589876,0.951200285669969503],"hpluv":[265.645416939351662,503.291227463659,33.1788572452669683],"hsluv":[265.645416939351662,99.9999999999995,33.1788572452669683]},"#55aa00":{"lch":[62.2364297391950743,84.7105424007581291,119.071642820441127],"luv":[62.2364297391950743,-41.1610955154551661,74.0380997176333437],"rgb":[0.333333333333333315,0.66666666666666663,0],"xyz":[0.181203244729902568,0.306798408854291604,0.0496696976001293408],"hpluv":[119.071642820441127,172.715819722381468,62.2364297391950743],"hsluv":[119.071642820441127,100.00000000000216,62.2364297391950743]},"#55aa11":{"lch":[62.270812500354296,83.3839078255156352,119.512873370738717],"luv":[62.270812500354296,-41.0765057562956173,72.5644317769187808],"rgb":[0.333333333333333315,0.66666666666666663,0.0666666666666666657],"xyz":[0.182214910229539701,0.307203075054146457,0.0549978025648849705],"hpluv":[119.512873370738717,169.917081036602212,62.270812500354296],"hsluv":[119.512873370738717,97.826098763204655,62.270812500354296]},"#55aa22":{"lch":[62.3344691942433826,80.9675552156414,120.358690899927907],"luv":[62.3344691942433826,-40.9219560187625078,69.8651451955580285],"rgb":[0.333333333333333315,0.66666666666666663,0.133333333333333331],"xyz":[0.184090268368016702,0.307953218309537258,0.0648746887608641631],"hpluv":[120.358690899927907,164.824621464176317,62.3344691942433826],"hsluv":[120.358690899927907,93.8493385636837729,62.3344691942433826]},"#55aa33":{"lch":[62.4390542004851312,77.1100321042589343,121.835090998601942],"luv":[62.4390542004851312,-40.6737079775314143,65.5103543760705094],"rgb":[0.333333333333333315,0.66666666666666663,0.2],"xyz":[0.187178019100474435,0.309188318602520384,0.0811368426184753133],"hpluv":[121.835090998601942,156.708983850290963,62.4390542004851312],"hsluv":[121.835090998601942,87.4478443822902,62.4390542004851312]},"#55aa44":{"lch":[62.5895604608427192,71.8060360850404322,124.168545167949461],"luv":[62.5895604608427192,-40.3283690350335959,59.4115264003566281],"rgb":[0.333333333333333315,0.66666666666666663,0.266666666666666663],"xyz":[0.191636014344693323,0.310971516700207951,0.104615617571361952],"hpluv":[124.168545167949461,145.578881327618376,62.5895604608427192],"hsluv":[124.168545167949461,78.5131262768233569,62.5895604608427192]},"#55aa55":{"lch":[62.7899606618147317,65.2067785819955361,127.715012949239551],"luv":[62.7899606618147317,-39.8892256495404212,51.582687503865472],"rgb":[0.333333333333333315,0.66666666666666663,0.333333333333333315],"xyz":[0.197598428384055336,0.313356482315952811,0.136017664845335867],"hpluv":[127.715012949239551,131.777681042751937,62.7899606618147317],"hsluv":[127.715012949239551,67.0983271543339583,62.7899606618147317]},"#55aa66":{"lch":[63.0434325957243402,57.6560159218084,133.059858461454269],"luv":[63.0434325957243402,-39.3653397911167744,42.1258376190401904],"rgb":[0.333333333333333315,0.66666666666666663,0.4],"xyz":[0.205183424157563493,0.31639048062535613,0.175965309252479829],"hpluv":[133.059858461454269,116.049721847977636,63.0434325957243402],"hsluv":[133.059858461454269,68.1368400599560289,63.0434325957243402]},"#55aa77":{"lch":[63.3524771250310863,49.7736139598232441,141.163090238883626],"luv":[63.3524771250310863,-38.7703675351212311,31.2133184364163512],"rgb":[0.333333333333333315,0.66666666666666663,0.466666666666666674],"xyz":[0.214497437177765427,0.320116085833436925,0.225019111158877738],"hpluv":[141.163090238883626,99.6953496544650903,63.3524771250310863],"hsluv":[141.163090238883626,69.3257510819996696,63.3524771250310863]},"#55aa88":{"lch":[63.7189896387035901,42.62351374085884,153.427389325734708],"luv":[63.7189896387035901,-38.1211143540371324,19.0668446268281784],"rgb":[0.333333333333333315,0.66666666666666663,0.533333333333333326],"xyz":[0.225637854279709227,0.324572252674214523,0.283691974562449878],"hpluv":[153.427389325734708,84.882799477410984,63.7189896387035901],"hsluv":[153.427389325734708,70.6362499177174783,63.7189896387035901]},"#55aa99":{"lch":[64.1443101574831473,37.9035590936142697,170.991128647613664],"luv":[64.1443101574831473,-37.4359848569684885,5.93521943587048106],"rgb":[0.333333333333333315,0.66666666666666663,0.6],"xyz":[0.238694818388781954,0.329795038317843681,0.352458652203567813],"hpluv":[170.991128647613664,74.9827180661079211,64.1443101574831473],"hsluv":[170.991128647613664,72.0364673991159918,64.1443101574831473]},"#55aaaa":{"lch":[64.6292640862610881,37.5790288142004414,192.177050630061],"luv":[64.6292640862610881,-36.7335179653569526,-7.92666793219602717],"rgb":[0.333333333333333315,0.66666666666666663,0.66666666666666663],"xyz":[0.253752511354034482,0.335818115503944803,0.431762501820566413],"hpluv":[192.177050630061,73.7828909738526,64.6292640862610881],"hsluv":[192.177050630061,73.4940830927894808,64.6292640862610881]},"#55aabb":{"lch":[65.1741997434662466,42.3607987370151307,211.725401595501864],"luv":[65.1741997434662466,-36.0311661131296148,-22.2753751520813346],"rgb":[0.333333333333333315,0.66666666666666663,0.733333333333333282],"xyz":[0.270890103461371157,0.342673152346879561,0.522020486919208104],"hpluv":[211.725401595501864,82.4760322189960249,65.1741997434662466],"hsluv":[211.725401595501864,74.9784994025983,65.1741997434662466]},"#55aacc":{"lch":[65.7790257871148327,51.0903516363502916,226.227071697937646],"luv":[65.7790257871148327,-35.3444111183519212,-36.8916878581455236],"rgb":[0.333333333333333315,0.66666666666666663,0.8],"xyz":[0.290182478905092855,0.350390102524368363,0.62362699758947826],"hpluv":[226.227071697937646,98.5577501957325808,65.7790257871148327],"hsluv":[226.227071697937646,76.4624197891718,65.7790257871148327]},"#55aadd":{"lch":[66.4432499478878071,62.1650528283955595,236.084470311275709],"luv":[66.4432499478878071,-34.6862381636523693,-51.5883579425784404],"rgb":[0.333333333333333315,0.66666666666666663,0.866666666666666696],"xyz":[0.311700804455726455,0.358997432744621869,0.736956845489484258],"hpluv":[236.084470311275709,118.722973851074883,66.4432499478878071],"hsluv":[236.084470311275709,77.9227939155192928,66.4432499478878071]},"#55aaee":{"lch":[67.1660194476775274,74.4631251020179832,242.774049894046698],"luv":[67.1660194476775274,-34.0669326024190866,-66.2133000462974763],"rgb":[0.333333333333333315,0.66666666666666663,0.933333333333333348],"xyz":[0.335512984721901164,0.368522304851091886,0.862367661558007481],"hpluv":[242.774049894046698,140.679551339708695,67.1660194476775274],"hsluv":[242.774049894046698,80.7550915423080085,67.1660194476775274]},"#55aaff":{"lch":[67.9461628502375135,87.3278464079016,247.446578213330071],"luv":[67.9461628502375135,-33.4941307575646476,-80.6492155140842897],"rgb":[0.333333333333333315,0.66666666666666663,1],"xyz":[0.361684033131732585,0.37899072421502461,1.00020184984978933],"hpluv":[247.446578213330071,163.089927997179217,67.9461628502375135],"hsluv":[247.446578213330071,99.9999999999981,67.9461628502375135]},"#002200":{"lch":[10.1376941245203973,15.6902558355344119,127.715012949240474],"luv":[10.1376941245203973,-9.59826829561359141,12.4119850914324186],"rgb":[0,0.133333333333333331,0],"xyz":[0.00572002399569634425,0.0114400479913928481,0.00190667466523206119],"hpluv":[127.715012949240474,196.394882900214583,10.1376941245203973],"hsluv":[127.715012949240474,100.000000000002331,10.1376941245203973]},"#002211":{"lch":[10.4423176349325608,11.2803579121031614,143.951720967420982],"luv":[10.4423176349325608,-9.12041102953238614,6.63811549142769763],"rgb":[0,0.133333333333333331,0.0666666666666666657],"xyz":[0.00673168949533346599,0.0118447141912477027,0.00723477962998769243],"hpluv":[143.951720967420982,137.077225818420459,10.4423176349325608],"hsluv":[143.951720967420982,99.9999999999911,10.4423176349325608]},"#002222":{"lch":[10.9891417742670896,8.69416226881610399,192.17705063006116],"luv":[10.9891417742670896,-8.49854762011842,-1.83388819318003415],"rgb":[0,0.133333333333333331,0.133333333333333331],"xyz":[0.00860704763381048461,0.0125948574466385205,0.0171116658259668902],"hpluv":[192.17705063006116,100.392967527320849,10.9891417742670896],"hsluv":[192.17705063006116,99.9999999999915,10.9891417742670896]},"#002233":{"lch":[11.8439988341371283,14.4341695325786503,236.81663495428262],"luv":[11.8439988341371283,-7.90011340243738758,-12.0802921456333543],"rgb":[0,0.133333333333333331,0.2],"xyz":[0.0116947983662682251,0.0138299577396216334,0.0333738196835780335],"hpluv":[236.81663495428262,154.643892414528665,11.8439988341371283],"hsluv":[236.81663495428262,99.9999999999918572,11.8439988341371283]},"#002244":{"lch":[12.9926705590666103,23.9154033254141893,251.756603241059679],"luv":[12.9926705590666103,-7.48682111947174356,-22.713300635140282],"rgb":[0,0.133333333333333331,0.266666666666666663],"xyz":[0.0161527936104871039,0.0156131558373092099,0.056852594636464672],"hpluv":[251.756603241059679,233.570832873869165,12.9926705590666103],"hsluv":[251.756603241059679,99.9999999999922551,12.9926705590666103]},"#002255":{"lch":[14.3995425627967926,34.0053227001087492,257.612107564284656],"luv":[14.3995425627967926,-7.29512566501762105,-33.2135983216232162],"rgb":[0,0.133333333333333331,0.333333333333333315],"xyz":[0.022115207649849096,0.0179981214530540411,0.0882546419104385804],"hpluv":[257.612107564284656,299.666041626864057,14.3995425627967926],"hsluv":[257.612107564284656,99.9999999999922551,14.3995425627967926]},"#002266":{"lch":[16.0198287291043684,44.1221041927951489,260.479541157990241],"luv":[16.0198287291043684,-7.29778599254304705,-43.514392998258792],"rgb":[0,0.133333333333333331,0.4],"xyz":[0.0297002034233572743,0.0210321197624573561,0.128202286317582542],"hpluv":[260.479541157990241,349.492349810916096,16.0198287291043684],"hsluv":[260.479541157990241,99.9999999999926672,16.0198287291043684]},"#002277":{"lch":[17.8086814865908138,54.1839210795750787,262.094384047744654],"luv":[17.8086814865908138,-7.45254493353373,-53.6689563674502708],"rgb":[0,0.133333333333333331,0.466666666666666674],"xyz":[0.0390142164435591868,0.0247577249705381724,0.177256088223980451],"hpluv":[262.094384047744654,386.080609388904179,17.8086814865908138],"hsluv":[262.094384047744654,99.9999999999926246,17.8086814865908138]},"#002288":{"lch":[19.7262797638069571,64.1945165648047862,263.091662768615947],"luv":[19.7262797638069571,-7.7213996360385595,-63.7284547486409778],"rgb":[0,0.133333333333333331,0.533333333333333326],"xyz":[0.0501546335455030148,0.0292138918113157633,0.235928951627552619],"hpluv":[263.091662768615947,412.944865974292611,19.7262797638069571],"hsluv":[263.091662768615947,99.9999999999928093,19.7262797638069571]},"#002299":{"lch":[21.7396965211461932,74.1610579713059082,263.749129578079874],"luv":[21.7396965211461932,-8.0748025544340809,-73.7201470639492129],"rgb":[0,0.133333333333333331,0.6],"xyz":[0.0632115976545757352,0.0344366774549449278,0.304695629268670554],"hpluv":[263.749129578079874,432.874263951475,21.7396965211461932],"hsluv":[263.749129578079874,99.9999999999928662,21.7396965211461932]},"#0022aa":{"lch":[23.8228560713303921,84.0831956926279389,264.204285416148139],"luv":[23.8228560713303921,-8.49087961251211532,-83.6533846373868641],"rgb":[0,0.133333333333333331,0.66666666666666663],"xyz":[0.0782692906198282773,0.0404597546410460224,0.383999478885669154],"hpluv":[264.204285416148139,447.872821658188343,23.8228560713303921],"hsluv":[264.204285416148139,99.9999999999925251,23.8228560713303921]},"#0022bb":{"lch":[25.9556350824861326,93.9557715434331868,264.531619021467236],"luv":[25.9556350824861326,-8.95364890679069,-93.5281731756572725],"rgb":[0,0.133333333333333331,0.733333333333333282],"xyz":[0.0954068827271649239,0.0473147914839807809,0.474257463984310901],"hpluv":[264.531619021467236,459.336683180505304,25.9556350824861326],"hsluv":[264.531619021467236,99.9999999999932783,25.9556350824861326]},"#0022cc":{"lch":[28.122733334265547,103.772183036952711,264.774345627526145],"luv":[28.122733334265547,-9.45141286238599143,-103.340876555018355],"rgb":[0,0.133333333333333331,0.8],"xyz":[0.114699258170886664,0.0550317416614695826,0.575863974654581057],"hpluv":[264.774345627526145,468.233789407088068,28.122733334265547],"hsluv":[264.774345627526145,99.9999999999932,28.122733334265547]},"#0022dd":{"lch":[30.3126112219004114,113.526334495176528,264.958927468127968],"luv":[30.3126112219004114,-9.97554123069502552,-113.087210599012522],"rgb":[0,0.133333333333333331,0.866666666666666696],"xyz":[0.136217583721520208,0.0636390718817231166,0.689193822554587],"hpluv":[264.958927468127968,475.239568383116307,30.3126112219004114],"hsluv":[264.958927468127968,99.9999999999930651,30.3126112219004114]},"#0022ee":{"lch":[32.516600051948771,123.213441320075319,265.102292473050682],"luv":[32.516600051948771,-10.519601137712538,-122.76355368691101],"rgb":[0,0.133333333333333331,0.933333333333333348],"xyz":[0.160029763987694945,0.0731639439881931475,0.814604638623110278],"hpluv":[265.102292473050682,480.830806343612153,32.516600051948771],"hsluv":[265.102292473050682,99.9999999999931504,32.516600051948771]},"#0022ff":{"lch":[34.728199222084136,132.830192238289243,265.215668718406278],"luv":[34.728199222084136,-11.0787458291525667,-132.367372720447662],"rgb":[0,0.133333333333333331,1],"xyz":[0.186200812397526339,0.0836323633521258575,0.952438826914892123],"hpluv":[265.215668718406278,485.348691920142073,34.728199222084136],"hsluv":[265.215668718406278,99.9999999999995595,34.728199222084136]},"#55bb00":{"lch":[67.6287132051522093,94.1564927152114421,120.799924159261636],"luv":[67.6287132051522093,-48.2120532219748839,80.8767150949587403],"rgb":[0.333333333333333315,0.733333333333333282,0],"xyz":[0.215157742638501348,0.374707404671490163,0.0609878635696619598],"hpluv":[120.799924159261636,176.668237076728246,67.6287132051522093],"hsluv":[120.799924159261636,100.000000000002245,67.6287132051522093]},"#55bb11":{"lch":[67.658807387059241,92.983820197622,121.168613223743336],"luv":[67.658807387059241,-48.1245535730997,79.5614112615755],"rgb":[0.333333333333333315,0.733333333333333282,0.0666666666666666657],"xyz":[0.21616940813813848,0.375112070871345,0.0663159685344176],"hpluv":[121.168613223743336,174.390319462510746,67.658807387059241],"hsluv":[121.168613223743336,98.2170484527892853,67.658807387059241]},"#55bb22":{"lch":[67.7145367797011,90.8418307914021739,121.8702408444057],"luv":[67.7145367797011,-47.9642424389893733,77.1470651987980318],"rgb":[0.333333333333333315,0.733333333333333282,0.133333333333333331],"xyz":[0.218044766276615481,0.375862214126735816,0.076192854730396789],"hpluv":[121.8702408444057,170.232819736279453,67.7145367797011],"hsluv":[121.8702408444057,94.9476871157098401,67.7145367797011]},"#55bb33":{"lch":[67.8061331119394595,87.4049119918652337,123.079288563119889],"luv":[67.8061331119394595,-47.7055226907732077,73.2379802090816128],"rgb":[0.333333333333333315,0.733333333333333282,0.2],"xyz":[0.221132517009073215,0.377097314419718943,0.0924550085880079253],"hpluv":[123.079288563119889,163.570954697809668,67.8061331119394595],"hsluv":[123.079288563119889,89.6636954368763526,67.8061331119394595]},"#55bb44":{"lch":[67.9380247917114701,82.6396215824211851,124.951716096499126],"luv":[67.9380247917114701,-47.3430758547011195,67.7343356349037293],"rgb":[0.333333333333333315,0.733333333333333282,0.266666666666666663],"xyz":[0.225590512253292103,0.378880512517406509,0.115933783540894564],"hpluv":[124.951716096499126,154.352877500253584,67.9380247917114701],"hsluv":[124.951716096499126,82.2446152582935213,67.9380247917114701]},"#55bb55":{"lch":[68.1137800414251,76.6309713561306154,127.715012949239735],"luv":[68.1137800414251,-46.8777966745344372,60.6199467990950964],"rgb":[0.333333333333333315,0.733333333333333282,0.333333333333333315],"xyz":[0.231552926292654115,0.38126547813315137,0.147335830814868479],"hpluv":[127.715012949239735,142.760701907139094,68.1137800414251],"hsluv":[127.715012949239735,72.6906423420812189,68.1137800414251]},"#55bb66":{"lch":[68.3363083667640723,69.6002362161904813,131.717534816394789],"luv":[68.3363083667640723,-46.3160914021311,51.9520216986687728],"rgb":[0.333333333333333315,0.733333333333333282,0.4],"xyz":[0.239137922066162273,0.384299476442554688,0.187283475222012441],"hpluv":[131.717534816394789,129.240469264566769,68.3363083667640723],"hsluv":[131.717534816394789,73.4099839145656432,68.3363083667640723]},"#55bb77":{"lch":[68.6079661831172416,61.943926665161591,137.498849513297245],"luv":[68.6079661831172416,-45.6690129611091,41.8496273084595956],"rgb":[0.333333333333333315,0.733333333333333282,0.466666666666666674],"xyz":[0.248451935086364206,0.388025081650635484,0.23633727712841035],"hpluv":[137.498849513297245,114.568047908441656,68.6079661831172416],"hsluv":[137.498849513297245,74.2430874467708719,68.6079661831172416]},"#55bb88":{"lch":[68.930619778887035,54.3103726013937376,145.860320527647957],"luv":[68.930619778887035,-44.9511677919681389,30.4796503628330058],"rgb":[0.333333333333333315,0.733333333333333282,0.533333333333333326],"xyz":[0.259592352188308,0.392481248491413082,0.29501014053198249],"hpluv":[145.860320527647957,99.9792617157038421,68.930619778887035],"hsluv":[145.860320527647957,75.173468866550067,68.930619778887035]},"#55bb99":{"lch":[69.3056876145919176,47.7211055743842465,157.786981113384826],"luv":[69.3056876145919176,-44.1794697421466793,18.0410191104680564],"rgb":[0.333333333333333315,0.733333333333333282,0.6],"xyz":[0.272649316297380762,0.397704034135042239,0.363776818173100425],"hpluv":[157.786981113384826,87.3737441175344713,69.3056876145919176],"hsluv":[157.786981113384826,76.1818306173187807,69.3056876145919176]},"#55bbaa":{"lch":[69.7341725511637378,43.6310575063277497,173.751690425302456],"luv":[69.7341725511637378,-43.37186937951342,4.74869725787034813],"rgb":[0.333333333333333315,0.733333333333333282,0.66666666666666663],"xyz":[0.287707009262633262,0.403727111321143362,0.443080667790099],"hpluv":[173.751690425302456,79.3943164161001675,69.7341725511637378],"hsluv":[173.751690425302456,77.247554342351421,69.7341725511637378]},"#55bbbb":{"lch":[70.2166895771587605,43.5254926875218899,192.177050630061075],"luv":[70.2166895771587605,-42.5461891389785691,-9.18097508120914796],"rgb":[0.333333333333333315,0.733333333333333282,0.733333333333333282],"xyz":[0.304844601369969936,0.41058214816407812,0.533338652888740716],"hpluv":[192.177050630061075,78.6579587560082274,70.2166895771587605],"hsluv":[192.177050630061075,78.350068429440185,70.2166895771587605]},"#55bbcc":{"lch":[70.753492069254392,47.9033609117661214,209.436295084806801],"luv":[70.753492069254392,-41.719164640327179,-23.5423721905035848],"rgb":[0.333333333333333315,0.733333333333333282,0.8],"xyz":[0.324136976813691691,0.418299098341566922,0.634945163559010872],"hpluv":[209.436295084806801,85.9127126132272849,70.753492069254392],"hsluv":[209.436295084806801,79.4699741443966445,70.753492069254392]},"#55bbdd":{"lch":[71.3444981992470701,55.9344204047748121,223.003151043067675],"luv":[71.3444981992470701,-40.905747403701568,-38.1494327004039633],"rgb":[0.333333333333333315,0.733333333333333282,0.866666666666666696],"xyz":[0.345655302364325179,0.426906428561820428,0.74827501145901687],"hpluv":[223.003151043067675,99.4850863142100081,71.3444981992470701],"hsluv":[223.003151043067675,80.5898663629362,71.3444981992470701]},"#55bbee":{"lch":[71.9893182406489,66.3452770137575385,232.793079173014576],"luv":[71.9893182406489,-40.1186787976363846,-52.8411524624918272],"rgb":[0.333333333333333315,0.733333333333333282,0.933333333333333348],"xyz":[0.369467482630499944,0.436431300668290445,0.873685827527540093],"hpluv":[232.793079173014576,116.944897502912525,71.9893182406489],"hsluv":[232.793079173014576,81.6948376758296888,71.9893182406489]},"#55bbff":{"lch":[72.6872829834048417,78.1278426582451146,239.741904567598624],"luv":[72.6872829834048417,-39.3683093588317803,-67.4840426816504788],"rgb":[0.333333333333333315,0.733333333333333282,1],"xyz":[0.395638531040331309,0.446899720032223169,1.01152001581932205],"hpluv":[239.741904567598624,136.39131713467242,72.6872829834048417],"hsluv":[239.741904567598624,99.9999999999976126,72.6872829834048417]},"#003300":{"lch":[17.3086983277836381,26.7889227675687067,127.71501294924046],"luv":[17.3086983277836381,-16.3877039844862402,21.1917328494772867],"rgb":[0,0.2,0],"xyz":[0.0118377460847071559,0.0236754921694146449,0.00394591536156894181],"hpluv":[127.71501294924046,196.394882900214611,17.3086983277836381],"hsluv":[127.71501294924046,100.000000000002402,17.3086983277836381]},"#003311":{"lch":[17.4974002223845133,22.6621201022865968,134.58430385811792],"luv":[17.4974002223845133,-15.9078557679049606,16.1403783226414816],"rgb":[0,0.2,0.0666666666666666657],"xyz":[0.0128494115843442776,0.0240801583692694977,0.00927402032632457241],"hpluv":[134.58430385811792,164.348724425256108,17.4974002223845133],"hsluv":[134.58430385811792,99.9999999999909335,17.4974002223845133]},"#003322":{"lch":[17.8416856931397234,17.1190432019509622,152.323942273369369],"luv":[17.8416856931397234,-15.1604156821769873,7.95131665159082601],"rgb":[0,0.2,0.133333333333333331],"xyz":[0.0147247697228212963,0.0248303016246603156,0.0191509065223037685],"hpluv":[152.323942273369369,121.753913655152402,17.8416856931397234],"hsluv":[152.323942273369369,99.9999999999912177,17.8416856931397234]},"#003333":{"lch":[18.3937448040413543,14.5523831926532932,192.17705063006116],"luv":[18.3937448040413543,-14.2249612699966086,-3.06958196712752551],"rgb":[0,0.2,0.2],"xyz":[0.017812520455279035,0.0260654019176434319,0.0354130603799149152],"hpluv":[192.17705063006116,100.392967527320849,18.3937448040413543],"hsluv":[192.17705063006116,99.9999999999915,18.3937448040413543]},"#003344":{"lch":[19.1608294605123817,20.3566459399555,229.223567805483242],"luv":[19.1608294605123817,-13.2951121246929258,-15.41535038578591],"rgb":[0,0.2,0.266666666666666663],"xyz":[0.0222705156994979156,0.0278486000153310084,0.0588918353328015537],"hpluv":[229.223567805483242,134.812835768594709,19.1608294605123817],"hsluv":[229.223567805483242,99.9999999999917577,19.1608294605123817]},"#003355":{"lch":[20.1371955335767296,30.6237106081975696,245.893961784182551],"luv":[20.1371955335767296,-12.5075398018694361,-27.9530517031554915],"rgb":[0,0.2,0.333333333333333315],"xyz":[0.0282329297388599076,0.0302335656310758379,0.0902938826067754552],"hpluv":[245.893961784182551,192.973712242731381,20.1371955335767296],"hsluv":[245.893961784182551,99.9999999999920419,20.1371955335767296]},"#003366":{"lch":[21.3076868402923836,41.8514919359335167,253.451236278131262],"luv":[21.3076868402923836,-11.9206140697212764,-40.1179054471226308],"rgb":[0,0.2,0.4],"xyz":[0.0358179255123680859,0.0332675639404791529,0.130241527013919417],"hpluv":[253.451236278131262,249.237832456686277,21.3076868402923836],"hsluv":[253.451236278131262,99.9999999999920846,21.3076868402923836]},"#003377":{"lch":[22.6513946103128916,53.0186284648852251,257.430711853641924],"luv":[22.6513946103128916,-11.5379190314963687,-51.7479602372902434],"rgb":[0,0.2,0.466666666666666674],"xyz":[0.04513193853257,0.0369931691485599692,0.179295328920317326],"hpluv":[257.430711853641924,297.011229333042763,22.6513946103128916],"hsluv":[257.430711853641924,99.9999999999922409,22.6513946103128916]},"#003388":{"lch":[24.1449124481648099,63.8887963004775941,259.778872090702237],"luv":[24.1449124481648099,-11.3369168899634012,-62.8748964862287636],"rgb":[0,0.2,0.533333333333333326],"xyz":[0.0562723556345138265,0.0414493359893375601,0.237968192323889494],"hpluv":[259.778872090702237,335.767299249073346,24.1449124481648099],"hsluv":[259.778872090702237,99.9999999999925677,24.1449124481648099]},"#003399":{"lch":[25.764809398314533,74.4520642325545481,261.279947020055374],"luv":[25.764809398314533,-11.2874373109462987,-73.5914643653724596],"rgb":[0,0.2,0.6],"xyz":[0.0693293197435865399,0.0466721216329667177,0.306734869965007428],"hpluv":[261.279947020055374,366.681615332004242,25.764809398314533],"hsluv":[261.279947020055374,99.9999999999928662,25.764809398314533]},"#0033aa":{"lch":[27.4892253326185596,84.7561178753388447,262.297068677869788],"luv":[27.4892253326185596,-11.360446037840406,-83.9913077831251],"rgb":[0,0.2,0.66666666666666663],"xyz":[0.084387012708839082,0.0526951988190678261,0.386038719582006029],"hpluv":[262.297068677869788,391.244172205097584,27.4892253326185596],"hsluv":[262.297068677869788,99.9999999999925819,27.4892253326185596]},"#0033bb":{"lch":[29.2987082140811808,94.8530383242648725,263.01737082090068],"luv":[29.2987082140811808,-11.531133966499155,-94.1495184734957178],"rgb":[0,0.2,0.733333333333333282],"xyz":[0.101524604816175729,0.0595502356620025847,0.476296704680647776],"hpluv":[263.01737082090068,410.811034734971429,29.2987082140811808],"hsluv":[263.01737082090068,99.999999999992923,29.2987082140811808]},"#0033cc":{"lch":[31.1765026722858281,104.784892642773883,263.545454640352943],"luv":[31.1765026722858281,-11.7793879173059235,-104.120697973319764],"rgb":[0,0.2,0.8],"xyz":[0.120816980259897469,0.0672671858394913863,0.577903215350917931],"hpluv":[263.545454640352943,426.491720029659064,31.1765026722858281],"hsluv":[263.545454640352943,99.9999999999928519,31.1765026722858281]},"#0033dd":{"lch":[33.108496036114694,114.582250296133722,263.943596884481394],"luv":[33.108496036114694,-12.0892798728815123,-113.942711022166648],"rgb":[0,0.2,0.866666666666666696],"xyz":[0.142335305810531026,0.0758745160597449203,0.691233063250923929],"hpluv":[263.943596884481394,439.154381827523366,33.108496036114694],"hsluv":[263.943596884481394,99.999999999992724,33.108496036114694]},"#0033ee":{"lch":[35.0829820911796091,124.266344101148519,264.250786122927309],"luv":[35.0829820911796091,-12.4483077284590724,-123.641271066592637],"rgb":[0,0.2,0.933333333333333348],"xyz":[0.166147486076705764,0.0853993881662149512,0.816643879319447152],"hpluv":[264.250786122927309,449.46548401365061,35.0829820911796091],"hsluv":[264.250786122927309,99.9999999999932214,35.0829820911796091]},"#0033ff":{"lch":[37.0903499028545482,133.851694130242549,264.492451291459133],"luv":[37.0903499028545482,-12.8466699872586325,-133.233776092154926],"rgb":[0,0.2,1],"xyz":[0.192318534486537157,0.0958678075301476473,0.954478067611229],"hpluv":[264.492451291459133,457.933345064777,37.0903499028545482],"hsluv":[264.492451291459133,99.999999999999531,37.0903499028545482]},"#55cc00":{"lch":[72.9678739916599,103.392643433537373,122.072672834653702],"luv":[72.9678739916599,-54.9009234662034089,87.6123696673744661],"rgb":[0.333333333333333315,0.8,0],"xyz":[0.253381485948118268,0.451154891290725057,0.0737291113395339148],"hpluv":[122.072672834653702,179.803140433373983,72.9678739916599],"hsluv":[122.072672834653702,100.000000000002444,72.9678739916599]},"#55cc11":{"lch":[72.9944661394807497,102.34674561848017,122.382691003133885],"luv":[72.9944661394807497,-54.8140205324080085,86.4307786136781431],"rgb":[0.333333333333333315,0.8,0.0666666666666666657],"xyz":[0.254393151447755372,0.45155955749057991,0.0790572163042895515],"hpluv":[122.382691003133885,177.91945009175069,72.9944661394807497],"hsluv":[122.382691003133885,98.5172338886757757,72.9944661394807497]},"#55cc22":{"lch":[73.0437189009647909,100.431941691916791,122.969611448584445],"luv":[73.0437189009647909,-54.6544745496639663,84.2583130836875114],"rgb":[0.333333333333333315,0.8,0.133333333333333331],"xyz":[0.256268509586232429,0.452309700745970711,0.0889341025002687441],"hpluv":[122.969611448584445,174.473032354427772,73.0437189009647909],"hsluv":[122.969611448584445,95.7933392549395,73.0437189009647909]},"#55cc33":{"lch":[73.1246943704287702,97.3470237033586,123.971835615120114],"luv":[73.1246943704287702,-54.3960871275936384,80.7310889875115123],"rgb":[0.333333333333333315,0.8,0.2],"xyz":[0.259356260318690135,0.453544801038953838,0.10519625635787988],"hpluv":[123.971835615120114,168.926560877595364,73.1246943704287702],"hsluv":[123.971835615120114,91.3772697810403542,73.1246943704287702]},"#55cc44":{"lch":[73.2413452172043,93.0415252478239836,125.502056943833935],"luv":[73.2413452172043,-54.0322080150887771,75.7446098244333399],"rgb":[0.333333333333333315,0.8,0.266666666666666663],"xyz":[0.26381425556290905,0.455327999136641404,0.128675031310766519],"hpluv":[125.502056943833935,161.198069131808353,73.2413452172043],"hsluv":[125.502056943833935,85.148140842768953,73.2413452172043]},"#55cc55":{"lch":[73.3968865779486919,87.5572640326508207,127.71501294923992],"luv":[73.3968865779486919,-53.5617851120033066,69.2633356148757144],"rgb":[0.333333333333333315,0.8,0.333333333333333315],"xyz":[0.269776669602271035,0.457712964752386264,0.160077078584740434],"hpluv":[127.71501294923992,151.374900584602614,73.3968865779486919],"hsluv":[127.71501294923992,77.0768048277098,73.3968865779486919]},"#55cc66":{"lch":[73.5939772793636,81.0375847478920832,130.834727778769576],"luv":[73.5939772793636,-52.9887999422805,61.3129449826769175],"rgb":[0.333333333333333315,0.8,0.4],"xyz":[0.277361665375779221,0.460746963061789583,0.200024722991884396],"hpluv":[130.834727778769576,139.728031568505,73.5939772793636],"hsluv":[130.834727778769576,77.5857883184082766,73.5939772793636]},"#55cc77":{"lch":[73.8348152761848553,73.7475179973278898,135.191797127350526],"luv":[73.8348152761848553,-52.3216404431773,51.972515352838883],"rgb":[0.333333333333333315,0.8,0.466666666666666674],"xyz":[0.286675678395981126,0.464472568269870378,0.249078524898282305],"hpluv":[135.191797127350526,126.743455190439619,73.8348152761848553],"hsluv":[135.191797127350526,78.1806978106980779,73.8348152761848553]},"#55cc88":{"lch":[74.1211942127210648,66.1117924559585646,141.267644806662588],"luv":[74.1211942127210648,-51.5723023085178269,41.3650424433311343],"rgb":[0.333333333333333315,0.8,0.533333333333333326],"xyz":[0.297816095497924926,0.468928735110648,0.307751388301854445],"hpluv":[141.267644806662588,113.181605649052202,74.1211942127210648],"hsluv":[141.267644806662588,78.852064841283763,74.1211942127210648]},"#55cc99":{"lch":[74.4545405069311,58.7794373107374923,149.710693018120253],"luv":[74.4545405069311,-50.7554383804248,29.646377947024483],"rgb":[0.333333333333333315,0.8,0.6],"xyz":[0.310873059606997626,0.474151520754277134,0.37651806594297238],"hpluv":[149.710693018120253,100.178278207809555,74.4545405069311],"hsluv":[149.710693018120253,79.5881732610030355,74.4545405069311]},"#55ccaa":{"lch":[74.8359403329188808,52.7021878309829361,161.189357777818884],"luv":[74.8359403329188808,-49.8873315971569866,16.9933736582089097],"rgb":[0.333333333333333315,0.8,0.66666666666666663],"xyz":[0.325930752572250182,0.480174597940378256,0.455821915559971],"hpluv":[161.189357777818884,89.3630022499163772,74.8359403329188808],"hsluv":[161.189357777818884,80.3759073289738097,74.8359403329188808]},"#55ccbb":{"lch":[75.2661614985634,49.1164256219739315,175.805780272408356],"luv":[75.2661614985634,-48.9848849956305372,3.59225665059547428],"rgb":[0.333333333333333315,0.8,0.733333333333333282],"xyz":[0.343068344679586856,0.487029634783313,0.546079900658612782],"hpluv":[175.805780272408356,82.8068592257523619,75.2661614985634],"hsluv":[175.805780272408356,81.2015846585734238,75.2661614985634]},"#55cccc":{"lch":[75.7456730324682894,49.1710405410584386,192.177050630061103],"luv":[75.7456730324682894,-48.0647147647340063,-10.3718090261618983],"rgb":[0.333333333333333315,0.8,0.8],"xyz":[0.362360720123308555,0.494746584960801816,0.647686411328882938],"hpluv":[192.177050630061103,82.3741405590198639,75.7456730324682894],"hsluv":[192.177050630061103,82.0517040066532815,75.7456730324682894]},"#55ccdd":{"lch":[76.2746640882933349,53.2320113470533514,207.674227909684788],"luv":[76.2746640882933349,-47.1424090239802069,-24.7232745296525458],"rgb":[0.333333333333333315,0.8,0.866666666666666696],"xyz":[0.383879045673942154,0.503353915181055322,0.761016259228888936],"hpluv":[207.674227909684788,89.8673986045394,76.2746640882933349],"hsluv":[207.674227909684788,82.913556803619926,76.2746640882933349]},"#55ccee":{"lch":[76.8530630513789674,60.6801737900983298,220.368363670310828],"luv":[76.8530630513789674,-46.2319850937693673,-39.3025068600722207],"rgb":[0.333333333333333315,0.8,0.933333333333333348],"xyz":[0.407691225940116864,0.51287878728752534,0.886427075297412159],"hpluv":[220.368363670310828,105.55411204702996,76.8530630513789674],"hsluv":[220.368363670310828,83.7756757275922865,76.8530630513789674]},"#55ccff":{"lch":[77.4805572724897758,70.4908339109135511,229.9629437526429],"luv":[77.4805572724897758,-45.3455492712466395,-53.9697955040126445],"rgb":[0.333333333333333315,0.8,1],"xyz":[0.433862274349948285,0.523347206651458063,1.02426126358919389],"hpluv":[229.9629437526429,126.754412601721029,77.4805572724897758],"hsluv":[229.9629437526429,99.9999999999968878,77.4805572724897758]},"#004400":{"lch":[24.1097877444294397,37.3150672336374782,127.715012949240432],"luv":[24.1097877444294397,-22.8269080205926969,29.5185791133361732],"rgb":[0,0.266666666666666663,0],"xyz":[0.0206703165676731908,0.0413406331353469575,0.00689010552255753684],"hpluv":[127.715012949240432,196.39488290021464,24.1097877444294397],"hsluv":[127.715012949240432,100.000000000002458,24.1097877444294397]},"#004411":{"lch":[24.2402356883412295,33.8624764720942082,131.447767669063751],"luv":[24.2402356883412295,-22.4148262696793807,25.3819399598065552],"rgb":[0,0.266666666666666663,0.0666666666666666657],"xyz":[0.0216819820673103125,0.0417452993352018104,0.0122182104873131692],"hpluv":[131.447767669063751,177.264269230781338,24.2402356883412295],"hsluv":[131.447767669063751,99.9999999999909335,24.2402356883412295]},"#004422":{"lch":[24.4798388415780295,28.4164365287723264,139.862893984056171],"luv":[24.4798388415780295,-21.7244820008415864,18.3177713379345413],"rgb":[0,0.266666666666666663,0.133333333333333331],"xyz":[0.0235573402057873311,0.0424954425905926317,0.0220950966832923652],"hpluv":[139.862893984056171,147.299199898382369,24.4798388415780295],"hsluv":[139.862893984056171,99.9999999999911466,24.4798388415780295]},"#004433":{"lch":[24.8682723444395748,22.2877633761795622,158.664607016269599],"luv":[24.8682723444395748,-20.760308528761005,8.10888316004269427],"rgb":[0,0.266666666666666663,0.2],"xyz":[0.0266450909382450717,0.0437305428835757445,0.0383572505409035119],"hpluv":[158.664607016269599,113.726114076625834,24.8682723444395748],"hsluv":[158.664607016269599,99.9999999999913172,24.8682723444395748]},"#004444":{"lch":[25.4163828994624552,20.1084089871091685,192.17705063006116],"luv":[25.4163828994624552,-19.6559790417892835,-4.24153273022775057],"rgb":[0,0.266666666666666663,0.266666666666666663],"xyz":[0.0311030861824639487,0.0455137409812633176,0.0618360254937901505],"hpluv":[192.17705063006116,100.392967527320792,25.4163828994624552],"hsluv":[192.17705063006116,99.9999999999914166,25.4163828994624552]},"#004455":{"lch":[26.1275223832094383,25.5944772375096541,223.546306053382096],"luv":[26.1275223832094383,-18.5513329588178841,-17.6330743352507042],"rgb":[0,0.266666666666666663,0.333333333333333315],"xyz":[0.0370655002218259477,0.0478987065970081505,0.093238072767764052],"hpluv":[223.546306053382096,124.304646155287358,26.1275223832094383],"hsluv":[223.546306053382096,99.999999999991644,26.1275223832094383]},"#004466":{"lch":[26.9988561724938734,35.8050932952910514,240.647496291889979],"luv":[26.9988561724938734,-17.5509899640931621,-31.2084516944496499],"rgb":[0,0.266666666666666663,0.4],"xyz":[0.0446504959953341191,0.050932704906411462,0.133185717174908],"hpluv":[240.647496291889979,168.282428552664811,26.9988561724938734],"hsluv":[240.647496291889979,99.9999999999920135,26.9988561724938734]},"#004477":{"lch":[28.0227048150185141,47.4927479988473422,249.396343090395135],"luv":[28.0227048150185141,-16.7127641209025413,-44.4549730392572684],"rgb":[0,0.266666666666666663,0.466666666666666674],"xyz":[0.0539645090155360385,0.0546583101144922784,0.182239519081305923],"hpluv":[249.396343090395135,215.05848085050232,28.0227048150185141],"hsluv":[249.396343090395135,99.9999999999921698,28.0227048150185141]},"#004488":{"lch":[29.1879465441319326,59.3592998069098,254.306666373838311],"luv":[29.1879465441319326,-16.0560040952153962,-57.1465765034181956],"rgb":[0,0.266666666666666663,0.533333333333333326],"xyz":[0.0651049261174798666,0.0591144769552698762,0.24091238248487809],"hpluv":[254.306666373838311,258.06229412425995,29.1879465441319326],"hsluv":[254.306666373838311,99.9999999999923,29.1879465441319326]},"#004499":{"lch":[30.4813623757938217,70.9684349502494,257.321762040288718],"luv":[30.4813623757938217,-15.5758442205369825,-69.2380808233832141],"rgb":[0,0.266666666666666663,0.6],"xyz":[0.07816189022655258,0.0643372625988990338,0.309679060125996],"hpluv":[257.321762040288718,295.440602563868879,30.4813623757938217],"hsluv":[257.321762040288718,99.9999999999926672,30.4813623757938217]},"#0044aa":{"lch":[31.8888011745219231,82.2033012029853,259.305022310013101],"luv":[31.8888011745219231,-15.2553283345918977,-80.7753532092093138],"rgb":[0,0.266666666666666663,0.66666666666666663],"xyz":[0.0932195831918051221,0.0703603397850001422,0.388982909742994598],"hpluv":[259.305022310013101,327.107417663034141,31.8888011745219231],"hsluv":[259.305022310013101,99.9999999999925109,31.8888011745219231]},"#0044bb":{"lch":[33.3960915948532602,93.0667571364503,260.679203518012741],"luv":[33.3960915948532602,-15.0732787327803415,-91.8379962332527],"rgb":[0,0.266666666666666663,0.733333333333333282],"xyz":[0.110357175299141769,0.0772153766279349,0.479240894841636345],"hpluv":[260.679203518012741,353.621176249907,33.3960915948532602],"hsluv":[260.679203518012741,99.9999999999929656,33.3960915948532602]},"#0044cc":{"lch":[34.9896851087579108,103.60206818965716,261.670396128603272],"luv":[34.9896851087579108,-15.0085679377548828,-102.509177255659253],"rgb":[0,0.266666666666666663,0.8],"xyz":[0.129649550742863495,0.0849323268054237,0.5808474055119065],"hpluv":[261.670396128603272,375.722944942957042,34.9896851087579108],"hsluv":[261.670396128603272,99.999999999992923,34.9896851087579108]},"#0044dd":{"lch":[36.6570567010139499,113.860579159150092,262.408492682931296],"luv":[36.6570567010139499,-15.0420602661110987,-112.862606338006245],"rgb":[0,0.266666666666666663,0.866666666666666696],"xyz":[0.151167876293497039,0.0935396570256772364,0.694177253411912498],"hpluv":[262.408492682931296,394.144185167595538,36.6570567010139499],"hsluv":[262.408492682931296,99.9999999999929088,36.6570567010139499]},"#0044ee":{"lch":[38.386911506645724,123.889384104134805,262.972536787865295],"luv":[38.386911506645724,-15.1572566165017264,-122.958680318078251],"rgb":[0,0.266666666666666663,0.933333333333333348],"xyz":[0.174980056559671776,0.103064529132147253,0.819588069480435721],"hpluv":[262.972536787865295,409.534269399062566,38.386911506645724],"hsluv":[262.972536787865295,99.9999999999931,38.386911506645724]},"#0044ff":{"lch":[40.1692504091911928,133.727629508879147,263.412926975584469],"luv":[40.1692504091911928,-15.3403008413028115,-132.844849595919101],"rgb":[0,0.266666666666666663,1],"xyz":[0.201151104969503169,0.113532948496079963,0.957422257772217566],"hpluv":[263.412926975584469,422.441664595501038,40.1692504091911928],"hsluv":[263.412926975584469,99.9999999999994174,40.1692504091911928]},"#55dd00":{"lch":[78.2526895057908121,112.425836873112019,123.034721453117925],"luv":[78.2526895057908121,-61.2886270790004488,94.2511166373683267],"rgb":[0.333333333333333315,0.866666666666666696,0],"xyz":[0.296015476495293473,0.536422872385076577,0.0879404415219252333],"hpluv":[123.034721453117925,210.800433631405241,78.2526895057908121],"hsluv":[123.034721453117925,100.000000000002288,78.2526895057908121]},"#55dd11":{"lch":[78.2763843013059102,111.485784004679431,123.297526334296066],"luv":[78.2763843013059102,-61.2042162992655108,93.1832814529020368],"rgb":[0.333333333333333315,0.866666666666666696,0.0666666666666666657],"xyz":[0.297027141994930577,0.536827538584931485,0.09326854648668087],"hpluv":[123.297526334296066,209.310421322213443,78.2763843013059102],"hsluv":[123.297526334296066,98.7516598856555561,78.2763843013059102]},"#55dd22":{"lch":[78.3202766586626353,109.761570808260174,123.793166282380056],"luv":[78.3202766586626353,-61.0490014413279738,91.2174426812846235],"rgb":[0.333333333333333315,0.866666666666666696,0.133333333333333331],"xyz":[0.298902500133407634,0.537577681840322286,0.103145432682660063],"hpluv":[123.793166282380056,206.571995072092733,78.3202766586626353],"hsluv":[123.793166282380056,96.4551350157602201,78.3202766586626353]},"#55dd33":{"lch":[78.3924559312840898,106.97461234521991,124.633900466047606],"luv":[78.3924559312840898,-60.7969536029841819,88.018737317724927],"rgb":[0.333333333333333315,0.866666666666666696,0.2],"xyz":[0.30199025086586534,0.538812782133305412,0.119407586540271199],"hpluv":[124.633900466047606,202.130538056106332,78.3924559312840898],"hsluv":[124.633900466047606,92.7228817840519355,78.3924559312840898]},"#55dd44":{"lch":[78.4964717161501255,103.064578059178857,125.904361390923313],"luv":[78.4964717161501255,-60.4405744101571756,83.4819993500804],"rgb":[0.333333333333333315,0.866666666666666696,0.266666666666666663],"xyz":[0.306448246110084255,0.540595980230993,0.142886361493157837],"hpluv":[125.904361390923313,195.867385876976442,78.4964717161501255],"hsluv":[125.904361390923313,87.4391970363123221,78.4964717161501255]},"#55dd55":{"lch":[78.635232286968062,98.0447483954765175,127.715012949239977],"luv":[78.635232286968062,-59.9773394353739,77.559599291037074],"rgb":[0.333333333333333315,0.866666666666666696,0.333333333333333315],"xyz":[0.31241066014944624,0.542980945846737728,0.174288408767131753],"hpluv":[127.715012949239977,187.771435495127037,78.635232286968062],"hsluv":[127.715012949239977,80.5594181605674891,78.635232286968062]},"#55dd66":{"lch":[78.8111684825228451,92.0067823672703469,130.218539636235505],"luv":[78.8111684825228451,-59.4092211255214551,70.2551951590567],"rgb":[0.333333333333333315,0.866666666666666696,0.4],"xyz":[0.319995655922954425,0.546014944156141,0.214236053174275715],"hpluv":[130.218539636235505,177.951388767985407,78.8111684825228451],"hsluv":[130.218539636235505,80.9267337864342693,78.8111684825228451]},"#55dd77":{"lch":[79.0263204832261863,85.1319563310668315,133.631202536406704],"luv":[79.0263204832261863,-58.7422260542947043,61.618186170487121],"rgb":[0.333333333333333315,0.866666666666666696,0.466666666666666674],"xyz":[0.329309668943156331,0.549740549364221898,0.263289855080673596],"hpluv":[133.631202536406704,166.66460441184762,79.0263204832261863],"hsluv":[133.631202536406704,81.3592233632428,79.0263204832261863]},"#55dd88":{"lch":[79.2823892178289,77.7115996221609322,138.259418470179128],"luv":[79.2823892178289,-57.9858175415186921,51.7371982221375],"rgb":[0.333333333333333315,0.866666666666666696,0.533333333333333326],"xyz":[0.340450086045100131,0.55419671620499944,0.321962718484245791],"hpluv":[138.259418470179128,154.371102046011828,79.2823892178289],"hsluv":[138.259418470179128,81.8514411788724,79.2823892178289]},"#55dd99":{"lch":[79.5807696492298504,70.1818875082800133,144.522564094970761],"luv":[79.5807696492298504,-57.1522092721799737,40.7323251181885624],"rgb":[0.333333333333333315,0.866666666666666696,0.6],"xyz":[0.353507050154172831,0.559419501848628653,0.390729396125363726],"hpluv":[144.522564094970761,141.828030979619143,79.5807696492298504],"hsluv":[144.522564094970761,82.3962440946128538,79.5807696492298504]},"#55ddaa":{"lch":[79.9225742847085,63.1747442044720913,152.933070337002903],"luv":[79.9225742847085,-56.2555676549498145,28.7464678372812266],"rgb":[0.333333333333333315,0.866666666666666696,0.66666666666666663],"xyz":[0.368564743119425386,0.56544257903472972,0.470033245742362271],"hpluv":[152.933070337002903,130.236824512138128,79.9225742847085],"hsluv":[152.933070337002903,82.9852754707380313,79.9225742847085]},"#55ddbb":{"lch":[80.3086513857730466,57.5612329714098649,163.927126105934775],"luv":[80.3086513857730466,-55.3111838467604926,15.9363886328987263],"rgb":[0.333333333333333315,0.866666666666666696,0.733333333333333282],"xyz":[0.385702335226762061,0.572297615877664478,0.560291230841004073],"hpluv":[163.927126105934775,121.406580229851471,80.3086513857730466],"hsluv":[163.927126105934775,83.6094665313934,80.3086513857730466]},"#55ddcc":{"lch":[80.7396004409482657,54.3905283694756534,177.403333860877041],"luv":[80.7396004409482657,-54.3346805898883076,2.46415533308082235],"rgb":[0.333333333333333315,0.866666666666666696,0.8],"xyz":[0.40499471067048376,0.580014566055153336,0.661897741511274229],"hpluv":[177.403333860877041,117.73427745544555,80.7396004409482657],"hsluv":[177.403333860877041,84.2595162876674664,80.7396004409482657]},"#55dddd":{"lch":[81.2157864208401605,54.5690893966631236,192.177050630061103],"luv":[81.2157864208401605,-53.3413100060750764,-11.5104371948595805],"rgb":[0.333333333333333315,0.866666666666666696,0.866666666666666696],"xyz":[0.426513036221117359,0.588621896275406842,0.775227589411280227],"hpluv":[192.177050630061103,121.625211000731653,81.2157864208401605],"hsluv":[192.177050630061103,84.9263164151063847,81.2157864208401605]},"#55ddee":{"lch":[81.73735371635685,58.3741450028570412,206.269517439458],"luv":[81.73735371635685,-52.3453816136692609,-25.8360567528002605],"rgb":[0.333333333333333315,0.866666666666666696,0.933333333333333348],"xyz":[0.450325216487292068,0.598146768381876859,0.90063840547980345],"hpluv":[206.269517439458,134.436687270459231,81.73735371635685],"hsluv":[206.269517439458,85.6012975649288421,81.73735371635685]},"#55ddff":{"lch":[82.3042402700550753,65.3293790133507599,218.171205050819623],"luv":[82.3042402700550753,-51.3598401525014268,-40.374429801293],"rgb":[0.333333333333333315,0.866666666666666696,1],"xyz":[0.476496264897123489,0.608615187745809583,1.0384725937715853],"hpluv":[218.171205050819623,156.046773818868189,82.3042402700550753],"hsluv":[218.171205050819623,99.9999999999958078,82.3042402700550753]},"#005500":{"lch":[30.6325595368381371,47.4104554868850059,127.715012949240474],"luv":[30.6325595368381371,-29.0026036892131067,37.5046699588244152],"rgb":[0,0.333333333333333315,0],"xyz":[0.0324835732820191528,0.0649671465640392215,0.0108278577606727468],"hpluv":[127.715012949240474,196.39488290021464,30.6325595368381371],"hsluv":[127.715012949240474,100.000000000002331,30.6325595368381371]},"#005511":{"lch":[30.7291805540017933,44.5531719728198325,130.030983014983661],"luv":[30.7291805540017933,-28.6566785608310113,34.1142185415534129],"rgb":[0,0.333333333333333315,0.0666666666666666657],"xyz":[0.033495238781656278,0.0653718127638940744,0.01615596272542838],"hpluv":[130.030983014983661,183.978458821492183,30.7291805540017933],"hsluv":[130.030983014983661,99.9999999999909335,30.7291805540017933]},"#005522":{"lch":[30.9072407208055395,39.7502752239143149,134.89425658266407],"luv":[30.9072407208055395,-28.0557665948475297,28.1595159964153758],"rgb":[0,0.333333333333333315,0.133333333333333331],"xyz":[0.0353705969201332932,0.0661219560192848888,0.0260328489214075726],"hpluv":[134.89425658266407,163.199653312489744,30.9072407208055395],"hsluv":[134.89425658266407,99.9999999999909903,30.9072407208055395]},"#005533":{"lch":[31.1975029455576802,33.2574057268159,144.773587953954916],"luv":[31.1975029455576802,-27.1672793055155033,19.1831689460880241],"rgb":[0,0.333333333333333315,0.2],"xyz":[0.0384583476525910337,0.067357056312268,0.0422950027790187227],"hpluv":[144.773587953954916,135.271984326190278,31.1975029455576802],"hsluv":[144.773587953954916,99.9999999999912177,31.1975029455576802]},"#005544":{"lch":[31.6103799108948778,27.1932751339722678,163.464109831123295],"luv":[31.6103799108948778,-26.0686058468900157,7.73963834500076331],"rgb":[0,0.333333333333333315,0.266666666666666663],"xyz":[0.0429163428968099142,0.0691402544099555816,0.0657737777319053613],"hpluv":[163.464109831123295,109.16191048912313,31.6103799108948778],"hsluv":[163.464109831123295,99.999999999991374,31.6103799108948778]},"#005555":{"lch":[32.1516370434520482,25.4370682812028797,192.17705063006116],"luv":[32.1516370434520482,-24.8647459548099441,-5.36552433088697445],"rgb":[0,0.333333333333333315,0.333333333333333315],"xyz":[0.0488787569361719063,0.0715252200257004145,0.0971758250058792628],"hpluv":[192.17705063006116,100.392967527320877,32.1516370434520482],"hsluv":[192.17705063006116,99.9999999999915,32.1516370434520482]},"#005566":{"lch":[32.8230722751799036,30.545644410021449,219.238547792689275],"luv":[32.8230722751799036,-23.6581848019048806,-19.3216636007977201],"rgb":[0,0.333333333333333315,0.4],"xyz":[0.0564637527096800845,0.074559218335103733,0.137123469413023225],"hpluv":[219.238547792689275,118.088984839520307,32.8230722751799036],"hsluv":[219.238547792689275,99.9999999999916298,32.8230722751799036]},"#005577":{"lch":[33.6230950493472065,40.3511971197610322,236.060106868306946],"luv":[33.6230950493472065,-22.5289967279924532,-33.4763112577822142],"rgb":[0,0.333333333333333315,0.466666666666666674],"xyz":[0.065777765729882,0.0782848235431845424,0.186177271319421134],"hpluv":[236.060106868306946,152.285327594300298,33.6230950493472065],"hsluv":[236.060106868306946,99.9999999999918,33.6230950493472065]},"#005588":{"lch":[34.5473308406039266,52.0529464564925703,245.569923252468897],"luv":[34.5473308406039266,-21.5281838547339461,-47.3924733973576764],"rgb":[0,0.333333333333333315,0.533333333333333326],"xyz":[0.076918182831825832,0.0827409903839621402,0.244850134722993301],"hpluv":[245.569923252468897,191.192188881903292,34.5473308406039266],"hsluv":[245.569923252468897,99.9999999999919709,34.5473308406039266]},"#005599":{"lch":[35.5892574919693772,64.2489447401961655,251.22324643469841],"luv":[35.5892574919693772,-20.6805523421639172,-60.8296116628390067],"rgb":[0,0.333333333333333315,0.6],"xyz":[0.0899751469408985316,0.0879637760275913,0.313616812364111208],"hpluv":[251.22324643469841,229.079590546614583,35.5892574919693772],"hsluv":[251.22324643469841,99.9999999999922125,35.5892574919693772]},"#0055aa":{"lch":[36.7408379507026,76.3552968047486189,254.821646708521541],"luv":[36.7408379507026,-19.9916927982920107,-73.6916791042243347],"rgb":[0,0.333333333333333315,0.66666666666666663],"xyz":[0.105032839906151088,0.0939868532136924,0.392920661981109809],"hpluv":[254.821646708521541,263.711724718685957,36.7408379507026],"hsluv":[254.821646708521541,99.9999999999921556,36.7408379507026]},"#0055bb":{"lch":[37.993106438468665,88.146943006458784,257.249085911334646],"luv":[37.993106438468665,-19.4551758320548949,-85.9731335635018],"rgb":[0,0.333333333333333315,0.733333333333333282],"xyz":[0.122170432013487734,0.100841890056627165,0.483178647079751555],"hpluv":[257.249085911334646,294.402692429224658,37.993106438468665],"hsluv":[257.249085911334646,99.9999999999924114,37.993106438468665]},"#0055cc":{"lch":[39.3366742314503384,99.5579220492412,258.963845190076711],"luv":[39.3366742314503384,-19.0582121518786707,-97.7167559446012888],"rgb":[0,0.333333333333333315,0.8],"xyz":[0.141462807457209461,0.108558840234115966,0.584785157750021711],"hpluv":[258.963845190076711,321.157087606315883,39.3366742314503384],"hsluv":[258.963845190076711,99.9999999999926,39.3366742314503384]},"#0055dd":{"lch":[40.7621365800243538,110.592821589198408,260.220233587680809],"luv":[40.7621365800243538,-18.7854624460211568,-108.985680654613518],"rgb":[0,0.333333333333333315,0.866666666666666696],"xyz":[0.162981133007843,0.1171661704543695,0.698115005650027709],"hpluv":[260.220233587680809,344.278042660470817,40.7621365800243538],"hsluv":[260.220233587680809,99.9999999999926672,40.7621365800243538]},"#0055ee":{"lch":[42.2603772648371105,121.285075365136905,261.168248695532611],"luv":[42.2603772648371105,-18.6213165580406681,-119.847052846418293],"rgb":[0,0.333333333333333315,0.933333333333333348],"xyz":[0.186793313274017742,0.126691042560839517,0.823525821718550932],"hpluv":[261.168248695532611,364.177675198016914,42.2603772648371105],"hsluv":[261.168248695532611,99.9999999999924256,42.2603772648371105]},"#0055ff":{"lch":[43.8227784910393,131.676969611306021,261.90102950371454],"luv":[43.8227784910393,-18.5511048350842884,-130.363648443170376],"rgb":[0,0.333333333333333315,1],"xyz":[0.212964361683849135,0.137159461924772241,0.961360010010332777],"hpluv":[261.90102950371454,381.28457852045068,43.8227784910393],"hsluv":[261.90102950371454,99.9999999999993321,43.8227784910393]},"#55ee00":{"lch":[83.4834241678481277,121.26988118033438,123.77813801339137],"luv":[83.4834241678481277,-67.423446821455,100.799121524975831],"rgb":[0.333333333333333315,0.933333333333333348,0],"xyz":[0.343194252835808289,0.630780425066107542,0.103666700302096418],"hpluv":[123.77813801339137,313.542875178701877,83.4834241678481277],"hsluv":[123.77813801339137,100.000000000002402,83.4834241678481277]},"#55ee11":{"lch":[83.5046935730824487,120.419265504422668,124.002811201886018],"luv":[83.5046935730824487,-67.3424968648776456,99.8287915414615412],"rgb":[0.333333333333333315,0.933333333333333348,0.0666666666666666657],"xyz":[0.344205918335445393,0.63118509126596245,0.108994805266852055],"hpluv":[124.002811201886018,311.80236567126093,83.5046935730824487],"hsluv":[124.002811201886018,98.9375412624106616,83.5046935730824487]},"#55ee22":{"lch":[83.5440973470955868,118.856748008926118,124.425313598414533],"luv":[83.5440973470955868,-67.1934622190367463,98.0406302625408728],"rgb":[0.333333333333333315,0.933333333333333348,0.133333333333333331],"xyz":[0.34608127647392245,0.631935234521353251,0.118871691462831247],"hpluv":[124.425313598414533,308.59848358059196,83.5440973470955868],"hsluv":[124.425313598414533,96.9807587800033133,83.5440973470955868]},"#55ee33":{"lch":[83.6089072227085524,116.32446068797897,125.138397832270286],"luv":[83.6089072227085524,-66.950941309724243,95.1259775880964469],"rgb":[0.333333333333333315,0.933333333333333348,0.2],"xyz":[0.349169027206380156,0.633170334814336377,0.135133845320442397],"hpluv":[125.138397832270286,303.387603747434184,83.6089072227085524],"hsluv":[125.138397832270286,93.7945051225822084,83.6089072227085524]},"#55ee44":{"lch":[83.7023291233000748,112.756808619009803,126.207644663357115],"luv":[83.7023291233000748,-66.6069499756988535,90.9813832873448547],"rgb":[0.333333333333333315,0.933333333333333348,0.266666666666666663],"xyz":[0.353627022450599071,0.634953532912023944,0.158612620273329036],"hpluv":[126.207644663357115,296.007020538140409,83.7023291233000748],"hsluv":[126.207644663357115,89.2707337544585,83.7023291233000748]},"#55ee55":{"lch":[83.8270046653184,108.148092962556504,127.715012949240077],"luv":[83.8270046653184,-66.1579022543843,85.5519840841642747],"rgb":[0.333333333333333315,0.933333333333333348,0.333333333333333315],"xyz":[0.359589436489961056,0.637338498527768693,0.190014667547302951],"hpluv":[127.715012949240077,286.404562223907249,83.8270046653184],"hsluv":[127.715012949240077,83.3573838846113091,83.8270046653184]},"#55ee66":{"lch":[83.985160091985378,102.554744038676162,129.769393513035965],"luv":[83.985160091985378,-65.6041880698479645,78.8261760618539853],"rgb":[0.333333333333333315,0.933333333333333348,0.4],"xyz":[0.367174432263469241,0.640372496837172,0.229962311954446885],"hpluv":[129.769393513035965,274.647728218817576,83.985160091985378],"hsluv":[129.769393513035965,83.6273111034757477,83.985160091985378]},"#55ee77":{"lch":[84.1786855608653752,96.1019099790829756,132.519661951802362],"luv":[84.1786855608653752,-64.9498200787083,70.8314758661090451],"rgb":[0.333333333333333315,0.933333333333333348,0.466666666666666674],"xyz":[0.376488445283671147,0.644098102045252863,0.279016113860844794],"hpluv":[132.519661951802362,260.948457539577589,84.1786855608653752],"hsluv":[132.519661951802362,83.9470254314832687,84.1786855608653752]},"#55ee88":{"lch":[84.4091822183787741,88.9952087097784,136.170997575445568],"luv":[84.4091822183787741,-64.2020140446184371,61.6299323860706],"rgb":[0.333333333333333315,0.933333333333333348,0.533333333333333326],"xyz":[0.387628862385614947,0.648554268886030405,0.337688977264417],"hpluv":[136.170997575445568,245.709397001158351,84.4091822183787741],"hsluv":[136.170997575445568,84.3134084109568533,84.4091822183787741]},"#55ee99":{"lch":[84.6779925165317877,81.540352796223317,141.002136712429774],"luv":[84.6779925165317877,-63.3706695007570531,51.3126434824633151],"rgb":[0.333333333333333315,0.933333333333333348,0.6],"xyz":[0.400685826494687647,0.653777054529659618,0.406455654905534869],"hpluv":[141.002136712429774,229.604367075154897,84.6779925165317877],"hsluv":[141.002136712429774,84.7220894550445394,84.6779925165317877]},"#55eeaa":{"lch":[84.9862212486181363,74.1734332109310373,147.37159021859884],"luv":[84.9862212486181363,-62.4677637576075426,39.9934580327855755],"rgb":[0.333333333333333315,0.933333333333333348,0.66666666666666663],"xyz":[0.415743519459940203,0.659800131715760685,0.48575950452253347],"hpluv":[147.37159021859884,213.709694911287,84.9862212486181363],"hsluv":[147.37159021859884,85.1677250765186358,84.9862212486181363]},"#55eebb":{"lch":[85.334751323756052,67.4984157699475418,155.676120933413],"luv":[85.334751323756052,-61.5066955643592337,27.8022037293077737],"rgb":[0.333333333333333315,0.933333333333333348,0.733333333333333282],"xyz":[0.432881111567276877,0.666655168558695443,0.576017489621175272],"hpluv":[155.676120933413,199.690784145783283,85.334751323756052],"hsluv":[155.676120933413,85.6443005177139298,85.334751323756052]},"#55eecc":{"lch":[85.7242566025865784,62.3040769944455,166.184583472908372],"luv":[85.7242566025865784,-60.5016239571924643,14.8778865660505755],"rgb":[0.333333333333333315,0.933333333333333348,0.8],"xyz":[0.452173487010998576,0.674372118736184301,0.677624000291445427],"hpluv":[166.184583472908372,189.979166061651426,85.7242566025865784],"hsluv":[166.184583472908372,86.1454332210543186,85.7242566025865784]},"#55eedd":{"lch":[86.1552131978466349,59.4824491826881427,178.687660418725557],"luv":[86.1552131978466349,-59.4668469392298462,1.36230535390821395],"rgb":[0.333333333333333315,0.933333333333333348,0.866666666666666696],"xyz":[0.473691812561632175,0.682979448956437807,0.790953848191451425],"hpluv":[178.687660418725557,187.703134777137279,86.1552131978466349],"hsluv":[178.687660418725557,86.6646578889921,86.1552131978466349]},"#55eeee":{"lch":[86.6279101052896578,59.7608483004272202,192.177050630061245],"luv":[86.6279101052896578,-58.4162567245265265,-12.6055519466972967],"rgb":[0.333333333333333315,0.933333333333333348,0.933333333333333348],"xyz":[0.497503992827806885,0.692504321062907824,0.916364664259974648],"hpluv":[192.177050630061245,196.025490067494644,86.6279101052896578],"hsluv":[192.177050630061245,87.195676441965972,86.6279101052896578]},"#55eeff":{"lch":[87.1424596935915901,63.3545065705612274,205.119112492248092],"luv":[87.1424596935915901,-57.3628964007582169,-26.8940814923128677],"rgb":[0.333333333333333315,0.933333333333333348,1],"xyz":[0.523675041237638306,0.702972740426840548,1.05419885255175649],"hpluv":[205.119112492248092,217.06231600799947,87.1424596935915901],"hsluv":[205.119112492248092,99.9999999999933,87.1424596935915901]},"#006600":{"lch":[36.9339903888407548,57.1632711650289735,127.71501294924046],"luv":[36.9339903888407548,-34.9687359497521086,45.2197642227726249],"rgb":[0,0.4,0],"xyz":[0.0475116309878656218,0.0950232619757325619,0.0158372103292880942],"hpluv":[127.71501294924046,196.394882900214554,36.9339903888407548],"hsluv":[127.71501294924046,100.000000000002331,36.9339903888407548]},"#006611":{"lch":[37.0090255636121412,54.7765813256580216,129.276595687178855],"luv":[37.0090255636121412,-34.6771211058740789,42.4024897091546933],"rgb":[0,0.4,0.0666666666666666657],"xyz":[0.04852329648750274,0.0954279281755874148,0.0211653152940437239],"hpluv":[129.276595687178855,187.813410896691579,37.0090255636121412],"hsluv":[129.276595687178855,99.9999999999908908,37.0090255636121412]},"#006622":{"lch":[37.1475616040544949,50.6324758020482761,132.428423847637788],"luv":[37.1475616040544949,-34.160143827310165,37.3728802682170453],"rgb":[0,0.4,0.133333333333333331],"xyz":[0.0503986546259797621,0.0961780714309782292,0.0310422014900229234],"hpluv":[132.428423847637788,172.957013965329963,37.1475616040544949],"hsluv":[132.428423847637788,99.9999999999909619,37.1475616040544949]},"#006633":{"lch":[37.3740982281225911,44.601943170857588,138.432874640413417],"luv":[37.3740982281225911,-33.3702331720845464,29.5932572160807972],"rgb":[0,0.4,0.2],"xyz":[0.0534864053584375,0.0974131717239613421,0.0473043553476340667],"hpluv":[138.432874640413417,151.43364776149042,37.3740982281225911],"hsluv":[138.432874640413417,99.9999999999910187,37.3740982281225911]},"#006644":{"lch":[37.6978110334583292,37.6830106217376226,149.139540405640531],"luv":[37.6978110334583292,-32.3478161181420845,19.3294615006434647],"rgb":[0,0.4,0.266666666666666663],"xyz":[0.0579444006026563832,0.099196369821648922,0.0707831303005207],"hpluv":[149.139540405640531,126.843666215367492,37.6978110334583292],"hsluv":[149.139540405640531,99.9999999999911893,37.6978110334583292]},"#006655":{"lch":[38.1247572916394191,31.9621551107412678,167.158861879927684],"luv":[38.1247572916394191,-31.1627826377188839,7.10354401671241],"rgb":[0,0.4,0.333333333333333315],"xyz":[0.0639068146420183752,0.101581335437393755,0.102185177574494607],"hpluv":[167.158861879927684,106.382034992292617,38.1247572916394191],"hsluv":[167.158861879927684,99.9999999999912461,38.1247572916394191]},"#006666":{"lch":[38.6583399620500714,30.584907136256998,192.177050630061132],"luv":[38.6583399620500714,-29.8967608054288689,-6.45137488264605441],"rgb":[0,0.4,0.4],"xyz":[0.0714918104155265466,0.104615333746797073,0.142132821981638569],"hpluv":[192.177050630061132,100.392967527320849,38.6583399620500714],"hsluv":[192.177050630061132,99.9999999999914877,38.6583399620500714]},"#006677":{"lch":[39.2996251720959648,35.3400629634721852,215.899751113488037],"luv":[39.2996251720959648,-28.6270125920824867,-20.7223116547099835],"rgb":[0,0.4,0.466666666666666674],"xyz":[0.080805823435728466,0.108340938954877883,0.191186623888036478],"hpluv":[215.899751113488037,114.108563264217921,39.2996251720959648],"hsluv":[215.899751113488037,99.999999999991644,39.2996251720959648]},"#006688":{"lch":[40.0476371065618721,44.619030030948764,232.088426656893603],"luv":[40.0476371065618721,-27.4159210327312195,-35.2026293738089109],"rgb":[0,0.4,0.533333333333333326],"xyz":[0.0919462405376723,0.112797105795655481,0.249859487291608645],"hpluv":[232.088426656893603,141.378234692038774,40.0476371065618721],"hsluv":[232.088426656893603,99.9999999999918145,40.0476371065618721]},"#006699":{"lch":[40.8996671875350728,56.0796471869528546,242.024131169727298],"luv":[40.8996671875350728,-26.3069429553173038,-49.5264735364712863],"rgb":[0,0.4,0.6],"xyz":[0.105003204646745008,0.118019891439284638,0.318626164932726552],"hpluv":[242.024131169727298,173.990215160848891,40.8996671875350728],"hsluv":[242.024131169727298,99.9999999999919,40.8996671875350728]},"#0066aa":{"lch":[41.8515997707465104,68.3303466488807345,248.245335088520562],"luv":[41.8515997707465104,-25.3254853434547229,-63.4638169768779861],"rgb":[0,0.4,0.66666666666666663],"xyz":[0.12006089761199755,0.124042968625385747,0.397930014549725153],"hpluv":[248.245335088520562,207.176688473106537,41.8515997707465104],"hsluv":[248.245335088520562,99.9999999999921,41.8515997707465104]},"#0066bb":{"lch":[42.8982420202673396,80.6980154219041452,252.339105133311591],"luv":[42.8982420202673396,-24.4823887435570384,-76.8946183711398],"rgb":[0,0.4,0.733333333333333282],"xyz":[0.137198489719334182,0.130898005468320505,0.488187999648366899],"hpluv":[252.339105133311591,238.705643004687346,42.8982420202673396],"hsluv":[252.339105133311591,99.9999999999922125,42.8982420202673396]},"#0066cc":{"lch":[44.0336413015701211,92.8728169416488356,255.165448618736946],"luv":[44.0336413015701211,-23.7781103155697018,-89.7772888680517696],"rgb":[0,0.4,0.8],"xyz":[0.156490865163055937,0.138614955645809307,0.589794510318637],"hpluv":[255.165448618736946,267.63526922347819,44.0336413015701211],"hsluv":[255.165448618736946,99.9999999999922835,44.0336413015701211]},"#0066dd":{"lch":[45.2513748624169807,104.723900430114114,257.197154574648096],"luv":[45.2513748624169807,-23.2064943358636171,-102.120291528843495],"rgb":[0,0.4,0.866666666666666696],"xyz":[0.17800919071368948,0.147222285866062841,0.703124358218643],"hpluv":[257.197154574648096,293.665789717253858,45.2513748624169807],"hsluv":[257.197154574648096,99.9999999999923119,45.2513748624169807]},"#0066ee":{"lch":[46.5448008930790422,116.210429262859975,258.70668283343889],"luv":[46.5448008930790422,-22.7576936505684415,-113.960305585607557],"rgb":[0,0.4,0.933333333333333348],"xyz":[0.201821370979864217,0.156747157972532858,0.828535174287166276],"hpluv":[258.70668283343889,316.82048544727013,46.5448008930790422],"hsluv":[258.70668283343889,99.9999999999923119,46.5448008930790422]},"#0066ff":{"lch":[47.9072652547968758,127.336469583599694,259.859032010401279],"luv":[47.9072652547968758,-22.4202120236612075,-125.347160234402949],"rgb":[0,0.4,1],"xyz":[0.227992419389695611,0.167215577336465582,0.966369362578948121],"hpluv":[259.859032010401279,337.280125749862,47.9072652547968758],"hsluv":[259.859032010401279,99.9999999999992326,47.9072652547968758]},"#55ff00":{"lch":[88.6611895097861691,129.940408372856581,124.363532639485271],"luv":[88.6611895097861691,-73.3437881830395213,107.262288168144963],"rgb":[0.333333333333333315,1,0],"xyz":[0.395046625265482121,0.734485169925456649,0.120950824445320529],"hpluv":[124.363532639485271,511.214684976108288,88.6611895097861691],"hsluv":[124.363532639485271,100.000000000002203,88.6611895097861691]},"#55ff11":{"lch":[88.6804070841335488,129.16615931328721,124.557188606571273],"luv":[88.6804070841335488,-73.2667318726085597,106.376137890284312],"rgb":[0.333333333333333315,1,0.0666666666666666657],"xyz":[0.396058290765119225,0.734889836125311557,0.126278929410076152],"hpluv":[124.557188606571273,509.111714190739917,88.6804070841335488],"hsluv":[124.557188606571273,99.999999999991374,88.6804070841335488]},"#55ff22":{"lch":[88.7160126920472862,127.742171235629925,124.920549061750862],"luv":[88.7160126920472862,-73.1247263453711867,104.741762009752222],"rgb":[0.333333333333333315,1,0.133333333333333331],"xyz":[0.397933648903596282,0.735639979380702358,0.136155815606055358],"hpluv":[124.920549061750862,505.235489858807625,88.7160126920472862],"hsluv":[124.920549061750862,99.9999999999912461,88.7160126920472862]},"#55ff33":{"lch":[88.7745841250638819,125.429409451765778,125.531442964179078],"luv":[88.7745841250638819,-72.893256299655377,102.074041467218606],"rgb":[0.333333333333333315,1,0.2],"xyz":[0.401021399636054,0.736875079673685485,0.152417969463666508],"hpluv":[125.531442964179078,498.916518871762833,88.7745841250638819],"hsluv":[125.531442964179078,99.9999999999915445,88.7745841250638819]},"#55ff44":{"lch":[88.8590323294941271,122.159967165607114,126.442013329478428],"luv":[88.8590323294941271,-72.5641116581323189,98.2726171279075658],"rgb":[0.333333333333333315,1,0.266666666666666663],"xyz":[0.405479394880272903,0.738658277771373,0.175896744416553147],"hpluv":[126.442013329478428,489.934204596741552,88.8590323294941271],"hsluv":[126.442013329478428,99.9999999999914735,88.8590323294941271]},"#55ff55":{"lch":[88.9717666926620154,117.915518658848484,127.715012949240119],"luv":[88.9717666926620154,-72.1329719647303,93.2786357968462],"rgb":[0.333333333333333315,1,0.333333333333333315],"xyz":[0.411441808919634888,0.7410432433871178,0.207298791690527062],"hpluv":[127.715012949240119,478.187207442594797,88.9717666926620154],"hsluv":[127.715012949240119,99.9999999999912461,88.9717666926620154]},"#55ff66":{"lch":[89.1148309932425,112.728028648536309,129.430986513959965],"luv":[89.1148309932425,-71.5990188667543919,87.0700232014633713],"rgb":[0.333333333333333315,1,0.4],"xyz":[0.419026804693143073,0.744077241696521119,0.247246436097671],"hpluv":[129.430986513959965,463.701047487447568,89.1148309932425],"hsluv":[129.430986513959965,99.999999999991374,89.1148309932425]},"#55ff77":{"lch":[89.2899761450384233,106.6837193332601,131.696695826109391],"luv":[89.2899761450384233,-70.9646547782272705,79.6582308552282825],"rgb":[0.333333333333333315,1,0.466666666666666674],"xyz":[0.428340817713345,0.747802846904602,0.296300238004068905],"hpluv":[131.696695826109391,446.653165807945641,89.2899761450384233],"hsluv":[131.696695826109391,99.9999999999911466,89.2899761450384233]},"#55ff88":{"lch":[89.4987035327786344,99.9302046144725722,134.655503696120093],"luv":[89.4987035327786344,-70.2351927280585784,71.0849034376696807],"rgb":[0.333333333333333315,1,0.533333333333333326],"xyz":[0.439481234815288779,0.752259013745379512,0.354973101407641101],"hpluv":[134.655503696120093,427.420708471833962,89.4987035327786344],"hsluv":[134.655503696120093,99.9999999999910472,89.4987035327786344]},"#55ff99":{"lch":[89.7422928839939544,92.6881300553494185,138.499225093055145],"luv":[89.7422928839939544,-69.4184746025382395,61.4179520744067275],"rgb":[0.333333333333333315,1,0.6],"xyz":[0.452538198924361534,0.757481799389008725,0.423739779048759],"hpluv":[138.499225093055145,406.664135605650245,89.7422928839939544],"hsluv":[138.499225093055145,99.9999999999909193,89.7422928839939544]},"#55ffaa":{"lch":[90.021821419032733,85.2692799565717081,143.477548510033301],"luv":[90.021821419032733,-68.524415632830582,50.7469660816416095],"rgb":[0.333333333333333315,1,0.66666666666666663],"xyz":[0.467595891889614035,0.763504876575109792,0.503043628665757581],"hpluv":[143.477548510033301,385.467603776639692,90.021821419032733],"hsluv":[143.477548510033301,99.9999999999908908,90.021821419032733]},"#55ffbb":{"lch":[90.3381779071049635,78.1017696608261929,149.892156464581973],"luv":[90.3381779071049635,-67.5644942943643514,39.178125719584358],"rgb":[0.333333333333333315,1,0.733333333333333282],"xyz":[0.484733483996950709,0.770359913418044551,0.593301613764399383],"hpluv":[149.892156464581973,365.560319764238727,90.3381779071049635],"hsluv":[149.892156464581973,99.9999999999906,90.3381779071049635]},"#55ffcc":{"lch":[90.6920737330737836,71.7555158590460849,158.04408297895796],"luv":[90.6920737330737836,-66.5512174426729217,26.828893251416094],"rgb":[0.333333333333333315,1,0.8],"xyz":[0.504025859440672463,0.778076863595533408,0.694908124434669539],"hpluv":[158.04408297895796,349.620992563925881,90.6920737330737836],"hsluv":[158.04408297895796,99.9999999999905214,90.6920737330737836]},"#55ffdd":{"lch":[91.0840522607878142,66.9403052018893874,168.083008151042208],"luv":[91.0840522607878142,-65.4975936461766,13.8227959213187273],"rgb":[0.333333333333333315,1,0.866666666666666696],"xyz":[0.525544184991306,0.786684193815786914,0.808237972334675536],"hpluv":[168.083008151042208,341.570927955438208,91.0840522607878142],"hsluv":[168.083008151042208,99.9999999999901092,91.0840522607878142]},"#55ffee":{"lch":[91.5144973031429,64.4172738793593,179.746868091755],"luv":[91.5144973031429,-64.4166452130874347,0.284593639433804613],"rgb":[0.333333333333333315,1,0.933333333333333348],"xyz":[0.549356365257480661,0.796209065922256931,0.933648788403198759],"hpluv":[179.746868091755,346.559914030924404,91.5144973031429],"hsluv":[179.746868091755,99.9999999999898108,91.5144973031429]},"#55ffff":{"lch":[91.9836412143362,64.7784688708661918,192.177050630061103],"luv":[91.9836412143362,-63.3209831419883,-13.663935128132529],"rgb":[0.333333333333333315,1,1],"xyz":[0.575527413667312082,0.806677485286189655,1.07148297669498049],"hpluv":[192.177050630061103,370.276433987554753,91.9836412143362],"hsluv":[192.177050630061103,99.9999999999890719,91.9836412143362]},"#007700":{"lch":[43.052730924646589,66.6333343982289534,127.715012949240503],"luv":[43.052730924646589,-40.7618988300426395,52.7111834129681611],"rgb":[0,0.466666666666666674,0],"xyz":[0.0659653690412832505,0.131930738082568333,0.0219884563470937981],"hpluv":[127.715012949240503,196.394882900214441,43.052730924646589],"hsluv":[127.715012949240503,100.000000000002217,43.052730924646589]},"#007711":{"lch":[43.1130460407029,64.6129906803504497,128.830381027920708],"luv":[43.1130460407029,-40.513441406878222,50.333881531534],"rgb":[0,0.466666666666666674,0.0666666666666666657],"xyz":[0.0669770345409203688,0.132335404282423186,0.0273165613118494313],"hpluv":[128.830381027920708,190.173702516526191,43.1130460407029],"hsluv":[128.830381027920708,99.9999999999908908,43.1130460407029]},"#007722":{"lch":[43.2245297597171856,61.038201507507992,131.028383581415682],"luv":[43.2245297597171856,-40.0674788501528809,46.0462721820529381],"rgb":[0,0.466666666666666674,0.133333333333333331],"xyz":[0.0688523926793974,0.133085547537814014,0.0371934475078286239],"hpluv":[131.028383581415682,179.188765673473426,43.2245297597171856],"hsluv":[131.028383581415682,99.9999999999909193,43.2245297597171856]},"#007733":{"lch":[43.4071769639209251,55.6324991773261601,135.049443606961],"luv":[43.4071769639209251,-39.3720497464739694,39.3041558041433419],"rgb":[0,0.466666666666666674,0.2],"xyz":[0.0719401434118551314,0.134320647830797113,0.0534556013654397671],"hpluv":[135.049443606961,162.632131787412106,43.4071769639209251],"hsluv":[135.049443606961,99.9999999999909193,43.4071769639209251]},"#007744":{"lch":[43.6689123670523855,48.8909209361139787,141.845848120172377],"luv":[43.6689123670523855,-38.4454486392046704,30.2038015639029105],"rgb":[0,0.466666666666666674,0.266666666666666663],"xyz":[0.076398138656074,0.136103845928484707,0.0769343763183264],"hpluv":[141.845848120172377,142.067640978907804,43.6689123670523855],"hsluv":[141.845848120172377,99.9999999999910614,43.6689123670523855]},"#007755":{"lch":[44.0154249216106,41.9153980271179,152.953344682219807],"luv":[44.0154249216106,-37.3313854656975224,19.0595973457790286],"rgb":[0,0.466666666666666674,0.333333333333333315],"xyz":[0.082360552695436,0.13848881154422954,0.108336423592300321],"hpluv":[152.953344682219807,120.839250305189026,44.0154249216106],"hsluv":[152.953344682219807,99.9999999999912461,44.0154249216106]},"#007766":{"lch":[44.4505333250062549,36.6388362985735725,170.062665906075836],"luv":[44.4505333250062549,-36.0891470448365865,6.32279929223085357],"rgb":[0,0.466666666666666674,0.4],"xyz":[0.0899455484689441753,0.141522809853632831,0.148284067999444269],"hpluv":[170.062665906075836,104.593337643625588,44.4505333250062549],"hsluv":[170.062665906075836,99.9999999999913314,44.4505333250062549]},"#007777":{"lch":[44.9764013416840669,35.58350047386471,192.17705063006116],"luv":[44.9764013416840669,-34.7828880940388601,-7.50574458738768],"rgb":[0,0.466666666666666674,0.466666666666666674],"xyz":[0.0992595614891461,0.145248415061713654,0.197337869905842178],"hpluv":[192.17705063006116,100.392967527320835,44.9764013416840669],"hsluv":[192.17705063006116,99.9999999999914451,44.9764013416840669]},"#007788":{"lch":[45.5937085159301603,40.0276538709377,213.25546015720218],"luv":[45.5937085159301603,-33.4724811425817,-21.9500815618326577],"rgb":[0,0.466666666666666674,0.533333333333333326],"xyz":[0.110399978591089923,0.149704581902491252,0.256010733309414373],"hpluv":[213.25546015720218,111.402399127386914,45.5937085159301603],"hsluv":[213.25546015720218,99.9999999999916156,45.5937085159301603]},"#007799":{"lch":[46.3018156057360244,48.7595612734022907,228.659125647543163],"luv":[46.3018156057360244,-32.2075160625452597,-36.6083422822662357],"rgb":[0,0.466666666666666674,0.6],"xyz":[0.123456942700162636,0.154927367546120409,0.324777410950532253],"hpluv":[228.659125647543163,133.62911578541167,46.3018156057360244],"hsluv":[228.659125647543163,99.9999999999917577,46.3018156057360244]},"#0077aa":{"lch":[47.0989379645613795,59.8445186957143,238.773531847525192],"luv":[47.0989379645613795,-31.0247207616125031,-51.1745358511991597],"rgb":[0,0.466666666666666674,0.66666666666666663],"xyz":[0.138514635665415164,0.160950444732221504,0.404081260567530853],"hpluv":[238.773531847525192,161.232500989130415,47.0989379645613795],"hsluv":[238.773531847525192,99.999999999991914,47.0989379645613795]},"#0077bb":{"lch":[47.9823278818304146,71.9659744020705432,245.408717039049918],"luv":[47.9823278818304146,-29.9480972873728,-65.4386196408934495],"rgb":[0,0.466666666666666674,0.733333333333333282],"xyz":[0.155652227772751839,0.167805481575156262,0.4943392456661726],"hpluv":[245.408717039049918,190.32034768447943,47.9823278818304146],"hsluv":[245.408717039049918,99.9999999999920561,47.9823278818304146]},"#0077cc":{"lch":[48.9484610491917067,84.4081580704908276,249.9122747909542],"luv":[48.9484610491917067,-28.9906993044602252,-79.2734287305105454],"rgb":[0,0.466666666666666674,0.8],"xyz":[0.174944603216473565,0.175522431752645064,0.595945756336442756],"hpluv":[249.9122747909542,218.818838178067409,48.9484610491917067],"hsluv":[249.9122747909542,99.9999999999922125,48.9484610491917067]},"#0077dd":{"lch":[49.9932200675849,96.8017840095652389,253.089738624096071],"luv":[49.9932200675849,-28.15707849035525,-92.6162206005108715],"rgb":[0,0.466666666666666674,0.866666666666666696],"xyz":[0.196462928767107109,0.184129761972898598,0.709275604236448753],"hpluv":[253.089738624096071,245.70363248193695,49.9932200675849],"hsluv":[253.089738624096071,99.9999999999921272,49.9932200675849]},"#0077ee":{"lch":[51.1120678627821547,108.963279527823246,255.411176145550684],"luv":[51.1120678627821547,-27.4457353077348785,-105.450120430828804],"rgb":[0,0.466666666666666674,0.933333333333333348],"xyz":[0.220275109033281846,0.193654634079368643,0.834686420304972],"hpluv":[255.411176145550684,270.517920771775039,51.1120678627821547],"hsluv":[255.411176145550684,99.9999999999922551,51.1120678627821547]},"#0077ff":{"lch":[52.300205122294,120.810007187166491,257.158195690943],"luv":[52.300205122294,-26.851223719183885,-117.788240590245493],"rgb":[0,0.466666666666666674,1],"xyz":[0.24644615744311324,0.204123053443301339,0.972520608596753822],"hpluv":[257.158195690943,293.11554041762389,52.300205122294],"hsluv":[257.158195690943,99.9999999999991189,52.300205122294]},"#008800":{"lch":[49.0166039301270473,75.8637069146273291,127.71501294924046],"luv":[49.0166039301270473,-46.4084346679225348,60.0129920808956214],"rgb":[0,0.533333333333333326,0],"xyz":[0.0880377387662537,0.176075477532509878,0.0293459129220837445],"hpluv":[127.71501294924046,196.394882900214583,49.0166039301270473],"hsluv":[127.71501294924046,100.000000000002359,49.0166039301270473]},"#008811":{"lch":[49.066374048408079,74.1307167522113133,128.546257021813432],"luv":[49.066374048408079,-46.1942790787678064,57.9780281364371461],"rgb":[0,0.533333333333333326,0.0666666666666666657],"xyz":[0.0890494042658908219,0.17648014373236473,0.0346740178868393742],"hpluv":[128.546257021813432,191.713881645209739,49.066374048408079],"hsluv":[128.546257021813432,99.9999999999908908,49.066374048408079]},"#008822":{"lch":[49.1584337135343503,71.0276132120671,130.159311596065152],"luv":[49.1584337135343503,-45.8067815452400779,54.2831521106656112],"rgb":[0,0.533333333333333326,0.133333333333333331],"xyz":[0.090924762404367851,0.177230286987755559,0.0445509040828185737],"hpluv":[130.159311596065152,183.344763498744726,49.1584337135343503],"hsluv":[130.159311596065152,99.9999999999909335,49.1584337135343503]},"#008833":{"lch":[49.3094443496477197,66.226384742663825,133.033255321350083],"luv":[49.3094443496477197,-45.1943905199784481,48.4086882864121648],"rgb":[0,0.533333333333333326,0.2],"xyz":[0.0940125131368255845,0.178465387280738658,0.060813057940429717],"hpluv":[133.033255321350083,170.427732437953466,49.3094443496477197],"hsluv":[133.033255321350083,99.9999999999909903,49.3094443496477197]},"#008844":{"lch":[49.5262444349700388,59.9709063982634589,137.708745518338219],"luv":[49.5262444349700388,-44.3625073014275202,40.3543995143041],"rgb":[0,0.533333333333333326,0.266666666666666663],"xyz":[0.0984705083810444581,0.180248585378426252,0.0842918328933163485],"hpluv":[137.708745518338219,153.654237765673173,49.5262444349700388],"hsluv":[137.708745518338219,99.9999999999910756,49.5262444349700388]},"#008855":{"lch":[49.8139833497656355,52.876539169604392,145.043769270071607],"luv":[49.8139833497656355,-43.3370811793054074,30.2956397756013871],"rgb":[0,0.533333333333333326,0.333333333333333315],"xyz":[0.104432922420406457,0.182633550994171084,0.115693880167290264],"hpluv":[145.043769270071607,134.694876863850226,49.8139833497656355],"hsluv":[145.043769270071607,99.9999999999911893,49.8139833497656355]},"#008866":{"lch":[50.1764284055384593,46.0546718070978613,156.264738854980266],"luv":[50.1764284055384593,-42.1591397878491918,18.5375221539472825],"rgb":[0,0.533333333333333326,0.4],"xyz":[0.112017918193914628,0.185667549303574375,0.155641524574434226],"hpluv":[156.264738854980266,116.469784961641182,50.1764284055384593],"hsluv":[156.264738854980266,99.9999999999912461,50.1764284055384593]},"#008877":{"lch":[50.6161324463586766,41.2412500498738694,172.391379993232761],"luv":[50.6161324463586766,-40.8781468825216336,5.46056893805106114],"rgb":[0,0.533333333333333326,0.466666666666666674],"xyz":[0.121331931214116548,0.189393154511655198,0.204695326480832135],"hpluv":[172.391379993232761,103.390869865470918,50.6161324463586766],"hsluv":[172.391379993232761,99.9999999999913456,50.6161324463586766]},"#008888":{"lch":[51.1345503085294695,40.4555776108317602,192.177050630061132],"luv":[51.1345503085294695,-39.545345738280993,-8.53342781453345],"rgb":[0,0.533333333333333326,0.533333333333333326],"xyz":[0.132472348316060362,0.193849321352432796,0.263368189884404302],"hpluv":[192.177050630061132,100.392967527320849,51.1345503085294695],"hsluv":[192.177050630061132,99.9999999999914877,51.1345503085294695]},"#008899":{"lch":[51.7321394091786715,44.6308971675799881,211.11913642158629],"luv":[51.7321394091786715,-38.208266400248,-23.066108485628412],"rgb":[0,0.533333333333333326,0.6],"xyz":[0.145529312425133089,0.199072106996061954,0.332134867525522237],"hpluv":[211.11913642158629,109.474886689832829,51.7321394091786715],"hsluv":[211.11913642158629,99.999999999991573,51.7321394091786715]},"#0088aa":{"lch":[52.4084594351014914,52.8385448128107598,225.694192047300788],"luv":[52.4084594351014914,-36.9070805124816346,-37.8124215831333572],"rgb":[0,0.533333333333333326,0.66666666666666663],"xyz":[0.160587005390385618,0.205095184182163048,0.411438717142520782],"hpluv":[225.694192047300788,127.934825585488483,52.4084594351014914],"hsluv":[225.694192047300788,99.9999999999917,52.4084594351014914]},"#0088bb":{"lch":[53.1622766119302952,63.4852929684367,235.812153399491365],"luv":[53.1622766119302952,-35.672889398211332,-52.5150205681309856],"rgb":[0,0.533333333333333326,0.733333333333333282],"xyz":[0.177724597497722292,0.211950221025097807,0.501696702241162584],"hpluv":[235.812153399491365,151.533580059798538,53.1622766119302952],"hsluv":[235.812153399491365,99.9999999999918572,53.1622766119302952]},"#0088cc":{"lch":[53.9916730817088961,75.3609801883338406,242.731381598031476],"luv":[53.9916730817088961,-34.5275961267233455,-66.9859868976812578],"rgb":[0,0.533333333333333326,0.8],"xyz":[0.197016972941444019,0.219667171202586609,0.60330321291143274],"hpluv":[242.731381598031476,177.116523654060018,53.9916730817088961],"hsluv":[242.731381598031476,99.9999999999919282,53.9916730817088961]},"#0088dd":{"lch":[54.894159312243417,87.7409205251226,247.565131731451658],"luv":[54.894159312243417,-33.4848266090853,-81.1001573460580545],"rgb":[0,0.533333333333333326,0.866666666666666696],"xyz":[0.218535298492077562,0.228274501422840143,0.716633060811438738],"hpluv":[247.565131731451658,202.822146488853946,54.894159312243417],"hsluv":[247.565131731451658,99.9999999999921414,54.894159312243417]},"#0088ee":{"lch":[55.8667862779657725,100.217939448335898,251.046181944553609],"luv":[55.8667862779657725,-32.551381555669181,-94.7841914355319091],"rgb":[0,0.533333333333333326,0.933333333333333348],"xyz":[0.242347478758252299,0.237799373529310187,0.842043876879962],"hpluv":[251.046181944553609,227.630842720065772,55.8667862779657725],"hsluv":[251.046181944553609,99.9999999999923261,55.8667862779657725]},"#0088ff":{"lch":[56.9062538959811803,112.568622459607909,253.628629682131134],"luv":[56.9062538959811803,-31.728824885135996,-108.00452043253614],"rgb":[0,0.533333333333333326,1],"xyz":[0.268518527168083665,0.248267792893242883,0.979878065171743806],"hpluv":[253.628629682131134,251.013269675548315,56.9062538959811803],"hsluv":[253.628629682131134,99.9999999999989,56.9062538959811803]},"#009900":{"lch":[54.8465256129575778,84.8867610313905629,127.71501294924046],"luv":[54.8465256129575778,-51.9281467214630865,67.1507987776363677],"rgb":[0,0.6,0],"xyz":[0.11390733921872119,0.227814678437445572,0.037969113072906],"hpluv":[127.71501294924046,196.394882900214611,54.8465256129575778],"hsluv":[127.71501294924046,100.000000000002359,54.8465256129575778]},"#009911":{"lch":[54.8884489227774139,83.3822613920475533,128.355135015114286],"luv":[54.8884489227774139,-51.7415219578455918,65.3866685214771195],"rgb":[0,0.6,0.0666666666666666657],"xyz":[0.114919004718358309,0.228219344637300425,0.0432972180376616292],"hpluv":[128.355135015114286,192.766711025891595,54.8884489227774139],"hsluv":[128.355135015114286,99.9999999999908908,54.8884489227774139]},"#009922":{"lch":[54.9660326693047665,80.6666974094322882,129.584419925030318],"luv":[54.9660326693047665,-51.4019848556742147,62.168738316310943],"rgb":[0,0.6,0.133333333333333331],"xyz":[0.116794362856835338,0.228969487892691254,0.0531741042336408287],"hpluv":[129.584419925030318,186.225526863887183,54.9660326693047665],"hsluv":[129.584419925030318,99.9999999999908766,54.9660326693047665]},"#009933":{"lch":[55.0934048637144826,76.4021664793699529,131.735569901926],"luv":[55.0934048637144826,-50.8604445821364948,57.0132109221080725],"rgb":[0,0.6,0.2],"xyz":[0.119882113589293071,0.230204588185674353,0.0694362580912519789],"hpluv":[131.735569901926,175.972736191316358,55.0934048637144826],"hsluv":[131.735569901926,99.9999999999909903,55.0934048637144826]},"#009944":{"lch":[55.2764995203901321,70.6973886175228614,135.142608572152881],"luv":[55.2764995203901321,-50.1148739946869739,49.8660221176072795],"rgb":[0,0.6,0.266666666666666663],"xyz":[0.124340108833511945,0.231987786283361946,0.0929150330441386174],"hpluv":[135.142608572152881,162.293888564466016,55.2764995203901321],"hsluv":[135.142608572152881,99.9999999999910472,55.2764995203901321]},"#009955":{"lch":[55.5199214835444792,63.9084670453141044,140.311824754994205],"luv":[55.5199214835444792,-49.1795700812718,40.8125231602173173],"rgb":[0,0.6,0.333333333333333315],"xyz":[0.130302522872873944,0.234372751899106779,0.124317080318112519],"hpluv":[140.311824754994205,146.065915008593578,55.5199214835444792],"hsluv":[140.311824754994205,99.999999999991033,55.5199214835444792]},"#009966":{"lch":[55.8272121342916847,56.7002292022714229,147.995210176352344],"luv":[55.8272121342916847,-48.0820094218291771,30.0505634148387166],"rgb":[0,0.6,0.4],"xyz":[0.137887518646382129,0.23740675020851007,0.164264724725256495],"hpluv":[147.995210176352344,128.877825594911201,55.8272121342916847],"hsluv":[147.995210176352344,99.9999999999911893,55.8272121342916847]},"#009977":{"lch":[56.2009899164422393,50.1460500452165832,159.138923639260469],"luv":[56.2009899164422393,-46.85880632633,17.8571723631952],"rgb":[0,0.6,0.466666666666666674],"xyz":[0.147201531666584035,0.241132355416590893,0.213318526631654404],"hpluv":[159.138923639260469,113.222330796973324,56.2009899164422393],"hsluv":[159.138923639260469,99.9999999999912887,56.2009899164422393]},"#009988":{"lch":[56.6430401241061077,45.7780774967248476,174.293450088826631],"luv":[56.6430401241061077,-45.5512109338885409,4.55187453172192669],"rgb":[0,0.6,0.533333333333333326],"xyz":[0.158341948768527863,0.245588522257368491,0.271991390035226543],"hpluv":[174.293450088826631,102.553461073272217,56.6430401241061077],"hsluv":[174.293450088826631,99.9999999999913456,56.6430401241061077]},"#009999":{"lch":[57.1543844255405133,45.2182256610376498,192.177050630061132],"luv":[57.1543844255405133,-44.2008363998384866,-9.53802880511673301],"rgb":[0,0.6,0.6],"xyz":[0.171398912877600562,0.250811307900997649,0.340758067676344478],"hpluv":[192.177050630061132,100.392967527320849,57.1543844255405133],"hsluv":[192.177050630061132,99.9999999999914877,57.1543844255405133]},"#0099aa":{"lch":[57.7353441317496,49.1617433665336065,209.362441333496832],"luv":[57.7353441317496,-42.8462007667450138,-24.1056028900479831],"rgb":[0,0.6,0.66666666666666663],"xyz":[0.186456605842853118,0.256834385087098771,0.420061917293343079],"hpluv":[209.362441333496832,108.050017888493571,57.7353441317496],"hsluv":[209.362441333496832,99.9999999999915872,57.7353441317496]},"#0099bb":{"lch":[58.3856036871333686,56.8846197873520509,223.121526867409756],"luv":[58.3856036871333686,-41.5203973647636531,-38.8833713947714656],"rgb":[0,0.6,0.733333333333333282],"xyz":[0.203594197950189765,0.26368942193003353,0.51031990239198477],"hpluv":[223.121526867409756,123.631292939903787,58.3856036871333686],"hsluv":[223.121526867409756,99.9999999999917151,58.3856036871333686]},"#0099cc":{"lch":[59.1042769117952531,67.0724902608298237,233.123241992210865],"luv":[59.1042769117952531,-40.2499186561976856,-53.6531732328907225],"rgb":[0,0.6,0.8],"xyz":[0.222886573393911491,0.271406372107522331,0.611926413062254926],"hpluv":[233.123241992210865,144.000781521109104,59.1042769117952531],"hsluv":[233.123241992210865,99.9999999999918572,59.1042769117952531]},"#0099dd":{"lch":[59.889976295668248,78.6325369214165448,240.220044999287609],"luv":[59.889976295668248,-39.0544489896310338,-68.2482664747921888],"rgb":[0,0.6,0.866666666666666696],"xyz":[0.244404898944545035,0.280013702327775837,0.725256260962260924],"hpluv":[240.220044999287609,166.60478591483178,59.889976295668248],"hsluv":[240.220044999287609,99.9999999999918288,59.889976295668248]},"#0099ee":{"lch":[60.7408843834734853,90.8542474807105549,245.312254820906361],"luv":[60.7408843834734853,-37.9473430473261288,-82.5499451298106521],"rgb":[0,0.6,0.933333333333333348],"xyz":[0.2682170792107198,0.289538574434245854,0.850667077030784147],"hpluv":[245.312254820906361,189.803165481490907,60.7408843834734853],"hsluv":[245.312254820906361,99.9999999999919424,60.7408843834734853]},"#0099ff":{"lch":[61.6548256470178444,103.309645725501895,249.051296659176671],"luv":[61.6548256470178444,-36.936501733242423,-96.4809708680364082],"rgb":[0,0.6,1],"xyz":[0.294388127620551165,0.300006993798178578,0.988501265322566],"hpluv":[249.051296659176671,212.624411607996194,61.6548256470178444],"hsluv":[249.051296659176671,99.9999999999986926,61.6548256470178444]},"#44aa00":{"lch":[61.6346835386869714,87.655425968627469,122.331376925101353],"luv":[61.6346835386869714,-46.8794507107122556,74.0661245293922],"rgb":[0.266666666666666663,0.66666666666666663,0],"xyz":[0.167579386406696784,0.29977360690638849,0.0490310792412290836],"hpluv":[122.331376925101353,180.464989524422549,61.6346835386869714],"hsluv":[122.331376925101353,100.00000000000226,61.6346835386869714]},"#44aa11":{"lch":[61.6696010074672927,86.3319887480293175,122.80087722620695],"luv":[61.6696010074672927,-46.7678581574140253,72.5670705248452492],"rgb":[0.266666666666666663,0.66666666666666663,0.0666666666666666657],"xyz":[0.168591051906333916,0.300178273106243343,0.0543591842059847133],"hpluv":[122.80087722620695,177.639660035048053,61.6696010074672927],"hsluv":[122.80087722620695,97.7717273205757778,61.6696010074672927]},"#44aa22":{"lch":[61.7342457720645541,83.9245562706402097,123.699102784065559],"luv":[61.7342457720645541,-46.5639790081192,69.8221097085679],"rgb":[0.266666666666666663,0.66666666666666663,0.133333333333333331],"xyz":[0.170466410044810918,0.300928416361634143,0.0642360704019639128],"hpluv":[123.699102784065559,172.505216938407472,61.7342457720645541],"hsluv":[123.699102784065559,93.6968530578778882,61.7342457720645541]},"#44aa33":{"lch":[61.8404488118369784,80.0901636841586111,125.261260913590505],"luv":[61.8404488118369784,-46.2365065380172098,65.3958697634278],"rgb":[0.266666666666666663,0.66666666666666663,0.2],"xyz":[0.173554160777268651,0.30216351665461727,0.080498224259575063],"hpluv":[125.261260913590505,164.340980941234676,61.8404488118369784],"hsluv":[125.261260913590505,87.1410828818075913,61.8404488118369784]},"#44aa44":{"lch":[61.9932720073472,74.8379874444649573,127.71501294923992],"luv":[61.9932720073472,-45.7809668449718501,59.2015830825281526],"rgb":[0.266666666666666663,0.66666666666666663,0.266666666666666663],"xyz":[0.178012156021487539,0.303946714752304836,0.103976999212461702],"hpluv":[127.71501294923992,153.185220958209158,61.9932720073472],"hsluv":[127.71501294923992,77.998580561819125,61.9932720073472]},"#44aa55":{"lch":[62.1967362447927883,68.3415808764166854,131.40733952388851],"luv":[62.1967362447927883,-45.2016647888952292,51.2579864704043118],"rgb":[0.266666666666666663,0.66666666666666663,0.333333333333333315],"xyz":[0.183974570060849552,0.306331680368049697,0.135379046486435617],"hpluv":[131.40733952388851,139.430168232009549,62.1967362447927883],"hsluv":[131.40733952388851,78.575415606985473,62.1967362447927883]},"#44aa66":{"lch":[62.4540496972210377,60.9745995384144,136.885019691281769],"luv":[62.4540496972210377,-44.510458035487396,41.6739836629655684],"rgb":[0.266666666666666663,0.66666666666666663,0.4],"xyz":[0.191559565834357709,0.309365678677453,0.175326690893579551],"hpluv":[136.885019691281769,123.88755407265441,62.4540496972210377],"hsluv":[136.885019691281769,79.2669246679894854,62.4540496972210377]},"#44aa77":{"lch":[62.7677273349888196,53.3862032124370103,144.988299459670287],"luv":[62.7677273349888196,-43.7251633677153,30.629998072253084],"rgb":[0.266666666666666663,0.66666666666666663,0.466666666666666674],"xyz":[0.200873578854559642,0.313091283885533811,0.22438049279997746],"hpluv":[144.988299459670287,107.927460302012818,62.7677273349888196],"hsluv":[144.988299459670287,80.0573307147673603,62.7677273349888196]},"#44aa88":{"lch":[63.1396635168947142,46.6323085826041606,156.819414130132799],"luv":[63.1396635168947142,-42.8676249510766354,18.3558964585511255],"rgb":[0.266666666666666663,0.66666666666666663,0.533333333333333326],"xyz":[0.212013995956503443,0.317547450726311409,0.283053356203549655],"hpluv":[156.819414130132799,93.7182088199909,63.1396635168947142],"hsluv":[156.819414130132799,80.9270306732118456,63.1396635168947142]},"#44aa99":{"lch":[63.5711832083111,42.2713825005608328,173.059905511526438],"luv":[63.5711832083111,-41.9616613239929848,5.10771548142927578],"rgb":[0.266666666666666663,0.66666666666666663,0.6],"xyz":[0.22507096006557617,0.322770236369940566,0.351820033844667535],"hpluv":[173.059905511526438,84.3772726773670598,63.5711832083111],"hsluv":[173.059905511526438,81.8544924931781281,63.5711832083111]},"#44aaaa":{"lch":[64.0630839897801536,41.9755778813547948,192.177050630061],"luv":[64.0630839897801536,-41.03114670244819,-8.85404646225986802],"rgb":[0.266666666666666663,0.66666666666666663,0.66666666666666663],"xyz":[0.240128653030828698,0.328793313556041689,0.431123883461666135],"hpluv":[192.177050630061,83.1434743556685731,64.0630839897801536],"hsluv":[192.177050630061,82.8180264051213868,64.0630839897801536]},"#44aabb":{"lch":[64.6156750410269893,46.3675567205894481,210.140689328835606],"luv":[64.6156750410269893,-40.0984334486196374,-23.2823098339426302],"rgb":[0.266666666666666663,0.66666666666666663,0.733333333333333282],"xyz":[0.257266245138165373,0.335648350398976447,0.521381868560307882],"hpluv":[210.140689328835606,91.0574853549996135,64.6156750410269893],"hsluv":[210.140689328835606,83.7972417316187,64.6156750410269893]},"#44aacc":{"lch":[65.2288162125558131,54.5527176111565382,224.088695054270687],"luv":[65.2288162125558131,-39.1832309762682058,-37.956203827872514],"rgb":[0.266666666666666663,0.66666666666666663,0.8],"xyz":[0.276558620581887071,0.343365300576465249,0.622988379230578],"hpluv":[224.088695054270687,106.124637545316332,65.2288162125558131],"hsluv":[224.088695054270687,84.7740840933985424,65.2288162125558131]},"#44aadd":{"lch":[65.9019585504415772,65.1392687949415574,233.984713087438024],"luv":[65.9019585504415772,-38.3019605797345406,-52.6885581021924381],"rgb":[0.266666666666666663,0.66666666666666663,0.866666666666666696],"xyz":[0.29807694613252067,0.351972630796718755,0.736318227130584],"hpluv":[233.984713087438024,125.424934833645892,65.9019585504415772],"hsluv":[233.984713087438024,85.7334354760652246,65.9019585504415772]},"#44aaee":{"lch":[66.634186587349916,77.0517400481588,240.904642753345257],"luv":[66.634186587349916,-37.4675316968449081,-67.3287064556787698],"rgb":[0.266666666666666663,0.66666666666666663,0.933333333333333348],"xyz":[0.32188912639869538,0.361497502903188772,0.861729043199107259],"hpluv":[240.904642753345257,146.73194579095005,66.634186587349916],"hsluv":[240.904642753345257,86.6633273618325717,66.634186587349916]},"#44aaff":{"lch":[67.4242620727880677,89.6163291450103827,245.832487512483851],"luv":[67.4242620727880677,-36.6894434071527229,-81.7616731231704534],"rgb":[0.266666666666666663,0.66666666666666663,1],"xyz":[0.348060174808526801,0.371965922267121496,0.999563231490889104],"hpluv":[245.832487512483851,168.659292786049974,67.4242620727880677],"hsluv":[245.832487512483851,99.9999999999982094,67.4242620727880677]},"#44bb00":{"lch":[67.1028050092269126,96.9162111575721497,123.392710981560953],"luv":[67.1028050092269126,-53.3402140179528601,80.9170782570533476],"rgb":[0.266666666666666663,0.733333333333333282,0],"xyz":[0.201533884315295564,0.367682602723587049,0.0603492452107617],"hpluv":[123.392710981560953,183.271561122122193,67.1028050092269126],"hsluv":[123.392710981560953,100.00000000000226,67.1028050092269126]},"#44bb11":{"lch":[67.1332810832727347,95.7453830613523138,123.778355355208646],"luv":[67.1332810832727347,-53.2326764896654581,79.5830417319651673],"rgb":[0.266666666666666663,0.733333333333333282,0.0666666666666666657],"xyz":[0.202545549814932696,0.368087268923441902,0.0656773501755173322],"hpluv":[123.778355355208646,180.975295348072393,67.1332810832727347],"hsluv":[123.778355355208646,98.1806384027583334,67.1332810832727347]},"#44bb22":{"lch":[67.1897165718252438,93.6085464076245728,124.511290753684577],"luv":[67.1897165718252438,-53.03566579282883,77.1348048189646391],"rgb":[0.266666666666666663,0.733333333333333282,0.133333333333333331],"xyz":[0.204420907953409697,0.368837412178832702,0.0755542363714965248],"hpluv":[124.511290753684577,176.787689053856155,67.1897165718252438],"hsluv":[124.511290753684577,94.8452524510698538,67.1897165718252438]},"#44bb33":{"lch":[67.2824703298360873,90.1849869824975627,125.771296969252688],"luv":[67.2824703298360873,-52.7177504009765485,73.1721987485246501],"rgb":[0.266666666666666663,0.733333333333333282,0.2],"xyz":[0.207508658685867431,0.370072512471815829,0.091816390229107675],"hpluv":[125.771296969252688,170.087205132927863,67.2824703298360873],"hsluv":[125.771296969252688,89.4565739304913308,67.2824703298360873]},"#44bb44":{"lch":[67.4160218575577375,85.4495691526201284,127.715012949240077],"luv":[67.4160218575577375,-52.2724357759646807,67.5960156105081182],"rgb":[0.266666666666666663,0.733333333333333282,0.266666666666666663],"xyz":[0.211966653930086318,0.371855710569503395,0.115295165181994314],"hpluv":[127.715012949240077,160.837043785954393,67.4160218575577375],"hsluv":[127.715012949240077,81.8947222100884318,67.4160218575577375]},"#44bb55":{"lch":[67.5939766620447813,79.5000401119176,130.566112214394138],"luv":[67.5939766620447813,-51.7008659583180759,60.3926886051327756],"rgb":[0.266666666666666663,0.733333333333333282,0.333333333333333315],"xyz":[0.217929067969448331,0.374240676185248256,0.146697212455968229],"hpluv":[130.566112214394138,149.244617358403957,67.5939766620447813],"hsluv":[130.566112214394138,82.2871698148834412,67.5939766620447813]},"#44bb66":{"lch":[67.8192698910356313,72.5749222232247,134.657948179728322],"luv":[67.8192698910356313,-51.0109407747319139,51.6236695420221778],"rgb":[0.266666666666666663,0.733333333333333282,0.4],"xyz":[0.225514063742956489,0.377274674494651574,0.186644856863112191],"hpluv":[134.657948179728322,135.791565604529097,67.8192698910356313],"hsluv":[134.657948179728322,82.7624878443234451,67.8192698910356313]},"#44bb77":{"lch":[68.0942730594189527,65.0902087481164671,140.487577627549143],"luv":[68.0942730594189527,-50.2162275054035163,41.4133525568618168],"rgb":[0.266666666666666663,0.733333333333333282,0.466666666666666674],"xyz":[0.234828076763158422,0.38100027970273237,0.2356986587695101],"hpluv":[140.487577627549143,121.295420087000366,68.0942730594189527],"hsluv":[140.487577627549143,83.3123735080707206,68.0942730594189527]},"#44bb88":{"lch":[68.4208577329380461,57.7058903955470939,148.752185803016886],"luv":[68.4208577329380461,-49.3345927236295907,29.9343907092910229],"rgb":[0.266666666666666663,0.733333333333333282,0.533333333333333326],"xyz":[0.245968493865102222,0.385456446543509967,0.294371522173082267],"hpluv":[148.752185803016886,107.021481540968693,68.4208577329380461],"hsluv":[148.752185803016886,83.9257037652282776,68.4208577329380461]},"#44bb99":{"lch":[68.8004384509552267,51.4171630403873507,160.23039633414129],"luv":[68.8004384509552267,-48.3866530594068536,17.3912754227620781],"rgb":[0.266666666666666663,0.733333333333333282,0.6],"xyz":[0.259025457974175,0.390679232187139125,0.363138199814200147],"hpluv":[160.23039633414129,94.8322885243955,68.8004384509552267],"hsluv":[160.23039633414129,84.5895330052649683,68.8004384509552267]},"#44bbaa":{"lch":[69.2340056114394571,47.5630236168925,175.171204236910796],"luv":[69.2340056114394571,-47.3942071553531576,4.003791165451279],"rgb":[0.266666666666666663,0.733333333333333282,0.66666666666666663],"xyz":[0.274083150939427478,0.396702309373240247,0.442442049431198747],"hpluv":[175.171204236910796,87.1744714415039113,69.2340056114394571],"hsluv":[175.171204236910796,85.2901010545764251,69.2340056114394571]},"#44bbbb":{"lch":[69.722153945093,47.4463312905994243,192.177050630061103],"luv":[69.722153945093,-46.3788106784417877,-10.0080104411700219],"rgb":[0.266666666666666663,0.733333333333333282,0.733333333333333282],"xyz":[0.291220743046764152,0.403557346216175,0.532700034529840494],"hpluv":[192.177050630061103,86.3517549054621156,69.722153945093],"hsluv":[192.177050630061103,86.0137488036252,69.722153945093]},"#44bbcc":{"lch":[70.265109629848,51.5238495855336254,208.311647260201596],"luv":[70.265109629848,-45.3606162241423405,-24.4360711219862],"rgb":[0.266666666666666663,0.733333333333333282,0.8],"xyz":[0.310513118490485907,0.411274296393663807,0.63430654520011065],"hpluv":[208.311647260201596,93.0481841100277478,70.265109629848],"hsluv":[208.311647260201596,86.7476639801695484,70.265109629848]},"#44bbdd":{"lch":[70.8627576511434683,59.1258582536945,221.390354970453018],"luv":[70.8627576511434683,-44.357542252504274,-39.0931651258026491],"rgb":[0.266666666666666663,0.733333333333333282,0.866666666666666696],"xyz":[0.332031444041119395,0.419881626613917314,0.747636393100116647],"hpluv":[221.390354970453018,105.876295000483495,70.8627576511434683],"hsluv":[221.390354970453018,87.4804162985680449,70.8627576511434683]},"#44bbee":{"lch":[71.5146701379092207,69.1277260896420813,231.126492355228834],"luv":[71.5146701379092207,-43.3847784652122499,-53.8182451576511269],"rgb":[0.266666666666666663,0.733333333333333282,0.933333333333333348],"xyz":[0.35584362430729416,0.429406498720387331,0.873047209168639871],"hpluv":[231.126492355228834,122.65816352572412,71.5146701379092207],"hsluv":[231.126492355228834,88.202277385306985,71.5146701379092207]},"#44bbff":{"lch":[72.2201358507708,80.5712163793027685,238.202407995552562],"luv":[72.2201358507708,-42.4545914747530801,-68.4786723845625573],"rgb":[0.266666666666666663,0.733333333333333282,1],"xyz":[0.382014672717125525,0.439874918084320055,1.01088139746042183],"hpluv":[238.202407995552562,141.566646923483631,72.2201358507708],"hsluv":[238.202407995552562,99.9999999999976694,72.2201358507708]},"#44cc00":{"lch":[72.503692055952385,105.959797206167082,124.178253965335855],"luv":[72.503692055952385,-59.5249745926526543,87.6598883396283384],"rgb":[0.266666666666666663,0.8,0],"xyz":[0.239757627624912484,0.444130089342821943,0.0730904929806336506],"hpluv":[124.178253965335855,185.447217969921951,72.503692055952385],"hsluv":[124.178253965335855,100.000000000002359,72.503692055952385]},"#44cc11":{"lch":[72.5305637479271752,104.914943747871533,124.498982817725434],"luv":[72.5305637479271752,-59.4229434801529877,86.4642076802510928],"rgb":[0.266666666666666663,0.8,0.0666666666666666657],"xyz":[0.240769293124549616,0.444534755542676796,0.0784185979453892873],"hpluv":[124.498982817725434,183.55052269402043,72.5305637479271752],"hsluv":[124.498982817725434,98.4921383302381628,72.5305637479271752]},"#44cc22":{"lch":[72.5803335982668,103.003123626508128,125.105641856618192],"luv":[72.5803335982668,-59.2356349500081265,84.2661440252673088],"rgb":[0.266666666666666663,0.8,0.133333333333333331],"xyz":[0.242644651263026617,0.445284898798067597,0.0882954841413684799],"hpluv":[125.105641856618192,180.082189217111164,72.5803335982668],"hsluv":[125.105641856618192,95.7225658430248387,72.5803335982668]},"#44cc33":{"lch":[72.6621573160580283,99.9260617146724144,126.139923542820412],"luv":[72.6621573160580283,-58.9323161564504758,80.6982027200153],"rgb":[0.266666666666666663,0.8,0.2],"xyz":[0.245732401995484351,0.446519999091050723,0.10455763799897963],"hpluv":[126.139923542820412,174.505777504147545,72.6621573160580283],"hsluv":[126.139923542820412,91.233607132201584,72.6621573160580283]},"#44cc44":{"lch":[72.780026014363628,95.6382843785450518,127.715012949240148],"luv":[72.780026014363628,-58.5052227586060383,75.6559339961998],"rgb":[0.266666666666666663,0.8,0.266666666666666663],"xyz":[0.250190397239703266,0.448303197188738289,0.128036412951866269],"hpluv":[127.715012949240148,166.747333178852926,72.780026014363628],"hsluv":[127.715012949240148,84.9041129363740339,72.780026014363628]},"#44cc55":{"lch":[72.9371837422115732,90.1892610669535912,129.983942971096695],"luv":[72.9371837422115732,-57.9531752136704,69.1052262456084492],"rgb":[0.266666666666666663,0.8,0.333333333333333315],"xyz":[0.256152811279065251,0.45068816280448315,0.159438460225840184],"hpluv":[129.983942971096695,156.908028239254975,72.9371837422115732],"hsluv":[129.983942971096695,85.1779272269293557,72.9371837422115732]},"#44cc66":{"lch":[73.1363103507417236,83.732792729713168,133.164212643981188],"luv":[73.1363103507417236,-57.28090462038152,61.074368962666],"rgb":[0.266666666666666663,0.8,0.4],"xyz":[0.263737807052573436,0.453722161113886469,0.199386104632984118],"hpluv":[133.164212643981188,145.278670258241675,73.1363103507417236],"hsluv":[133.164212643981188,85.5122241677148764,73.1363103507417236]},"#44cc77":{"lch":[73.3796177536812309,76.5464624175537,137.569101073773794],"luv":[73.3796177536812309,-56.4983001604517625,51.6459387330839],"rgb":[0.266666666666666663,0.8,0.466666666666666674],"xyz":[0.273051820072775342,0.457447766321967264,0.248439906539382027],"hpluv":[137.569101073773794,132.369828459728325,73.3796177536812309],"hsluv":[137.569101073773794,85.9026534082125153,73.3796177536812309]},"#44cc88":{"lch":[73.6689069899719442,69.0664605730878378,143.639563525196422],"luv":[73.6689069899719442,-55.6194534086204087,40.9469459010095278],"rgb":[0.266666666666666663,0.8,0.533333333333333326],"xyz":[0.284192237174719142,0.461903933162744862,0.307112769942954222],"hpluv":[143.639563525196422,118.965846887396481,73.6689069899719442],"hsluv":[143.639563525196422,86.3428682965135863,73.6689069899719442]},"#44cc99":{"lch":[74.0056056952011,61.9424628035573548,151.940118655705163],"luv":[74.0056056952011,-54.661526046940331,29.1373689338922652],"rgb":[0.266666666666666663,0.8,0.6],"xyz":[0.297249201283791842,0.467126718806374,0.375879447584072102],"hpluv":[151.940118655705163,106.209454381597496,74.0056056952011],"hsluv":[151.940118655705163,86.8250568088678,74.0056056952011]},"#44ccaa":{"lch":[74.3907954563299256,56.0938540204294327,163.002493202880316],"luv":[74.3907954563299256,-53.6435329798001206,16.3979214631106132],"rgb":[0.266666666666666663,0.8,0.66666666666666663],"xyz":[0.312306894249044398,0.473149795992475142,0.455183297201070702],"hpluv":[163.002493202880316,95.6831366692641581,74.3907954563299256],"hsluv":[163.002493202880316,87.3405106459777727,74.3907954563299256]},"#44ccbb":{"lch":[74.8252340948823331,52.6660587979454959,176.823724318960615],"luv":[74.8252340948823331,-52.5851528012588929,2.91812511330579927],"rgb":[0.266666666666666663,0.8,0.733333333333333282],"xyz":[0.329444486356381072,0.4800048328354099,0.545441282299712449],"hpluv":[176.823724318960615,89.3145186414393493,74.8252340948823331],"hsluv":[176.823724318960615,87.8801809558037235,74.8252340948823331]},"#44cccc":{"lch":[75.3093757141467393,52.6911947618550442,192.177050630061103],"luv":[75.3093757141467393,-51.5056671360628826,-11.1143267137884898],"rgb":[0.266666666666666663,0.8,0.8],"xyz":[0.348736861800102771,0.487721783012898702,0.647047792969982605],"hpluv":[192.177050630061103,88.7826952764381758,75.3093757141467393],"hsluv":[192.177050630061103,88.4351737608208168,75.3093757141467393]},"#44ccdd":{"lch":[75.8433901234223669,56.5143539908888,206.846753698803184],"luv":[75.8433901234223669,-50.423101427505074,-25.5222069860548118],"rgb":[0.266666666666666663,0.8,0.866666666666666696],"xyz":[0.37025518735073637,0.496329113233152208,0.760377640869988602],"hpluv":[206.846753698803184,94.5540981724771257,75.8433901234223669],"hsluv":[206.846753698803184,88.9971515077065334,75.8433901234223669]},"#44ccee":{"lch":[76.4271825186181104,63.6191993934700264,219.125479385679029],"luv":[76.4271825186181104,-49.3536035237008,-40.1450414209705926],"rgb":[0.266666666666666663,0.8,0.933333333333333348],"xyz":[0.39406736761691108,0.505853985339622225,0.885788456938511826],"hpluv":[219.125479385679029,108.248092211119214,76.4271825186181104],"hsluv":[219.125479385679029,89.5586239337052,76.4271825186181104]},"#44ccff":{"lch":[77.0604138316104752,73.087044724203011,228.6232677289035],"luv":[77.0604138316104752,-48.3110621928290342,-54.8430248647743426],"rgb":[0.266666666666666663,0.8,1],"xyz":[0.420238416026742501,0.516322404703555,1.02362264523029367],"hpluv":[228.6232677289035,128.526456918779161,77.0604138316104752],"hsluv":[228.6232677289035,99.9999999999969731,77.0604138316104752]},"#44dd00":{"lch":[77.8394471675691193,114.806757868746558,124.774603647715026],"luv":[77.8394471675691193,-65.4799812263264869,94.3025116894186],"rgb":[0.266666666666666663,0.866666666666666696,0],"xyz":[0.282391618172087688,0.529398070437173462,0.0873018231630249691],"hpluv":[124.774603647715026,210.465861771712326,77.8394471675691193],"hsluv":[124.774603647715026,100.000000000002174,77.8394471675691193]},"#44dd11":{"lch":[77.8633510332093692,113.867279553553601,125.04447057905567],"luv":[77.8633510332093692,-65.3839645843072503,93.2238946202376724],"rgb":[0.266666666666666663,0.866666666666666696,0.0666666666666666657],"xyz":[0.283403283671724793,0.529802736637028371,0.0926299281277806],"hpluv":[125.04447057905567,209.014039294370775,77.8633510332093692],"hsluv":[125.04447057905567,98.7339197526847272,77.8633510332093692]},"#44dd22":{"lch":[77.9076302523257738,112.144788460185168,125.553114236235714],"luv":[77.9076302523257738,-65.2074178024426914,91.2384033306006472],"rgb":[0.266666666666666663,0.866666666666666696,0.133333333333333331],"xyz":[0.28527864181020185,0.530552879892419171,0.102506814323759798],"hpluv":[125.553114236235714,206.347170822894697,77.9076302523257738],"hsluv":[125.553114236235714,96.4050109160080382,77.9076302523257738]},"#44dd33":{"lch":[77.9804445180848802,109.362510567887881,126.41495586461761],"luv":[77.9804445180848802,-64.9207541848309546,88.0082632130877869],"rgb":[0.266666666666666663,0.866666666666666696,0.2],"xyz":[0.288366392542659555,0.531787980185402298,0.118768968181370949],"hpluv":[126.41495586461761,202.025685311970193,77.9804445180848802],"hsluv":[126.41495586461761,92.6208241654068729,77.9804445180848802]},"#44dd44":{"lch":[78.0853727898892345,105.463232003770898,127.715012949240119],"luv":[78.0853727898892345,-64.5154806081751389,83.428089194092081],"rgb":[0.266666666666666663,0.866666666666666696,0.266666666666666663],"xyz":[0.292824387786878471,0.533571178283089864,0.142247743134257587],"hpluv":[127.715012949240119,195.940425098340825,78.0853727898892345],"hsluv":[127.715012949240119,87.2650912217990395,78.0853727898892345]},"#44dd55":{"lch":[78.2253459168282888,100.46502238820301,129.562971792001804],"luv":[78.2253459168282888,-63.9887749627021662,77.4510000079714303],"rgb":[0.266666666666666663,0.866666666666666696,0.333333333333333315],"xyz":[0.298786801826240456,0.535956143898834614,0.173649790408231475],"hpluv":[129.562971792001804,188.090878204767051,78.2253459168282888],"hsluv":[129.562971792001804,87.4605090914447,78.2253459168282888]},"#44dd66":{"lch":[78.4028117957757615,94.4661355921174,132.108441056441876],"luv":[78.4028117957757615,-63.3429373931831776,70.0822592109557],"rgb":[0.266666666666666663,0.866666666666666696,0.4],"xyz":[0.306371797599748641,0.538990142208237932,0.213597434815375464],"hpluv":[132.108441056441876,178.59774401526758,78.4028117957757615],"hsluv":[132.108441056441876,87.7006053461373654,78.4028117957757615]},"#44dd77":{"lch":[78.6198227824069278,87.656024220764337,135.559861003190832],"luv":[78.6198227824069278,-62.584854150819659,61.3735660778470375],"rgb":[0.266666666666666663,0.866666666666666696,0.466666666666666674],"xyz":[0.315685810619950546,0.542715747416318783,0.262651236721773373],"hpluv":[135.559861003190832,167.73117312681623,78.6198227824069278],"hsluv":[135.559861003190832,87.9831439767702221,78.6198227824069278]},"#44dd88":{"lch":[78.8780874692010201,80.3346414261830404,140.206181380764804],"luv":[78.8780874692010201,-61.7253288138421823,51.416324216113189],"rgb":[0.266666666666666663,0.866666666666666696,0.533333333333333326],"xyz":[0.326826227721894347,0.547171914257096326,0.321324100125345513],"hpluv":[140.206181380764804,155.961921377148798,78.8780874692010201],"hsluv":[140.206181380764804,88.3044935606717729,78.8780874692010201]},"#44dd99":{"lch":[79.1790042342924,72.9438114093828602,146.430978952194238],"luv":[79.1790042342924,-60.7782665628728651,40.3336328210091182],"rgb":[0.266666666666666663,0.866666666666666696,0.6],"xyz":[0.339883191830967046,0.552394699900725539,0.390090777766463448],"hpluv":[146.430978952194238,144.047423549525234,79.1790042342924],"hsluv":[146.430978952194238,88.6599152631773109,79.1790042342924]},"#44ddaa":{"lch":[79.5236849812282,66.109750002698334,154.681927012774025],"luv":[79.5236849812282,-59.7597565852220498,28.2713731236083063],"rgb":[0.266666666666666663,0.866666666666666696,0.66666666666666663],"xyz":[0.354940884796219602,0.558417777086826606,0.469394627383462049],"hpluv":[154.681927012774025,133.15854000611057,79.5236849812282],"hsluv":[154.681927012774025,89.0438856180527267,79.5236849812282]},"#44ddbb":{"lch":[79.9129735834354733,60.6712530747818448,165.306614809553963],"luv":[79.9129735834354733,-58.687123678359157,15.3890371376899697],"rgb":[0.266666666666666663,0.866666666666666696,0.733333333333333282],"xyz":[0.372078476903556277,0.565272813929761364,0.55965261248210374],"hpluv":[165.306614809553963,125.005338667233715,79.9129735834354733],"hsluv":[165.306614809553963,89.4504295982059574,79.9129735834354733]},"#44ddcc":{"lch":[80.3474616163736783,57.6077690930220925,178.158710030216184],"luv":[80.3474616163736783,-57.5780241737671616,1.85099760130491053],"rgb":[0.266666666666666663,0.866666666666666696,0.8],"xyz":[0.391370852347278,0.572989764107250221,0.661259123152373895],"hpluv":[178.158710030216184,121.786592068950441,80.3474616163736783],"hsluv":[178.158710030216184,89.8734379183952399,80.3474616163736783]},"#44dddd":{"lch":[80.8275029051271758,57.7489755309586,192.177050630061132],"luv":[80.8275029051271758,-56.4496501662069505,-12.1811810177875159],"rgb":[0.266666666666666663,0.866666666666666696,0.866666666666666696],"xyz":[0.412889177897911575,0.581597094327503727,0.774588971052379893],"hpluv":[192.177050630061132,125.674721736272474,80.8275029051271758],"hsluv":[192.177050630061132,90.3069463225795204,80.8275029051271758]},"#44ddee":{"lch":[81.3532277894993143,61.361693698739991,205.642938459455962],"luv":[81.3532277894993143,-55.3180860243278758,-26.5549771640468073],"rgb":[0.266666666666666663,0.866666666666666696,0.933333333333333348],"xyz":[0.436701358164086284,0.591121966433973745,0.899999787120903116],"hpluv":[205.642938459455962,137.939634766348263,81.3532277894993143],"hsluv":[205.642938459455962,90.7453615563817806,81.3532277894993143]},"#44ddff":{"lch":[81.9245576129038113,68.0382655080336463,217.195369709248553],"luv":[81.9245576129038113,-54.1978382178125813,-41.1314953029609],"rgb":[0.266666666666666663,0.866666666666666696,1],"xyz":[0.462872406573917705,0.601590385797906468,1.03783397541268507],"hpluv":[217.195369709248553,158.576151866946,81.9245576129038113],"hsluv":[217.195369709248553,99.9999999999957367,81.9245576129038113]},"#44ee00":{"lch":[83.112739541513335,123.476763986331008,125.23710114083579],"luv":[83.112739541513335,-71.241317589729718,100.852297507867192],"rgb":[0.266666666666666663,0.933333333333333348,0],"xyz":[0.329570394512602505,0.623755623118204428,0.103028081943196154],"hpluv":[125.23710114083579,311.240798427125753,83.112739541513335],"hsluv":[125.23710114083579,100.000000000002402,83.112739541513335]},"#44ee11":{"lch":[83.1341682891089135,122.626446998812852,125.466600012922257],"luv":[83.1341682891089135,-71.1513320296005674,99.8735873690646656],"rgb":[0.266666666666666663,0.933333333333333348,0.0666666666666666657],"xyz":[0.330582060012239609,0.624160289318059336,0.10835618690795179],"hpluv":[125.466600012922257,309.547675363147619,83.1341682891089135],"hsluv":[125.466600012922257,98.9247180409442279,83.1341682891089135]},"#44ee22":{"lch":[83.1738669889620184,121.064908518289769,125.897986234483838],"luv":[83.1738669889620184,-70.9856689153146192,98.0701120789979],"rgb":[0.266666666666666663,0.933333333333333348,0.133333333333333331],"xyz":[0.332457418150716666,0.624910432573450136,0.118233073103930983],"hpluv":[125.897986234483838,306.432309176179558,83.1738669889620184],"hsluv":[125.897986234483838,96.9444732717922,83.1738669889620184]},"#44ee33":{"lch":[83.2391611795664517,118.535427876706891,126.625494433478437],"luv":[83.2391611795664517,-70.7161072615436694,95.1308563805026921],"rgb":[0.266666666666666663,0.933333333333333348,0.2],"xyz":[0.335545168883174372,0.626145532866433263,0.134495226961542119],"hpluv":[126.625494433478437,301.369067751793693,83.2391611795664517],"hsluv":[126.625494433478437,93.7204451717133651,83.2391611795664517]},"#44ee44":{"lch":[83.3332795320092714,114.974418092600288,127.715012949240275],"luv":[83.3332795320092714,-70.3337997514069855,90.9520391649414],"rgb":[0.266666666666666663,0.933333333333333348,0.266666666666666663],"xyz":[0.340003164127393287,0.627928730964120829,0.157974001914428758],"hpluv":[127.715012949240275,294.205765091151079,83.3332795320092714],"hsluv":[127.715012949240275,89.1439564147074321,83.3332795320092714]},"#44ee55":{"lch":[83.4588814464859183,110.379279114867671,129.248151137931956],"luv":[83.4588814464859183,-69.8347997913980123,85.479155330485213],"rgb":[0.266666666666666663,0.933333333333333348,0.333333333333333315],"xyz":[0.345965578166755272,0.630313696579865579,0.189376049188402673],"hpluv":[129.248151137931956,284.901382538762221,83.4588814464859183],"hsluv":[129.248151137931956,89.2862876088480419,83.4588814464859183]},"#44ee66":{"lch":[83.6182069813856,104.810737833959209,131.33226272314829],"luv":[83.6182069813856,-69.2195888954281,78.7015837099029],"rgb":[0.266666666666666663,0.933333333333333348,0.4],"xyz":[0.353550573940263457,0.633347694889268897,0.229323693595546635],"hpluv":[131.33226272314829,273.53562680177663,83.6182069813856],"hsluv":[131.33226272314829,89.462046779026835,83.6182069813856]},"#44ee77":{"lch":[83.8131566406418642,98.3993759238413759,134.112401675041724],"luv":[83.8131566406418642,-68.4926783274834889,70.6483559449852123],"rgb":[0.266666666666666663,0.933333333333333348,0.466666666666666674],"xyz":[0.362864586960465363,0.637073300097349748,0.278377495501944572],"hpluv":[134.112401675041724,260.333399951005049,83.8131566406418642],"hsluv":[134.112401675041724,89.6701381262035682,83.8131566406418642]},"#44ee88":{"lch":[84.045338735079568,91.3569443918750892,137.785521400150031],"luv":[84.045338735079568,-67.6621349200187439,61.3834406553211949],"rgb":[0.266666666666666663,0.933333333333333348,0.533333333333333326],"xyz":[0.374005004062409163,0.641529466938127291,0.337050358905516712],"hpluv":[137.785521400150031,245.709311488591595,84.045338735079568],"hsluv":[137.785521400150031,89.9084899734552323,84.045338735079568]},"#44ee99":{"lch":[84.3160998906388386,83.9946679616676306,142.613931790318958],"luv":[84.3160998906388386,-66.738995210465,51.0001055321292895],"rgb":[0.266666666666666663,0.933333333333333348,0.6],"xyz":[0.387061968171481863,0.646752252581756504,0.405817036546634591],"hpluv":[142.613931790318958,230.343048149298568,84.3160998906388386],"hsluv":[142.613931790318958,90.1742147406472725,84.3160998906388386]},"#44eeaa":{"lch":[84.626546237332235,76.7502660373389887,148.925817786423067],"luv":[84.626546237332235,-65.7365837009088239,39.6144531722415607],"rgb":[0.266666666666666663,0.933333333333333348,0.66666666666666663],"xyz":[0.402119661136734419,0.652775329767857571,0.485120886163633247],"hpluv":[148.925817786423067,215.298316825794302,84.626546237332235],"hsluv":[148.925817786423067,90.4637941794664897,84.626546237332235]},"#44eebb":{"lch":[84.9775593290447,70.218708007349818,157.069253127653155],"luv":[84.9775593290447,-64.6697768267590618,27.3584889823731068],"rgb":[0.266666666666666663,0.933333333333333348,0.733333333333333282],"xyz":[0.419257253244071093,0.659630366610792329,0.575378871262274938],"hpluv":[157.069253127653155,202.183693696822303,84.9775593290447],"hsluv":[157.069253127653155,90.7732788992861401,84.9775593290447]},"#44eecc":{"lch":[85.3698091329633826,65.1592886039499462,167.256585364158155],"luv":[85.3698091329633826,-63.5542641697608914,14.3731832665241086],"rgb":[0.266666666666666663,0.933333333333333348,0.8],"xyz":[0.438549628687792792,0.667347316788281186,0.676985381932545094],"hpluv":[167.256585364158155,193.290067765431047,85.3698091329633826],"hsluv":[167.256585364158155,91.0984884260964,85.3698091329633826]},"#44eedd":{"lch":[85.803765500838054,62.4110099600490216,179.263728091065275],"luv":[85.803765500838054,-62.4058570040272613,0.801982435119061421],"rgb":[0.266666666666666663,0.933333333333333348,0.866666666666666696],"xyz":[0.460067954238426391,0.675954647008534693,0.790315229832551092],"hpluv":[179.263728091065275,191.499842549603557,85.803765500838054],"hsluv":[179.263728091065275,91.4351983708881875,85.803765500838054]},"#44eeee":{"lch":[86.2797089909746546,62.6494691870182407,192.17705063006116],"luv":[86.2797089909746546,-61.2398849709435922,-13.2148582346064085],"rgb":[0.266666666666666663,0.933333333333333348,0.933333333333333348],"xyz":[0.4838801345046011,0.68547951911500471,0.915726045901074315],"hpluv":[192.17705063006116,199.700166684316315,86.2797089909746546],"hsluv":[192.17705063006116,91.7793037580661775,86.2797089909746546]},"#44eeff":{"lch":[86.7977415696122847,66.0848691943621134,204.633388514668525],"luv":[86.7977415696122847,-60.0707080483631159,-27.5448719547627086],"rgb":[0.266666666666666663,0.933333333333333348,1],"xyz":[0.510051182914432522,0.695947938478937433,1.05356023419285627],"hpluv":[204.633388514668525,219.870556477974674,86.7977415696122847],"hsluv":[204.633388514668525,99.9999999999936904,86.7977415696122847]},"#44ff00":{"lch":[88.3264513606833,131.987460278186802,125.602389702763816],"luv":[88.3264513606833,-76.837408418496949,107.315899745634312],"rgb":[0.266666666666666663,1,0],"xyz":[0.381422766942276337,0.727460367977553535,0.120312206086420265],"hpluv":[125.602389702763816,502.990651378155178,88.3264513606833],"hsluv":[125.602389702763816,100.000000000002331,88.3264513606833]},"#44ff11":{"lch":[88.3457924202418496,131.213348009411362,125.799444038401859],"luv":[88.3457924202418496,-76.7532223203665609,106.423143908077066],"rgb":[0.266666666666666663,1,0.0666666666666666657],"xyz":[0.382434432441913441,0.727865034177408443,0.125640311051175901],"hpluv":[125.799444038401859,500.950310911531346,88.3457924202418496],"hsluv":[125.799444038401859,99.9999999999917577,88.3457924202418496]},"#44ff22":{"lch":[88.3816266358799538,129.789896608084,126.169061428897493],"luv":[88.3816266358799538,-76.5980824061806089,104.776672180562713],"rgb":[0.266666666666666663,1,0.133333333333333331],"xyz":[0.384309790580390498,0.728615177432799244,0.13551719724715508],"hpluv":[126.169061428897493,497.190929074143924,88.3816266358799538],"hsluv":[126.169061428897493,99.9999999999915445,88.3816266358799538]},"#44ff33":{"lch":[88.4405736189592204,127.478814054469,126.790121098902588],"luv":[88.4405736189592204,-76.3452168675528071,102.089450454884],"rgb":[0.266666666666666663,1,0.2],"xyz":[0.387397541312848204,0.72985027772578237,0.15177935110476623],"hpluv":[126.790121098902588,491.06642972530841,88.4405736189592204],"hsluv":[126.790121098902588,99.9999999999916,88.4405736189592204]},"#44ff44":{"lch":[88.5255621746627099,124.213522374992053,127.715012949240247],"luv":[88.5255621746627099,-75.9856771103925,98.2607552122302],"rgb":[0.266666666666666663,1,0.266666666666666663],"xyz":[0.391855536557067119,0.731633475823469936,0.175258126057652869],"hpluv":[127.715012949240247,482.369437382385513,88.5255621746627099],"hsluv":[127.715012949240247,99.9999999999915872,88.5255621746627099]},"#44ff55":{"lch":[88.6390158335401,119.977757557138,129.006344472088813],"luv":[88.6390158335401,-75.5147735105559832,93.2318684253877734],"rgb":[0.266666666666666663,1,0.333333333333333315],"xyz":[0.397817950596429104,0.734018441439214686,0.206660173331626784],"hpluv":[129.006344472088813,471.012302242813519,88.6390158335401],"hsluv":[129.006344472088813,99.9999999999916724,88.6390158335401]},"#44ff66":{"lch":[88.7829895920100256,114.806361082699226,130.743859599912923],"luv":[88.7829895920100256,-74.9316504675157518,86.9813100801842438],"rgb":[0.266666666666666663,1,0.4],"xyz":[0.405402946369937289,0.737052439748618,0.246607817738770746],"hpluv":[130.743859599912923,457.03528250903878,88.7829895920100256],"hsluv":[130.743859599912923,99.999999999991374,88.7829895920100256]},"#44ff77":{"lch":[88.9592430558717524,108.789243130847709,133.032335199193767],"luv":[88.9592430558717524,-74.2389756563468239,79.5215311376676226],"rgb":[0.266666666666666663,1,0.466666666666666674],"xyz":[0.414716959390139195,0.740778044956698856,0.295661619645168683],"hpluv":[133.032335199193767,440.631455855157412,88.9592430558717524],"hsluv":[133.032335199193767,99.999999999991374,88.9592430558717524]},"#44ff88":{"lch":[89.1692840038805343,102.078340317719523,136.01097660716411],"luv":[89.1692840038805343,-73.4425963051882462,70.8955048643657904],"rgb":[0.266666666666666663,1,0.533333333333333326],"xyz":[0.425857376492083,0.745234211797476398,0.354334483048740823],"hpluv":[136.01097660716411,422.1930512248951,89.1692840038805343],"hsluv":[136.01097660716411,99.9999999999912177,89.1692840038805343]},"#44ff99":{"lch":[89.4143964062191117,94.8987049380611438,139.863519733640288],"luv":[89.4143964062191117,-72.5511163277215303,61.1727040314764139],"rgb":[0.266666666666666663,1,0.6],"xyz":[0.43891434060115575,0.750456997441105611,0.423101160689858702],"hpluv":[139.863519733640288,402.3908266141122,89.4143964062191117],"hsluv":[139.863519733640288,99.9999999999912,89.4143964062191117]},"#44ffaa":{"lch":[89.695659684091666,87.5652599917726207,144.82485232612342],"luv":[89.695659684091666,-71.5753927145854192,50.4444042008586777],"rgb":[0.266666666666666663,1,0.66666666666666663],"xyz":[0.453972033566408251,0.756480074627206678,0.502405010306857358],"hpluv":[144.82485232612342,382.304282325397367,89.695659684091666],"hsluv":[144.82485232612342,99.9999999999909335,89.695659684091666]},"#44ffbb":{"lch":[90.0139628620153616,80.5050918065685153,151.171682460988421],"luv":[90.0139628620153616,-70.527972915407986,38.8184858440859557],"rgb":[0.266666666666666663,1,0.733333333333333282],"xyz":[0.471109625673744925,0.763335111470141436,0.592662995405499],"hpluv":[151.171682460988421,363.621116250194575,90.0139628620153616],"hsluv":[151.171682460988421,99.999999999990834,90.0139628620153616]},"#44ffcc":{"lch":[90.3700157308713443,74.2777558665274853,159.169074542576084],"luv":[90.3700157308713443,-69.4225064855060481,26.4140229771485018],"rgb":[0.266666666666666663,1,0.8],"xyz":[0.490402001117466679,0.771052061647630294,0.694269506075769205],"hpluv":[159.169074542576084,348.900804743837909,90.3700157308713443],"hsluv":[159.169074542576084,99.9999999999905924,90.3700157308713443]},"#44ffdd":{"lch":[90.7643583149998,69.56728840997188,168.931262835156701],"luv":[90.7643583149998,-68.2731674827513899,13.3559806299794577],"rgb":[0.266666666666666663,1,0.866666666666666696],"xyz":[0.511920326668100167,0.7796593918678838,0.807599353975775203],"hpluv":[168.931262835156701,341.810509676969502,90.7643583149998],"hsluv":[168.931262835156701,99.9999999999902798,90.7643583149998]},"#44ffee":{"lch":[91.1973694573754869,67.0945142582603182,180.196137266844971],"luv":[91.1973694573754869,-67.094121132442,-0.229680249688981986],"rgb":[0.266666666666666663,1,0.933333333333333348],"xyz":[0.535732506934274877,0.789184263974353817,0.933010170044298426],"hpluv":[180.196137266844971,347.079488330816218,91.1973694573754869],"hsluv":[180.196137266844971,99.999999999989825,91.1973694573754869]},"#44ffff":{"lch":[91.6692750397398726,67.4158875874256,192.177050630061103],"luv":[91.6692750397398726,-65.8990611515587261,-14.2202545175369188],"rgb":[0.266666666666666663,1,1],"xyz":[0.561903555344106298,0.799652683338286541,1.07084435833608027],"hpluv":[192.177050630061103,369.886157390881351,91.6692750397398726],"hsluv":[192.177050630061103,99.9999999999897,91.6692750397398726]},"#33aa00":{"lch":[61.1785977172963129,90.1064171712311435,124.683940112874311],"luv":[61.1785977172963129,-51.2749716142469723,74.09482911373847],"rgb":[0.2,0.66666666666666663,0],"xyz":[0.157393059993970491,0.294521282349826385,0.0485535951906325494],"hpluv":[124.683940112874311,186.894073454811917,61.1785977172963129],"hsluv":[124.683940112874311,100.000000000002302,61.1785977172963129]},"#33aa11":{"lch":[61.2139288108167818,88.7849168066190089,125.171000261233829],"luv":[61.2139288108167818,-51.1417680861379793,72.5760360544852148],"rgb":[0.2,0.66666666666666663,0.0666666666666666657],"xyz":[0.158404725493607623,0.294925948549681238,0.0538817001553881791],"hpluv":[125.171000261233829,184.046797309440706,61.2139288108167818],"hsluv":[125.171000261233829,97.729263879491441,61.2139288108167818]},"#33aa22":{"lch":[61.2793378507832642,86.3832953662584657,126.10140218084841],"luv":[61.2793378507832642,-50.8984310656693708,69.7955831939783593],"rgb":[0.2,0.66666666666666663,0.133333333333333331],"xyz":[0.160280083632084625,0.295676091805072039,0.0637585863513673717],"hpluv":[126.10140218084841,178.877217305585333,61.2793378507832642],"hsluv":[126.10140218084841,93.5778090815338146,61.2793378507832642]},"#33aa33":{"lch":[61.3867923044640946,82.5646745763668548,127.715012949240119],"luv":[61.3867923044640946,-50.5076466968263134,65.3138814728533],"rgb":[0.2,0.66666666666666663,0.2],"xyz":[0.163367834364542386,0.296911192098055166,0.0800207402089785219],"hpluv":[127.715012949240119,170.670578118814461,61.3867923044640946],"hsluv":[127.715012949240119,86.9017438736093339,61.3867923044640946]},"#33aa44":{"lch":[61.5414071550205364,77.3485744588317488,130.237764523164799],"luv":[61.5414071550205364,-49.9641607354037305,59.0456146789935588],"rgb":[0.2,0.66666666666666663,0.266666666666666663],"xyz":[0.167825829608761246,0.298694390195742732,0.10349951516186516],"hpluv":[130.237764523164799,159.486606837004757,61.5414071550205364],"hsluv":[130.237764523164799,87.1702267355774723,61.5414071550205364]},"#33aa55":{"lch":[61.7472402279952775,70.9239260559490106,134.00596147156574],"luv":[61.7472402279952775,-49.2732069613111605,51.0132763399638876],"rgb":[0.2,0.66666666666666663,0.333333333333333315],"xyz":[0.173788243648123231,0.301079355811487592,0.134901562435839062],"hpluv":[134.00596147156574,145.752006815371971,61.7472402279952775],"hsluv":[134.00596147156574,87.512567621072165,61.7472402279952775]},"#33aa66":{"lch":[62.0075227235960824,63.6834089970413046,139.532932917076664],"luv":[62.0075227235960824,-48.4490087982300253,41.3312246123130436],"rgb":[0.2,0.66666666666666663,0.4],"xyz":[0.181373239421631416,0.304113354120890911,0.174849206842983024],"hpluv":[139.532932917076664,130.323054003441854,62.0075227235960824],"hsluv":[139.532932917076664,87.9225345315596769,62.0075227235960824]},"#33aa77":{"lch":[62.3247799262656201,56.2910074750267,147.571074265173024],"luv":[62.3247799262656201,-47.5128361285441727,30.1862207898839152],"rgb":[0.2,0.66666666666666663,0.466666666666666674],"xyz":[0.190687252441833321,0.307838959328971706,0.223903008749380933],"hpluv":[147.571074265173024,114.608702125460667,62.3247799262656201],"hsluv":[147.571074265173024,88.3905588997681519,62.3247799262656201]},"#33aa88":{"lch":[62.7009046876535052,49.786919253891476,159.033972270618222],"luv":[62.7009046876535052,-46.4906641824602147,17.8144736848221363],"rgb":[0.2,0.66666666666666663,0.533333333333333326],"xyz":[0.201827669543777177,0.312295126169749304,0.2825758721529531],"hpluv":[159.033972270618222,100.758286424528237,62.7009046876535052],"hsluv":[159.033972270618222,88.9048289963628804,62.7009046876535052]},"#33aa99":{"lch":[63.1372095297142835,45.6309193537352797,174.368717478757389],"luv":[63.1372095297142835,-45.4107033068770818,4.47759156711236095],"rgb":[0.2,0.66666666666666663,0.6],"xyz":[0.214884633652849877,0.317517911813378462,0.351342549794071035],"hpluv":[174.368717478757389,91.7092542399893631,63.1372095297142835],"hsluv":[174.368717478757389,89.4524406674979,63.1372095297142835]},"#33aaaa":{"lch":[63.6344696573538897,45.3208071547743288,192.17705063006116],"luv":[63.6344696573538897,-44.3011098571894,-9.5596666563997],"rgb":[0.2,0.66666666666666663,0.66666666666666663],"xyz":[0.229942326618102433,0.323540988999479584,0.430646399411069636],"hpluv":[192.17705063006116,90.3742140686623117,63.6344696573538897],"hsluv":[192.17705063006116,90.0204628815860559,63.6344696573538897]},"#33aabb":{"lch":[64.1929631055189844,49.4317459506583177,209.109442205543161],"luv":[64.1929631055189844,-43.188124160558381,-24.0475245965695663],"rgb":[0.2,0.66666666666666663,0.733333333333333282],"xyz":[0.247079918725439052,0.330396025842414343,0.520904384509711327],"hpluv":[209.109442205543161,97.7142389408223835,64.1929631055189844],"hsluv":[209.109442205543161,90.5968047396532228,64.1929631055189844]},"#33aacc":{"lch":[64.8125111239688181,57.2242456540803062,222.641155468482083],"luv":[64.8125111239688181,-42.0947673064025736,-38.7639633693247347],"rgb":[0.2,0.66666666666666663,0.8],"xyz":[0.266372294169160806,0.338112976019903144,0.622510895179981483],"hpluv":[222.641155468482083,112.036763534802631,64.8125111239688181],"hsluv":[222.641155468482083,91.1708232266795875,64.8125111239688181]},"#33aadd":{"lch":[65.4925201274692199,67.4454999587780151,232.519386199289158],"luv":[65.4925201274692199,-41.0401119544032653,-53.5220017886062465],"rgb":[0.2,0.66666666666666663,0.866666666666666696],"xyz":[0.28789061971979435,0.34672030624015665,0.73584074307998748],"hpluv":[232.519386199289158,130.67743538587149,65.4925201274692199],"hsluv":[232.519386199289158,91.7336648454097485,65.4925201274692199]},"#33aaee":{"lch":[66.23202547083838,79.0605595482254,239.573325902293959],"luv":[66.23202547083838,-40.039054494753934,-68.1721804788773],"rgb":[0.2,0.66666666666666663,0.933333333333333348],"xyz":[0.311702799985969059,0.356245178346626667,0.861251559148510704],"hpluv":[239.573325902293959,151.471586303299148,66.23202547083838],"hsluv":[239.573325902293959,92.278374899274425,66.23202547083838]},"#33aaff":{"lch":[67.0297366624436,91.3892467801412778,244.667711773110682],"luv":[67.0297366624436,-39.1024682991195291,-82.6014007142609898],"rgb":[0.2,0.66666666666666663,1],"xyz":[0.33787384839580048,0.366713597710559391,0.999085747440292549],"hpluv":[244.667711773110682,173.00828905748071,67.0297366624436],"hsluv":[244.667711773110682,99.9999999999982094,67.0297366624436]},"#33bb00":{"lch":[66.705199456007648,99.1588934495857757,125.274120260315158],"luv":[66.705199456007648,-57.2631629787864327,80.9531735993793262],"rgb":[0.2,0.733333333333333282,0],"xyz":[0.191347557902569271,0.362430278167024944,0.0598717611601651684],"hpluv":[125.274120260315158,188.630237299381349,66.705199456007648],"hsluv":[125.274120260315158,100.000000000002331,66.705199456007648]},"#33bb11":{"lch":[66.7359690986495764,97.9890755357957914,125.670572132139952],"luv":[66.7359690986495764,-57.1397853669544133,79.6046723036925385],"rgb":[0.2,0.733333333333333282,0.0666666666666666657],"xyz":[0.192359223402206403,0.362834944366879797,0.0651998661249208],"hpluv":[125.670572132139952,186.318944611331347,66.7359690986495764],"hsluv":[125.670572132139952,98.1524285745497451,66.7359690986495764]},"#33bb22":{"lch":[66.7929473545782,95.8553977164860243,126.423299967719473],"luv":[66.7929473545782,-56.9137739802675,77.1302768224563],"rgb":[0.2,0.733333333333333282,0.133333333333333331],"xyz":[0.194234581540683404,0.363585087622270597,0.0750767523209],"hpluv":[126.423299967719473,182.106434833594022,66.7929473545782],"hsluv":[126.423299967719473,94.7659081903439073,66.7929473545782]},"#33bb33":{"lch":[66.8865907457163,92.4406335233364302,127.715012949240233],"luv":[66.8865907457163,-56.5491099236273058,73.126389853740946],"rgb":[0.2,0.733333333333333282,0.2],"xyz":[0.197322332273141166,0.364820187915253724,0.0913389061785111478],"hpluv":[127.715012949240233,175.373180985258983,66.8865907457163],"hsluv":[127.715012949240233,89.2962069049265637,66.8865907457163]},"#33bb44":{"lch":[67.0214179407225572,87.725631811763563,129.70178400392939],"luv":[67.0214179407225572,-56.0384119529137763,67.4943172612971409],"rgb":[0.2,0.733333333333333282,0.266666666666666663],"xyz":[0.201780327517360025,0.36660338601294129,0.114817681131397786],"hpluv":[129.70178400392939,166.093340387543549,67.0214179407225572],"hsluv":[129.70178400392939,89.4761749642590871,67.0214179407225572]},"#33bb55":{"lch":[67.2010629421400552,81.8171313208689099,132.60288320444127],"luv":[67.2010629421400552,-55.3830806540106479,60.2225651632978796],"rgb":[0.2,0.733333333333333282,0.333333333333333315],"xyz":[0.207742741556722,0.368988351628686151,0.146219728405371674],"hpluv":[132.60288320444127,154.492511096020365,67.2010629421400552],"hsluv":[132.60288320444127,89.7076242739581,67.2010629421400552]},"#33bb66":{"lch":[67.4284803792762091,74.9653268862145,136.738510871982356],"luv":[67.4284803792762091,-54.5922668909562248,51.3759148907695788],"rgb":[0.2,0.733333333333333282,0.4],"xyz":[0.215327737330230196,0.372022349938089469,0.186167372812515663],"hpluv":[136.738510871982356,141.07705768332076,67.4284803792762091],"hsluv":[136.738510871982356,89.9877463438330096,67.4284803792762091]},"#33bb77":{"lch":[67.7060530794905446,67.5982244112705,142.572908280802977],"luv":[67.7060530794905446,-53.681598162732449,41.0829156980295878],"rgb":[0.2,0.733333333333333282,0.466666666666666674],"xyz":[0.224641750350432101,0.375747955146170265,0.235221174718913573],"hpluv":[142.572908280802977,126.69139486293237,67.7060530794905446],"hsluv":[142.572908280802977,90.3115397167098,67.7060530794905446]},"#33bb88":{"lch":[68.0356563096068641,60.380187227113133,150.730801091974854],"luv":[68.0356563096068641,-52.67158330257773,29.5206931148449],"rgb":[0.2,0.733333333333333282,0.533333333333333326],"xyz":[0.235782167452375957,0.380204121986947863,0.293894038122485712],"hpluv":[150.730801091974854,112.615249481580875,68.0356563096068641],"hsluv":[150.730801091974854,90.6723452470342437,68.0356563096068641]},"#33bb99":{"lch":[68.4187011865960244,54.2829584497859159,161.862695711717],"luv":[68.4187011865960244,-51.585814888834193,16.8980259295610082],"rgb":[0.2,0.733333333333333282,0.6],"xyz":[0.248839131561448657,0.385426907630577,0.362660715763603647],"hpluv":[161.862695711717,100.676477021468287,68.4187011865960244],"hsluv":[161.862695711717,91.0624469223214,68.4187011865960244]},"#33bbaa":{"lch":[68.8561680799326439,50.5661966451060749,176.101011456941364],"luv":[68.8561680799326439,-50.4491601398581224,3.43838397135738649],"rgb":[0.2,0.733333333333333282,0.66666666666666663],"xyz":[0.263896824526701212,0.391449984816678143,0.441964565380602248],"hpluv":[176.101011456941364,93.1873079321678404,68.8561680799326439],"hsluv":[176.101011456941364,91.473675634614068,68.8561680799326439]},"#33bbbb":{"lch":[69.3486356756669835,50.4205674478029,192.177050630061103],"luv":[69.3486356756669835,-49.286127891295429,-10.635375839212843],"rgb":[0.2,0.733333333333333282,0.733333333333333282],"xyz":[0.281034416634037831,0.398305021659612901,0.532222550479243939],"hpluv":[192.177050630061103,92.2590830970113132,69.3486356756669835],"hsluv":[192.177050630061103,91.8979539795913922,69.3486356756669835]},"#33bbcc":{"lch":[69.8963087653012423,54.2786660468549442,207.559867588447844],"luv":[69.8963087653012423,-48.1195504219082224,-25.1133919457216273],"rgb":[0.2,0.733333333333333282,0.8],"xyz":[0.300326792077759586,0.406021971837101703,0.633829061149514095],"hpluv":[207.559867588447844,98.540384199822455,69.8963087653012423],"hsluv":[207.559867588447844,92.3277362004695306,69.8963087653012423]},"#33bbdd":{"lch":[70.4990463576295241,61.569428837921933,220.28187220447964],"luv":[70.4990463576295241,-46.9696505240293618,-39.807618580850594],"rgb":[0.2,0.733333333333333282,0.866666666666666696],"xyz":[0.321845117628393129,0.414629302057355209,0.747158909049520092],"hpluv":[220.28187220447964,110.820781636478685,70.4990463576295241],"hsluv":[220.28187220447964,92.7563200135089119,70.4990463576295241]},"#33bbee":{"lch":[71.1563908243766576,71.2672074810155181,229.953995552192254],"luv":[71.1563908243766576,-45.8534981630350487,-54.557048750410388],"rgb":[0.2,0.733333333333333282,0.933333333333333348],"xyz":[0.345657297894567894,0.424154174163825226,0.872569725118043316],"hpluv":[229.953995552192254,127.091105244163856,71.1563908243766576],"hsluv":[229.953995552192254,93.1780289437208893,71.1563908243766576]},"#33bbff":{"lch":[71.8675982303626597,82.4526478797043296,237.101125866277243],"luv":[71.8675982303626597,-44.7848112977892,-69.2297610814592161],"rgb":[0.2,0.733333333333333282,1],"xyz":[0.37182834630439926,0.43462259352775795,1.01040391340982527],"hpluv":[237.101125866277243,145.583046200088774,71.8675982303626597],"hsluv":[237.101125866277243,99.9999999999977831,71.8675982303626597]},"#33cc00":{"lch":[72.1534232831706532,108.011475964841438,125.713046635977918],"luv":[72.1534232831706532,-63.0491190384013507,87.6999859098336287],"rgb":[0.2,0.8,0],"xyz":[0.229571301212186191,0.438877764786259839,0.0726130089300371234],"hpluv":[125.713046635977918,189.955680955455,72.1534232831706532],"hsluv":[125.713046635977918,100.000000000002402,72.1534232831706532]},"#33cc11":{"lch":[72.1805088449519,106.967132064598133,126.040754358939225],"luv":[72.1805088449519,-62.9352412435677095,86.493483868665578],"rgb":[0.2,0.8,0.0666666666666666657],"xyz":[0.230582966711823323,0.439282430986114691,0.0779411138947927601],"hpluv":[126.040754358939225,188.048441784684599,72.1805088449519],"hsluv":[126.040754358939225,98.4728126855506645,72.1805088449519]},"#33cc22":{"lch":[72.2306742907645543,105.057034533260762,126.660198785960176],"luv":[72.2306742907645543,-62.7261976516662614,84.2757653960309199],"rgb":[0.2,0.8,0.133333333333333331],"xyz":[0.232458324850300324,0.440032574241505492,0.0878180000907719527],"hpluv":[126.660198785960176,184.562215611711281,72.2306742907645543],"hsluv":[126.660198785960176,95.6680740449206866,72.2306742907645543]},"#33cc33":{"lch":[72.31314692234902,101.984984863208481,127.715012949240304],"luv":[72.31314692234902,-62.3877173898115416,80.6765756365369668],"rgb":[0.2,0.8,0.2],"xyz":[0.235546075582758085,0.441267674534488619,0.104080153948383103],"hpluv":[127.715012949240304,178.960959976488198,72.31314692234902],"hsluv":[127.715012949240304,91.1230258822071306,72.31314692234902]},"#33cc44":{"lch":[72.4319472107582669,97.7091257880760651,129.318260791805528],"luv":[72.4319472107582669,-61.9111863445413135,75.5915224590797123],"rgb":[0.2,0.8,0.266666666666666663],"xyz":[0.240004070826976945,0.443050872632176185,0.127558928901269741],"hpluv":[129.318260791805528,171.176559629977817,72.4319472107582669],"hsluv":[129.318260791805528,91.2471619418673612,72.4319472107582669]},"#33cc55":{"lch":[72.590341240881628,92.2844112105744756,131.621023493746776],"luv":[72.590341240881628,-61.2953573189119396,68.9876200751215407],"rgb":[0.2,0.8,0.333333333333333315],"xyz":[0.24596648486633893,0.445435838247921045,0.158960976175243629],"hpluv":[131.621023493746776,161.32023063104279,72.590341240881628],"hsluv":[131.621023493746776,91.4078622695478,72.590341240881628]},"#33cc66":{"lch":[72.7910248315973405,85.8719567505974197,134.835055825888389],"luv":[72.7910248315973405,-60.5455878238572112,60.8951948123993319],"rgb":[0.2,0.8,0.4],"xyz":[0.253551480639847115,0.448469836557324364,0.198908620582387619],"hpluv":[134.835055825888389,149.696915507144809,72.7910248315973405],"hsluv":[134.835055825888389,91.6039613293452533,72.7910248315973405]},"#33cc77":{"lch":[73.0362204241858421,78.757716060864837,139.259917231121676],"luv":[73.0362204241858421,-59.6729854923348,51.3995393126768079],"rgb":[0.2,0.8,0.466666666666666674],"xyz":[0.262865493660049,0.452195441765405159,0.247962422488785528],"hpluv":[139.259917231121676,136.834039856532058,73.0362204241858421],"hsluv":[139.259917231121676,91.8328510325735294,73.0362204241858421]},"#33cc88":{"lch":[73.3277345291399,71.3846311778678597,145.306874573990314],"luv":[73.3277345291399,-58.6933246064594201,40.6307668527313197],"rgb":[0.2,0.8,0.533333333333333326],"xyz":[0.274005910761992877,0.456651608606182757,0.306635285892357667],"hpluv":[145.306874573990314,123.530949311180805,73.3277345291399],"hsluv":[145.306874573990314,92.0907512285691894,73.3277345291399]},"#33cc99":{"lch":[73.6669954969027714,64.400374936046,153.483372150156],"luv":[73.6669954969027714,-57.6257667092137709,28.7520312861295437],"rgb":[0.2,0.8,0.6],"xyz":[0.287062874871065576,0.461874394249811915,0.375401963533475602],"hpluv":[153.483372150156,110.931469165383049,73.6669954969027714],"hsluv":[153.483372150156,92.3730273510429072,73.6669954969027714]},"#33ccaa":{"lch":[74.0550811623464114,58.6991946004706691,164.236139418897579],"luv":[74.0550811623464114,-56.4914910882685106,15.9470022690160835],"rgb":[0.2,0.8,0.66666666666666663],"xyz":[0.302120567836318132,0.467897471435913037,0.454705813150474203],"hpluv":[164.236139418897579,100.581152280716978,74.0550811623464114],"hsluv":[164.236139418897579,92.6745296641919794,74.0550811623464114]},"#33ccbb":{"lch":[74.4927414449451106,55.3647402049724846,177.507530206592946],"luv":[74.4927414449451106,-55.3123621552270137,2.40770653799565881],"rgb":[0.2,0.8,0.733333333333333282],"xyz":[0.319258159943654751,0.474752508278847796,0.544963798249115894],"hpluv":[177.507530206592946,94.310193436061823,74.4927414449451106],"hsluv":[177.507530206592946,92.9899230693886,74.4927414449451106]},"#33cccc":{"lch":[74.9804187561532416,55.3552144916165361,192.177050630061132],"luv":[74.9804187561532416,-54.1097476482840918,-11.6762571422475752],"rgb":[0.2,0.8,0.8],"xyz":[0.338550535387376506,0.482469458456336597,0.646570308919386],"hpluv":[192.177050630061132,93.6806731785530928,74.9804187561532416],"hsluv":[192.177050630061132,93.3139795405001422,74.9804187561532416]},"#33ccdd":{"lch":[75.5182678303382602,59.0031963362726231,206.282454691493683],"luv":[75.5182678303382602,-52.9035678654544128,-26.1264173778571198],"rgb":[0.2,0.8,0.866666666666666696],"xyz":[0.360068860938010049,0.491076788676590104,0.759900156819392],"hpluv":[206.282454691493683,99.1431801932779564,75.5182678303382602],"hsluv":[206.282454691493683,93.6418135046530296,75.5182678303382602]},"#33ccee":{"lch":[76.106175853756767,65.8577115847402439,218.26062431545347],"luv":[76.106175853756767,-51.7116147040808585,-40.7817003063324606],"rgb":[0.2,0.8,0.933333333333333348],"xyz":[0.383881041204184759,0.500601660783060121,0.885310972887915271],"hpluv":[218.26062431545347,110.229350215344013,76.106175853756767],"hsluv":[218.26062431545347,93.969050662624,76.106175853756767]},"#33ccff":{"lch":[76.7437832939395435,75.0714180144803,227.674056146546604],"luv":[76.7437832939395435,-50.5491406549608,-55.5022718611574248],"rgb":[0.2,0.8,1],"xyz":[0.41005208961401618,0.511070080146992844,1.02314516117969712],"hpluv":[227.674056146546604,129.845560156838474,76.7437832939395435],"hsluv":[227.674056146546604,99.9999999999969731,76.7437832939395435]},"#33dd00":{"lch":[77.5280782787270653,116.686614644285086,126.047543424376144],"luv":[77.5280782787270653,-68.6649809221669187,94.3445092843369508],"rgb":[0.2,0.866666666666666696,0],"xyz":[0.272205291759361367,0.524145745880611358,0.0868243391124284419],"hpluv":[126.047543424376144,210.356208283509261,77.5280782787270653],"hsluv":[126.047543424376144,100.000000000002416,77.5280782787270653]},"#33dd11":{"lch":[77.5521415069474926,115.747372453695789,126.322097671746874],"luv":[77.5521415069474926,-68.5599423432795,93.2576459912042],"rgb":[0.2,0.866666666666666696,0.0666666666666666657],"xyz":[0.273216957258998472,0.524550412080466266,0.0921524440771840786],"hpluv":[126.322097671746874,208.932074165120611,77.5521415069474926],"hsluv":[126.322097671746874,98.7203227917640902,77.5521415069474926]},"#33dd22":{"lch":[77.5967156031793337,114.025807364398673,126.839335004613],"luv":[77.5967156031793337,-68.36681588768,91.2571270119929778],"rgb":[0.2,0.866666666666666696,0.133333333333333331],"xyz":[0.275092315397475529,0.525300555335857067,0.102029330273163271],"hpluv":[126.839335004613,206.31706664059891,77.5967156031793337],"hsluv":[126.839335004613,96.3665979525037102,77.5967156031793337]},"#33dd33":{"lch":[77.670013861504259,111.246421345384377,127.715012949240332],"luv":[77.670013861504259,-68.0532561222895,88.0029578668175247],"rgb":[0.2,0.866666666666666696,0.2],"xyz":[0.278180066129933234,0.526535655628840193,0.118291484130774421],"hpluv":[127.715012949240332,202.082466523340599,77.670013861504259],"hsluv":[127.715012949240332,92.5426273046004439,77.670013861504259]},"#33dd44":{"lch":[77.7756375941771267,107.354265763003397,129.034195217585733],"luv":[77.7756375941771267,-67.6100090567609726,83.3895979895470134],"rgb":[0.2,0.866666666666666696,0.266666666666666663],"xyz":[0.28263806137415215,0.52831885372652776,0.14177025908366106],"hpluv":[129.034195217585733,196.125875311323085,77.7756375941771267],"hsluv":[129.034195217585733,92.6304308505642098,77.7756375941771267]},"#33dd55":{"lch":[77.9165348137244,102.370875286307594,130.905664069221132],"luv":[77.9165348137244,-67.0340391276217105,77.3707548439410431],"rgb":[0.2,0.866666666666666696,0.333333333333333315],"xyz":[0.288600475413514135,0.530703819342272509,0.173172306357634975],"hpluv":[130.905664069221132,188.454179514464698,77.9165348137244],"hsluv":[130.905664069221132,92.7446831943234287,77.9165348137244]},"#33dd66":{"lch":[78.095166356878579,96.3992072274516261,133.476315028685519],"luv":[78.095166356878579,-66.3279238591037767,69.9529389705828777],"rgb":[0.2,0.866666666666666696,0.4],"xyz":[0.29618547118702232,0.533737817651675828,0.213119950764778909],"hpluv":[133.476315028685519,179.196222734944627,78.095166356878579],"hsluv":[133.476315028685519,92.8850067954864187,78.095166356878579]},"#33dd77":{"lch":[78.3135937781308513,89.6343875602499196,136.948304354896891],"luv":[78.3135937781308513,-65.499258897229538,61.1896275296294192],"rgb":[0.2,0.866666666666666696,0.466666666666666674],"xyz":[0.305499484207224226,0.537463422859756679,0.262173752671176818],"hpluv":[136.948304354896891,168.630388284117117,78.3135937781308513],"hsluv":[136.948304354896891,93.050064801238122,78.3135937781308513]},"#33dd88":{"lch":[78.5735314106716487,82.3820261839553609,141.59738099104726],"luv":[78.5735314106716487,-64.5599157920348432,51.1743638074698],"rgb":[0.2,0.866666666666666696,0.533333333333333326],"xyz":[0.316639901309168,0.541919589700534221,0.320846616074749],"hpluv":[141.59738099104726,157.233383580683977,78.5735314106716487],"hsluv":[141.59738099104726,93.2377028740416449,78.5735314106716487]},"#33dd99":{"lch":[78.8763801167060592,75.0869406053615762,147.781507566587862],"luv":[78.8763801167060592,-63.5251386535812799,40.0325543591259105],"rgb":[0.2,0.866666666666666696,0.6],"xyz":[0.329696865418240725,0.547142375344163434,0.389613293715866893],"hpluv":[147.781507566587862,145.760006886720333,78.8763801167060592],"hsluv":[147.781507566587862,93.4451205095912343,78.8763801167060592]},"#33ddaa":{"lch":[79.2232512041385633,68.3697583649377094,155.904677195463563],"luv":[79.2232512041385633,-62.4125308872686801,27.9123601138582131],"rgb":[0.2,0.866666666666666696,0.66666666666666663],"xyz":[0.344754558383493281,0.553165452530264501,0.468917143332865494],"hpluv":[155.904677195463563,135.355769729163313,79.2232512041385633],"hsluv":[155.904677195463563,93.6690625743759,79.2232512041385633]},"#33ddbb":{"lch":[79.6149850527770866,63.045401416642612,166.259028854183981],"luv":[79.6149850527770866,-61.2410113290283604,14.9753521221847095],"rgb":[0.2,0.866666666666666696,0.733333333333333282],"xyz":[0.361892150490829956,0.560020489373199259,0.559175128431507296],"hpluv":[166.259028854183981,127.658944712944631,79.6149850527770866],"hsluv":[166.259028854183981,93.9060163408359614,79.6149850527770866]},"#33ddcc":{"lch":[80.0521670478692613,60.0458591823856054,178.675787060338223],"luv":[80.0521670478692613,-60.0298228841068138,1.3876488942262355],"rgb":[0.2,0.866666666666666696,0.8],"xyz":[0.381184525934551655,0.567737439550688117,0.660781639101777452],"hpluv":[178.675787060338223,124.734340702728062,80.0521670478692613],"hsluv":[178.675787060338223,94.1523985056595905,80.0521670478692613]},"#33dddd":{"lch":[80.5351423549551555,60.1510343961145963,192.177050630061245],"luv":[80.5351423549551555,-58.7976638126828,-12.6878551809710149],"rgb":[0.2,0.866666666666666696,0.866666666666666696],"xyz":[0.402702851485185254,0.576344769770941623,0.774111487001783449],"hpluv":[192.177050630061245,128.603021497070955,80.5351423549551555],"hsluv":[192.177050630061245,94.4047190696773271,80.5351423549551555]},"#33ddee":{"lch":[81.0640304387754,63.6213092914002303,205.209077734070348],"luv":[81.0640304387754,-57.5619892131040913,-27.0977562499646396],"rgb":[0.2,0.866666666666666696,0.933333333333333348],"xyz":[0.426515031751359963,0.58586964187741164,0.899522303070306672],"hpluv":[205.209077734070348,140.476637056352985,81.0640304387754],"hsluv":[205.209077734070348,94.6597131799347835,81.0640304387754]},"#33ddff":{"lch":[81.6387398294900208,70.0938175080633528,216.50946924270437],"luv":[81.6387398294900208,-56.3385046754299452,-41.7027114680837769],"rgb":[0.2,0.866666666666666696,1],"xyz":[0.452686080161191384,0.596338061241344364,1.03735649136208852],"hpluv":[216.50946924270437,160.421433033358312,81.6387398294900208],"hsluv":[216.50946924270437,99.999999999996,81.6387398294900208]},"#33ee00":{"lch":[82.833762600699373,125.203353646442437,126.3077634478595],"luv":[82.833762600699373,-74.1357070958390239,100.894879442497455],"rgb":[0.2,0.933333333333333348,0],"xyz":[0.319384068099876184,0.618503298561642323,0.102550597892599626],"hpluv":[126.3077634478595,309.713105305240845,82.833762600699373],"hsluv":[126.3077634478595,100.000000000002302,82.833762600699373]},"#33ee11":{"lch":[82.85531245284119,124.353122892884315,126.540515263097504],"luv":[82.85531245284119,-74.0387382831010541,99.9097813362598544],"rgb":[0.2,0.933333333333333348,0.0666666666666666657],"xyz":[0.320395733599513288,0.618907964761497231,0.107878702857355263],"hpluv":[126.540515263097504,308.054239915702169,82.85531245284119],"hsluv":[126.540515263097504,98.9149262576223833,82.85531245284119]},"#33ee22":{"lch":[82.8952353009988,122.792060636983948,126.977870705292972],"luv":[82.8952353009988,-73.860225327277135,98.0946342573363808],"rgb":[0.2,0.933333333333333348,0.133333333333333331],"xyz":[0.322271091737990345,0.619658108016888,0.117755589053334456],"hpluv":[126.977870705292972,305.002845011722627,82.8952353009988],"hsluv":[126.977870705292972,96.9167682151396264,82.8952353009988]},"#33ee33":{"lch":[82.9608975691188846,120.264250910780831,127.715012949240375],"luv":[82.9608975691188846,-73.5697721383487391,95.1366316128687259],"rgb":[0.2,0.933333333333333348,0.2],"xyz":[0.325358842470448051,0.620893208309871159,0.134017742910945592],"hpluv":[127.715012949240375,300.046240285686,82.9608975691188846],"hsluv":[127.715012949240375,93.6639064416312834,82.9608975691188846]},"#33ee44":{"lch":[83.0555452014946241,116.707569363843,128.817932535493583],"luv":[83.0555452014946241,-73.1578713419028,90.9317469728687513],"rgb":[0.2,0.933333333333333348,0.266666666666666663],"xyz":[0.329816837714666966,0.622676406407558725,0.157496517863832231],"hpluv":[128.817932535493583,293.039720989359807,83.0555452014946241],"hsluv":[128.817932535493583,93.7274034182796356,83.0555452014946241]},"#33ee55":{"lch":[83.1818510898783643,112.121671621867506,130.367812557605703],"luv":[83.1818510898783643,-72.6203079673681202,85.4257579305358092],"rgb":[0.2,0.933333333333333348,0.333333333333333315],"xyz":[0.335779251754028951,0.625061372023303474,0.188898565137806146],"hpluv":[130.367812557605703,283.950089878719211,83.1818510898783643],"hsluv":[130.367812557605703,93.8103653792530139,83.1818510898783643]},"#33ee66":{"lch":[83.3420657578551,106.5703857928128,132.470647679843353],"luv":[83.3420657578551,-71.9576476395269,78.6088040502757224],"rgb":[0.2,0.933333333333333348,0.4],"xyz":[0.343364247527537136,0.628095370332706793,0.228846209544950108],"hpluv":[132.470647679843353,272.865433725808,83.3420657578551],"hsluv":[132.470647679843353,93.912785079345241,83.3420657578551]},"#33ee77":{"lch":[83.5380975272703523,100.188150337510052,135.268396470867572],"luv":[83.5380975272703523,-71.1748024762597851,70.5110839550557387],"rgb":[0.2,0.933333333333333348,0.466666666666666674],"xyz":[0.352678260547739042,0.631820975540787644,0.277900011451348],"hpluv":[135.268396470867572,260.019238129472967,83.5380975272703523],"hsluv":[135.268396470867572,94.0340074276028304,83.5380975272703523]},"#33ee88":{"lch":[83.7715600973053682,93.1909370684561651,138.951686086792108],"luv":[83.7715600973053682,-70.2805135444840801,61.1980405537673],"rgb":[0.2,0.933333333333333348,0.533333333333333326],"xyz":[0.363818677649682842,0.636277142381565186,0.336572874854920157],"hpluv":[138.951686086792108,245.83342468256393,83.7715600973053682],"hsluv":[138.951686086792108,94.1728069818675237,83.7715600973053682]},"#33ee99":{"lch":[84.0438031984902807,85.8935006436990278,143.770719305914184],"luv":[84.0438031984902807,-69.2867121669879822,50.7646035138469784],"rgb":[0.2,0.933333333333333348,0.6],"xyz":[0.376875641758755542,0.641499928025194399,0.405339552496038091],"hpluv":[143.770719305914184,230.989810482694878,84.0438031984902807],"hsluv":[143.770719305914184,94.3274826341768886,84.0438031984902807]},"#33eeaa":{"lch":[84.3559338989094698,78.7339796376561907,150.032255922422308],"luv":[84.3559338989094698,-68.2077782157370223,39.328596980513943],"rgb":[0.2,0.933333333333333348,0.66666666666666663],"xyz":[0.391933334724008098,0.647523005211295466,0.484643402113036692],"hpluv":[150.032255922422308,216.540119706931335,84.3559338989094698],"hsluv":[150.032255922422308,94.495967075681591,84.3559338989094698]},"#33eebb":{"lch":[84.7088326356722,72.2999891840671,158.051587623557367],"luv":[84.7088326356722,-67.0597412553262,27.0236847743774931],"rgb":[0.2,0.933333333333333348,0.733333333333333282],"xyz":[0.409070926831344772,0.654378042054230225,0.574901387211678383],"hpluv":[158.051587623557367,204.04938686040532,84.7088326356722],"hsluv":[158.051587623557367,94.6759444498571838,84.7088326356722]},"#33eecc":{"lch":[85.1031663228954,67.3294619946068451,168.005441410177127],"luv":[85.1031663228954,-65.8594808644086,13.992327638881461],"rgb":[0.2,0.933333333333333348,0.8],"xyz":[0.428363302275066471,0.662094992231719082,0.676507897881948539],"hpluv":[168.005441410177127,195.708498626929867,85.1031663228954],"hsluv":[168.005441410177127,94.8649680125767389,85.1031663228954]},"#33eedd":{"lch":[85.539399954776755,64.6250931348259314,179.663789762776076],"luv":[85.539399954776755,-64.6239805156479861,0.37921629457989664],"rgb":[0.2,0.933333333333333348,0.866666666666666696],"xyz":[0.44988162782570007,0.670702322451972588,0.789837745781954537],"hpluv":[179.663789762776076,194.233009793031641,85.539399954776755],"hsluv":[179.663789762776076,95.0605698730458926,85.539399954776755]},"#33eeee":{"lch":[86.0178075751720286,64.8282855412949601,192.177050630061217],"luv":[86.0178075751720286,-63.3696789602654533,-13.6744431219908602],"rgb":[0.2,0.933333333333333348,0.933333333333333348],"xyz":[0.47369380809187478,0.680227194558442605,0.91524856185047776],"hpluv":[192.177050630061217,202.327515221469156,86.0178075751720286],"hsluv":[192.177050630061217,95.2603564020327127,86.0178075751720286]},"#33eeff":{"lch":[86.538483142230433,68.1460620684978124,204.293044736593487],"luv":[86.538483142230433,-62.1119480142598803,-28.035543321245509],"rgb":[0.2,0.933333333333333348,1],"xyz":[0.499864856501706201,0.690695613922375329,1.05308275014225972],"hpluv":[204.293044736593487,221.878852364873978,86.538483142230433],"hsluv":[204.293044736593487,99.999999999993932,86.538483142230433]},"#33ff00":{"lch":[88.074762753062231,133.577745567808222,126.513803819973305],"luv":[88.074762753062231,-79.4809541468946,107.358241597361044],"rgb":[0.2,1,0],"xyz":[0.37123644052955,0.72220804342099143,0.119834722035823737],"hpluv":[126.513803819973305,497.272976699974663,88.074762753062231],"hsluv":[126.513803819973305,100.00000000000226,88.074762753062231]},"#33ff11":{"lch":[88.0941974462199,132.80363803677966,126.71317891025123],"luv":[88.0941974462199,-79.3912833442141448,106.460464045403725],"rgb":[0.2,1,0.0666666666666666657],"xyz":[0.37224810602918712,0.722612709620846339,0.125162827000579374],"hpluv":[126.71317891025123,495.277769978645495,88.0941974462199],"hsluv":[126.71317891025123,99.9999999999917861,88.0941974462199]},"#33ff22":{"lch":[88.1302050034733355,131.38040615815558,127.087058789859782],"luv":[88.1302050034733355,-79.2260405323659285,104.804797713872986],"rgb":[0.2,1,0.133333333333333331],"xyz":[0.374123464167664177,0.723362852876237139,0.135039713196558553],"hpluv":[127.087058789859782,491.602558840386564,88.1302050034733355],"hsluv":[127.087058789859782,99.9999999999915161,88.1302050034733355]},"#33ff33":{"lch":[88.1894367416410745,129.070276381710187,127.715012949240347],"luv":[88.1894367416410745,-78.9567203165017162,102.10275491931047],"rgb":[0.2,1,0.2],"xyz":[0.377211214900121883,0.724597953169220266,0.151301867054169703],"hpluv":[127.715012949240347,485.618062737129037,88.1894367416410745],"hsluv":[127.715012949240347,99.9999999999917577,88.1894367416410745]},"#33ff44":{"lch":[88.2748349985884,125.807640063387211,128.649544439126117],"luv":[88.2748349985884,-78.5738101086462137,98.2533391968394909],"rgb":[0.2,1,0.266666666666666663],"xyz":[0.381669210144340798,0.726381151266907832,0.174780642007056342],"hpluv":[128.649544439126117,477.126267833886629,88.2748349985884],"hsluv":[128.649544439126117,99.9999999999917151,88.2748349985884]},"#33ff55":{"lch":[88.3888340150102181,121.57774004888698,129.95306271607248],"luv":[88.3888340150102181,-78.0723424240601,93.1979410921456122],"rgb":[0.2,1,0.333333333333333315],"xyz":[0.387631624183702783,0.728766116882652581,0.206182689281030257],"hpluv":[129.95306271607248,466.04908765344419,88.3888340150102181],"hsluv":[129.95306271607248,99.999999999991644,88.3888340150102181]},"#33ff66":{"lch":[88.5334972733264,116.417510431790106,131.704600668064415],"luv":[88.5334972733264,-77.4514410423726929,86.9155395518881],"rgb":[0.2,1,0.4],"xyz":[0.395216619957210968,0.7318001151920559,0.246130333688174219],"hpluv":[131.704600668064415,452.43688525451455,88.5334972733264],"hsluv":[131.704600668064415,99.9999999999913882,88.5334972733264]},"#33ff77":{"lch":[88.7105909437740081,110.419515958012653,134.007319384137503],"luv":[88.7105909437740081,-76.7139872603015505,79.419353202025647],"rgb":[0.2,1,0.466666666666666674],"xyz":[0.404530632977412874,0.735525720400136751,0.295184135594572128],"hpluv":[134.007319384137503,436.493157669178117,88.7105909437740081],"hsluv":[134.007319384137503,99.9999999999915,88.7105909437740081]},"#33ff88":{"lch":[88.9216276204312379,103.738746998712813,136.99719245927011],"luv":[88.9216276204312379,-75.8662497359534882,70.7533729221786558],"rgb":[0.2,1,0.533333333333333326],"xyz":[0.415671050079356674,0.739981887240914293,0.353856998998144268],"hpluv":[136.99719245927011,418.619650658891032,88.9216276204312379],"hsluv":[136.99719245927011,99.9999999999912603,88.9216276204312379]},"#33ff99":{"lch":[89.1678944508512359,96.6032590942606788,140.85189111032139],"luv":[89.1678944508512359,-74.9174292298428242,60.9882649796200695],"rgb":[0.2,1,0.6],"xyz":[0.428728014188429429,0.745204672884543506,0.422623676639262202],"hpluv":[140.85189111032139,399.492483487252343,89.1678944508512359],"hsluv":[140.85189111032139,99.9999999999913456,89.1678944508512359]},"#33ffaa":{"lch":[89.4504724790268426,89.3298939826383105,145.795546705853383],"luv":[89.4504724790268426,-73.8791171714821,50.2165909327964926],"rgb":[0.2,1,0.66666666666666663],"xyz":[0.44378570715368193,0.751227750070644573,0.501927526256260803],"hpluv":[145.795546705853383,380.184928602968114,89.4504724790268426],"hsluv":[145.795546705853383,99.9999999999912,89.4504724790268426]},"#33ffbb":{"lch":[89.7702508712150262,82.3444719603705,152.087330110215447],"luv":[89.7702508712150262,-72.7646918614874494,38.5475249625060314],"rgb":[0.2,1,0.733333333333333282],"xyz":[0.460923299261018604,0.758082786913579332,0.592185511354902605],"hpluv":[152.087330110215447,362.351543222333419,89.7702508712150262],"hsluv":[152.087330110215447,99.9999999999909761,89.7702508712150262]},"#33ffcc":{"lch":[90.127938152783571,76.1985663634222,159.968053619612647],"luv":[90.127938152783571,-71.5886883295869723,26.1013643147272063],"rgb":[0.2,1,0.8],"xyz":[0.480215674704740358,0.765799737091068189,0.693792022025172761],"hpluv":[159.968053619612647,348.464440630653087,90.127938152783571],"hsluv":[159.968053619612647,99.999999999990834,90.127938152783571]},"#33ffdd":{"lch":[90.5240717550146314,71.5577226375514357,169.529475161807255],"luv":[90.5240717550146314,-70.3661811113599924,13.0041618290463337],"rgb":[0.2,1,0.866666666666666696],"xyz":[0.501734000255373846,0.774407067311321695,0.807121869925178759],"hpluv":[169.529475161807255,342.013155745428833,90.5240717550146314],"hsluv":[169.529475161807255,99.9999999999904077,90.5240717550146314]},"#33ffee":{"lch":[90.9590266887802,69.1149718308150511,180.51167449693034],"luv":[90.9590266887802,-69.1122158161064561,-0.61721646306864264],"rgb":[0.2,1,0.933333333333333348],"xyz":[0.525546180521548667,0.783931939417791712,0.932532685993702],"hpluv":[180.51167449693034,347.442342228089899,90.9590266887802],"hsluv":[180.51167449693034,99.9999999999901519,90.9590266887802]},"#33ffff":{"lch":[91.4330238629877243,69.4028497051403122,192.177050630061132],"luv":[91.4330238629877243,-67.8413175363212702,-14.6393709608822622],"rgb":[0.2,1,1],"xyz":[0.55171722893138,0.794400358781724436,1.07036687428548372],"hpluv":[192.177050630061132,369.590917988860895,91.4330238629877243],"hsluv":[192.177050630061132,99.9999999999897256,91.4330238629877243]},"#22aa00":{"lch":[60.8595101229647923,91.9296409673314656,126.268252023172565],"luv":[60.8595101229647923,-54.3824975763784053,74.1188427172042594],"rgb":[0.133333333333333331,0.66666666666666663,0],"xyz":[0.150337683054585614,0.290883353615456,0.0482228743965988915],"hpluv":[126.268252023172565,191.675426474830772,60.8595101229647923],"hsluv":[126.268252023172565,100.000000000002288,60.8595101229647923]},"#22aa11":{"lch":[60.8951349805759605,90.6090655032342482,126.765726538166419],"luv":[60.8951349805759605,-54.2335583573106,72.5859759132132893],"rgb":[0.133333333333333331,0.66666666666666663,0.0666666666666666657],"xyz":[0.151349348554222746,0.291288019815310828,0.0535509793613545212],"hpluv":[126.765726538166419,188.811473003651798,60.8951349805759605],"hsluv":[126.765726538166419,97.6988909499644365,60.8951349805759605]},"#22aa22":{"lch":[60.9610867967894592,88.21068058626,127.715012949240347],"luv":[60.9610867967894592,-53.9615024560723953,69.7802294505720226],"rgb":[0.133333333333333331,0.66666666666666663,0.133333333333333331],"xyz":[0.153224706692699747,0.292038163070701628,0.0634278655573337208],"hpluv":[127.715012949240347,183.614848439340193,60.9610867967894592],"hsluv":[127.715012949240347,93.4926845994439475,60.9610867967894592]},"#22aa33":{"lch":[61.0694299105106495,84.4016098893730629,129.358188857231823],"luv":[61.0694299105106495,-53.5246691509727626,65.259034196016259],"rgb":[0.133333333333333331,0.66666666666666663,0.2],"xyz":[0.156312457425157481,0.293273263363684755,0.0796900194149448571],"hpluv":[129.358188857231823,175.374397166590711,61.0694299105106495],"hsluv":[129.358188857231823,93.5882360519160699,61.0694299105106495]},"#22aa44":{"lch":[61.2253168994486145,79.2082340196825214,131.918899994809664],"luv":[61.2253168994486145,-52.917281977470445,58.938150671985575],"rgb":[0.133333333333333331,0.66666666666666663,0.266666666666666663],"xyz":[0.160770452669376368,0.295056461461372321,0.103168794367831496],"hpluv":[131.918899994809664,164.164260791814144,61.2253168994486145],"hsluv":[131.918899994809664,93.7213426507132397,61.2253168994486145]},"#22aa55":{"lch":[61.4328316402448422,72.8294169380228169,135.724592815827151],"luv":[61.4328316402448422,-52.1453123372646488,50.8428005993127883],"rgb":[0.133333333333333331,0.66666666666666663,0.333333333333333315],"xyz":[0.166732866708738381,0.297441427077117182,0.134570841641805411],"hpluv":[135.724592815827151,150.433869175471955,61.4328316402448422],"hsluv":[135.724592815827151,93.8909627694616802,61.4328316402448422]},"#22aa66":{"lch":[61.695221435526193,65.6694032551541511,141.26425661379642],"luv":[61.695221435526193,-51.2247747289881588,41.0912761769754056],"rgb":[0.133333333333333331,0.66666666666666663,0.4],"xyz":[0.174317862482246538,0.3004754253865205,0.174518486048949373],"hpluv":[141.26425661379642,135.067502346464636,61.695221435526193],"hsluv":[141.26425661379642,94.0939374356695737,61.695221435526193]},"#22aa77":{"lch":[62.015018576984005,58.3994247120946,149.232117680428786],"luv":[62.015018576984005,-50.1795183581889,29.8748848373309741],"rgb":[0.133333333333333331,0.66666666666666663,0.466666666666666674],"xyz":[0.183631875502448472,0.304201030594601296,0.223572287955347282],"hpluv":[149.232117680428786,119.495353216490457,62.015018576984005],"hsluv":[149.232117680428786,94.3254538020573534,62.015018576984005]},"#22aa88":{"lch":[62.3941144695078265,52.0455462506657582,160.428514439052776],"luv":[62.3941144695078265,-49.0385773736463904,17.4343572780611709],"rgb":[0.133333333333333331,0.66666666666666663,0.533333333333333326],"xyz":[0.194772292604392272,0.308657197435378894,0.282245151358919477],"hpluv":[160.428514439052776,105.847175197261592,62.3941144695078265],"hsluv":[160.428514439052776,94.5795977554836753,62.3941144695078265]},"#22aa99":{"lch":[62.8338123759312168,48.0032947436357915,175.177921691935865],"luv":[62.8338123759312168,-47.8333890460383486,4.03524455451089725],"rgb":[0.133333333333333331,0.66666666666666663,0.6],"xyz":[0.207829256713465,0.313879983079008051,0.351011829000037356],"hpluv":[175.177921691935865,96.9431131493944918,62.8338123759312168],"hsluv":[175.177921691935865,94.8499327714938119,62.8338123759312168]},"#22aaaa":{"lch":[63.334871160235295,47.6677335272966047,192.177050630061132],"luv":[63.334871160235295,-46.595231466735612,-10.0547115418935782],"rgb":[0.133333333333333331,0.66666666666666663,0.66666666666666663],"xyz":[0.222886949678717528,0.319903060265109174,0.430315678617035957],"hpluv":[192.177050630061132,95.5038628742744748,63.334871160235295],"hsluv":[192.177050630061132,95.1300327368807075,63.334871160235295]},"#22aabb":{"lch":[63.8975462810157211,51.5875561200845425,208.460106210027732],"luv":[63.8975462810157211,-45.3531553267970224,-24.5838818811491713],"rgb":[0.133333333333333331,0.66666666666666663,0.733333333333333282],"xyz":[0.240024541786054202,0.326758097108043932,0.520573663715677704],"hpluv":[208.460106210027732,102.447201536891086,63.8975462810157211],"hsluv":[208.460106210027732,95.4139121453229393,63.8975462810157211]},"#22aacc":{"lch":[64.5216311304052681,59.1142282054053112,221.706391964203618],"luv":[64.5216311304052681,-44.1325525375176184,-39.3295027027292079],"rgb":[0.133333333333333331,0.66666666666666663,0.8],"xyz":[0.259316917229775901,0.334475047285532734,0.62218017438594786],"hpluv":[221.706391964203618,116.258847224370101,64.5216311304052681],"hsluv":[221.706391964203618,95.6963242429470853,64.5216311304052681]},"#22aadd":{"lch":[65.2065000175346796,69.0826091468118619,231.553565124642319],"luv":[65.2065000175346796,-42.9543721979751538,-54.1047945713593279],"rgb":[0.133333333333333331,0.66666666666666663,0.866666666666666696],"xyz":[0.2808352427804095,0.34308237750578624,0.735510022285953857],"hpluv":[231.553565124642319,134.436491082611866,65.2065000175346796],"hsluv":[231.553565124642319,95.9729250289437,65.2065000175346796]},"#22aaee":{"lch":[65.951153016283925,80.4876559434330687,238.683318882444183],"luv":[65.951153016283925,-41.8348964739996418,-68.7612114224159825],"rgb":[0.133333333333333331,0.66666666666666663,0.933333333333333348],"xyz":[0.304647423046584209,0.352607249612256257,0.86092083835447708],"hpluv":[238.683318882444183,154.862481256054423,65.951153016283925],"hsluv":[238.683318882444183,96.2403212652285305,65.951153016283925]},"#22aaff":{"lch":[66.7542622474436911,92.6475815050926741,243.881654723446388],"luv":[66.7542622474436911,-40.785937465112724,-83.187028218555227],"rgb":[0.133333333333333331,0.66666666666666663,1],"xyz":[0.33081847145641563,0.363075668976189,0.998755026646258925],"hpluv":[243.881654723446388,176.114215620682756,66.7542622474436911],"hsluv":[243.881654723446388,99.9999999999982521,66.7542622474436911]},"#22bb00":{"lch":[66.4275479271698117,100.802558180890344,126.547308547849156],"luv":[66.4275479271698117,-60.0265444602621798,80.9812922592122533],"rgb":[0.133333333333333331,0.733333333333333282,0],"xyz":[0.184292180963184393,0.358792349432654534,0.0595410403661315105],"hpluv":[126.547308547849156,192.558484368086766,66.4275479271698117],"hsluv":[126.547308547849156,100.000000000002402,66.4275479271698117]},"#22bb11":{"lch":[66.4585250929908682,99.6331665050874449,126.950333401467461],"luv":[66.4585250929908682,-59.891738470658936,79.6225315522727612],"rgb":[0.133333333333333331,0.733333333333333282,0.0666666666666666657],"xyz":[0.185303846462821525,0.359197015632509387,0.0648691453308871402],"hpluv":[126.950333401467461,190.235936561387632,66.4585250929908682],"hsluv":[126.950333401467461,98.1323711753334464,66.4585250929908682]},"#22bb22":{"lch":[66.5158870179191553,97.5011623585143496,127.715012949240375],"luv":[66.5158870179191553,-59.6448091899021904,77.1295883430057785],"rgb":[0.133333333333333331,0.733333333333333282,0.133333333333333331],"xyz":[0.187179204601298527,0.359947158887900187,0.0747460315268663328],"hpluv":[127.715012949240375,186.004620566556611,66.5158870179191553],"hsluv":[127.715012949240375,94.7095045552014341,66.5158870179191553]},"#22bb33":{"lch":[66.6101592341861561,94.091611241079562,129.025604662043349],"luv":[66.6101592341861561,-59.2464412491434089,73.0964465979998721],"rgb":[0.133333333333333331,0.733333333333333282,0.2],"xyz":[0.19026695533375626,0.361182259180883314,0.091008185384477483],"hpluv":[129.025604662043349,179.246118589082698,66.6101592341861561],"hsluv":[129.025604662043349,94.7728361420699628,66.6101592341861561]},"#22bb44":{"lch":[66.7458880420052907,89.3893698914418735,131.03732282887168],"luv":[66.7458880420052907,-58.6886365964374903,67.424797990356],"rgb":[0.133333333333333331,0.733333333333333282,0.266666666666666663],"xyz":[0.194724950577975148,0.36296545727857088,0.114486960337364121],"hpluv":[131.03732282887168,169.941985039444177,66.7458880420052907],"hsluv":[131.03732282887168,94.8616428317247511,66.7458880420052907]},"#22bb55":{"lch":[66.9267274999506,83.5071173210959472,133.96576260666626],"luv":[66.9267274999506,-57.9730125462468777,60.1046459068846488],"rgb":[0.133333333333333331,0.733333333333333282,0.333333333333333315],"xyz":[0.200687364617337161,0.365350422894315741,0.145889007611338023],"hpluv":[133.96576260666626,158.330006142604873,66.9267274999506],"hsluv":[133.96576260666626,94.9758066387206128,66.9267274999506]},"#22bb66":{"lch":[67.1556458878222315,76.7025221245859541,138.121353671725132],"luv":[67.1556458878222315,-57.1096598103208919,51.2031606116460054],"rgb":[0.133333333333333331,0.733333333333333282,0.4],"xyz":[0.208272360390845318,0.368384421203719059,0.185836652018481985],"hpluv":[138.121353671725132,144.932719296840418,67.1556458878222315],"hsluv":[138.121353671725132,95.1139083236691363,67.1556458878222315]},"#22bb77":{"lch":[67.4350338747947831,69.4107315991336407,143.945643371462126],"luv":[67.4350338747947831,-56.1157304677756557,40.8518598743670935],"rgb":[0.133333333333333331,0.733333333333333282,0.466666666666666674],"xyz":[0.217586373411047251,0.372110026411799855,0.234890453924879894],"hpluv":[143.945643371462126,130.611184627207962,67.4350338747947831],"hsluv":[143.945643371462126,95.2734443978328471,67.4350338747947831]},"#22bb88":{"lch":[67.7667691572368653,62.2973404800357571,152.016434409622292],"luv":[67.7667691572368653,-55.0136735570032656,29.2310511724943218],"rgb":[0.133333333333333331,0.733333333333333282,0.533333333333333326],"xyz":[0.228726790512991052,0.376566193252577452,0.293563317328452089],"hpluv":[152.016434409622292,116.65196328010299,67.7667691572368653],"hsluv":[152.016434409622292,95.4510958201536823,67.7667691572368653]},"#22bb99":{"lch":[68.1522602188863402,56.3167420179958214,162.907285030510934],"luv":[68.1522602188863402,-53.8292536917802948,16.552549003324323],"rgb":[0.133333333333333331,0.733333333333333282,0.6],"xyz":[0.241783754622063779,0.38178897889620661,0.362329994969569968],"hpluv":[162.907285030510934,104.856796539193,68.1522602188863402],"hsluv":[162.907285030510934,95.6430286983925555,68.1522602188863402]},"#22bbaa":{"lch":[68.5924801056558238,52.6774965449754617,176.68900923381463],"luv":[68.5924801056558238,-52.5895649511659542,3.04241688349887474],"rgb":[0.133333333333333331,0.733333333333333282,0.66666666666666663],"xyz":[0.256841447587316307,0.387812056082307732,0.441633844586568569],"hpluv":[176.68900923381463,97.4513697523019,68.5924801056558238],"hsluv":[176.68900923381463,95.8451953079369616,68.5924801056558238]},"#22bbbb":{"lch":[69.087995915136645,52.5025293878432677,192.177050630061075],"luv":[69.087995915136645,-51.3212466461144174,-11.0745309069971647],"rgb":[0.133333333333333331,0.733333333333333282,0.733333333333333282],"xyz":[0.273979039694653,0.394667092925242491,0.531891829685210316],"hpluv":[192.177050630061075,96.4310638968393903,69.087995915136645],"hsluv":[192.177050630061075,96.05360442262905,69.087995915136645]},"#22bbcc":{"lch":[69.6389970716796824,56.2104265974936,207.07804051519031],"luv":[69.6389970716796824,-50.0490518690675117,-25.5871933841835393],"rgb":[0.133333333333333331,0.733333333333333282,0.8],"xyz":[0.293271415138374736,0.402384043102731292,0.633498340355480472],"hpluv":[207.07804051519031,102.424464009042,69.6389970716796824],"hsluv":[207.07804051519031,96.2645382772070519,69.6389970716796824]},"#22bbdd":{"lch":[70.2453239794146924,63.2897284454122868,219.558412279776348],"luv":[70.2453239794146924,-48.7948432782897541,-40.3069844585422956],"rgb":[0.133333333333333331,0.733333333333333282,0.866666666666666696],"xyz":[0.314789740689008224,0.410991373322984799,0.746828188255486469],"hpluv":[219.558412279776348,114.328666738486675,70.2453239794146924],"hsluv":[219.558412279776348,96.4747049793171101,70.2453239794146924]},"#22bbee":{"lch":[70.9064977498674409,72.7777709471329644,229.176572531806158],"luv":[70.9064977498674409,-47.5770176148035588,-55.072963774560229],"rgb":[0.133333333333333331,0.733333333333333282,0.933333333333333348],"xyz":[0.338601920955183,0.420516245429454816,0.872239004324009692],"hpluv":[229.176572531806158,130.242295294742263,70.9064977498674409],"hsluv":[229.176572531806158,96.6813261778791286,70.9064977498674409]},"#22bbff":{"lch":[71.621751136046143,83.782469360031385,236.362391595167765],"luv":[71.621751136046143,-46.4103062114400586,-69.7537500742789121],"rgb":[0.133333333333333331,0.733333333333333282,1],"xyz":[0.364772969365014355,0.43098466479338754,1.01007319261579154],"hpluv":[236.362391595167765,148.438838585801221,71.621751136046143],"hsluv":[236.362391595167765,99.9999999999977405,71.621751136046143]},"#22cc00":{"lch":[71.9091745039523431,109.499123564337054,126.755635680122666],"luv":[71.9091745039523431,-65.5246489265194185,87.7301455852794732],"rgb":[0.133333333333333331,0.8,0],"xyz":[0.222515924272801313,0.435239836051889428,0.0722822881360034586],"hpluv":[126.755635680122666,193.226045742870838,71.9091745039523431],"hsluv":[126.755635680122666,100.000000000002288,71.9091745039523431]},"#22cc11":{"lch":[71.9364107151438077,108.454952609175663,127.087674169957992],"luv":[71.9364107151438077,-65.4022833696805,86.5159989567857508],"rgb":[0.133333333333333331,0.8,0.0666666666666666657],"xyz":[0.223527589772438445,0.435644502251744281,0.0776103931007591],"hpluv":[127.087674169957992,191.311003889673145,71.9364107151438077],"hsluv":[127.087674169957992,98.4591341389350418,71.9364107151438077]},"#22cc22":{"lch":[71.9868548113652196,106.54571101335867,127.715012949240403],"luv":[71.9868548113652196,-65.1776701905061771,84.2843985793322332],"rgb":[0.133333333333333331,0.8,0.133333333333333331],"xyz":[0.225402947910915447,0.436394645507135082,0.0874872792967382878],"hpluv":[127.715012949240403,187.811464536348922,71.9868548113652196],"hsluv":[127.715012949240403,95.6295101801496,71.9868548113652196]},"#22cc33":{"lch":[72.0697845089905229,103.47656324227728,128.782383231673776],"luv":[72.0697845089905229,-64.8140104316899084,80.6631464312780224],"rgb":[0.133333333333333331,0.8,0.2],"xyz":[0.22849069864337318,0.437629745800118208,0.103749433154349424],"hpluv":[128.782383231673776,182.191494825933376,72.0697845089905229],"hsluv":[128.782383231673776,95.6728206524347,72.0697845089905229]},"#22cc44":{"lch":[72.1892409305665126,99.2080881077430092,130.402545810446583],"luv":[72.1892409305665126,-64.3020931154350563,75.5479024657046381],"rgb":[0.133333333333333331,0.8,0.266666666666666663],"xyz":[0.232948693887592068,0.439412943897805774,0.127228208107236063],"hpluv":[130.402545810446583,174.38692971209278,72.1892409305665126],"hsluv":[130.402545810446583,95.7338579762306807,72.1892409305665126]},"#22cc55":{"lch":[72.3485056391290584,93.798910065649892,132.724941359454647],"luv":[72.3485056391290584,-63.6406395178356732,68.9064912128369116],"rgb":[0.133333333333333331,0.8,0.333333333333333315],"xyz":[0.23891110792695408,0.441797909513550635,0.158630255381209978],"hpluv":[132.724941359454647,164.515777124050715,72.3485056391290584],"hsluv":[132.724941359454647,95.8128514989610665,72.3485056391290584]},"#22cc66":{"lch":[72.5502856399570106,87.4149553130202577,135.957009780349864],"luv":[72.5502856399570106,-62.8354766726053597,60.7706942835425821],"rgb":[0.133333333333333331,0.8,0.4],"xyz":[0.246496103700462238,0.444831907822953954,0.19857789978835394],"hpluv":[135.957009780349864,152.89241471165704,72.5502856399570106],"hsluv":[135.957009780349864,95.9092114165347454,72.5502856399570106]},"#22cc77":{"lch":[72.7968107106438,80.347487444586676,140.388595454497391],"luv":[72.7968107106438,-61.8986076052927601,51.2277377519640922],"rgb":[0.133333333333333331,0.8,0.466666666666666674],"xyz":[0.255810116720664171,0.448557513031034749,0.247631701694751849],"hpluv":[140.388595454497391,140.055211607516185,72.7968107106438],"hsluv":[140.388595454497391,96.0216367005683651,72.7968107106438]},"#22cc88":{"lch":[73.0898911189871399,73.0433057087839899,146.410934307510047],"luv":[73.0898911189871399,-60.8470337434031379,40.4099368162836328],"rgb":[0.133333333333333331,0.8,0.533333333333333326],"xyz":[0.266950533822607972,0.453013679871812347,0.306304565098324044],"hpluv":[146.410934307510047,126.812607157634474,73.0898911189871399],"hsluv":[146.410934307510047,96.1482500942118463,73.0898911189871399]},"#22cc99":{"lch":[73.4309556061454316,66.1476907411168,154.494840416347301],"luv":[73.4309556061454316,-59.7013675833161201,28.4826912187770667],"rgb":[0.133333333333333331,0.8,0.6],"xyz":[0.280007497931680671,0.458236465515441505,0.375071242739441923],"hpluv":[154.494840416347301,114.307528246897718,73.4309556061454316],"hsluv":[154.494840416347301,96.2867563581127826,73.4309556061454316]},"#22ccaa":{"lch":[73.8210792378530272,60.5373530055450857,165.03572853292485],"luv":[73.8210792378530272,-58.4843517505691963,15.631753236079188],"rgb":[0.133333333333333331,0.8,0.66666666666666663],"xyz":[0.295065190896933227,0.464259542701542627,0.454375092356440524],"hpluv":[165.03572853292485,104.059650734936554,73.8210792378530272],"hsluv":[165.03572853292485,96.4346108423233233,73.8210792378530272]},"#22ccbb":{"lch":[74.2610062314211916,57.2561659312404601,177.947236116536601],"luv":[74.2610062314211916,-57.2194225987583565,2.05090580243043252],"rgb":[0.133333333333333331,0.8,0.733333333333333282],"xyz":[0.312202783004269901,0.471114579544477385,0.544633077455082271],"hpluv":[177.947236116536601,97.8364666306377302,74.2610062314211916],"hsluv":[177.947236116536601,96.5891828531354406,74.2610062314211916]},"#22cccc":{"lch":[74.7511706210643467,57.2167927817266,192.177050630061132],"luv":[74.7511706210643467,-55.9294412838427633,-12.0689259631595149],"rgb":[0.133333333333333331,0.8,0.8],"xyz":[0.3314951584479916,0.478831529721966187,0.646239588125352427],"hpluv":[192.177050630061132,97.128087782713564,74.7511706210643467],"hsluv":[192.177050630061132,96.747899952527,74.7511706210643467]},"#22ccdd":{"lch":[75.2917163799825602,60.7443465218384091,205.915913497891523],"luv":[75.2917163799825602,-54.6356779140553357,-26.5484148912282159],"rgb":[0.133333333333333331,0.8,0.866666666666666696],"xyz":[0.353013483998625199,0.487438859942219693,0.759569436025358424],"hpluv":[205.915913497891523,102.375961416692178,75.2917163799825602],"hsluv":[205.915913497891523,96.9083635301369,75.2917163799825602]},"#22ccee":{"lch":[75.8825178700112843,67.4282526949852894,217.691288579377613],"luv":[75.8825178700112843,-53.3570890727704779,-41.2260877015904583],"rgb":[0.133333333333333331,0.8,0.933333333333333348],"xyz":[0.376825664264799909,0.49696373204868971,0.884980252093881647],"hpluv":[217.691288579377613,112.755958051566466,75.8825178700112843],"hsluv":[217.691288579377613,97.0684311053177851,75.8825178700112843]},"#22ccff":{"lch":[76.5232010138481,76.4669756721874165,227.041443142980768],"luv":[76.5232010138481,-52.1098871667616095,-55.9621124325938553],"rgb":[0.133333333333333331,0.8,1],"xyz":[0.40299671267463133,0.507432151412622434,1.02281444038566338],"hpluv":[227.041443142980768,130.754689276117347,76.5232010138481],"hsluv":[227.041443142980768,99.999999999997,76.5232010138481]},"#22dd00":{"lch":[77.3111928538645543,118.038829613749726,126.914864539429317],"luv":[77.3111928538645543,-70.8973873693031607,94.3754510494695],"rgb":[0.133333333333333331,0.866666666666666696,0],"xyz":[0.265149914819976518,0.520507817146241,0.0864936183183947771],"hpluv":[126.914864539429317,210.347075729226248,77.3111928538645543],"hsluv":[126.914864539429317,100.000000000002288,77.3111928538645543]},"#22dd11":{"lch":[77.3353680300965323,117.099630973594756,127.192375056145337],"luv":[77.3353680300965323,-70.7859197567446756,93.2827805028547346],"rgb":[0.133333333333333331,0.866666666666666696,0.0666666666666666657],"xyz":[0.266161580319613622,0.520912483346095856,0.0918217232831504138],"hpluv":[127.192375056145337,208.941659016378082,77.3353680300965323],"hsluv":[127.192375056145337,98.7107326231664217,77.3353680300965323]},"#22dd22":{"lch":[77.3801492665193535,115.37848303888174,127.715012949240432],"luv":[77.3801492665193535,-70.5809801545768636,91.2716801027172409],"rgb":[0.133333333333333331,0.866666666666666696,0.133333333333333331],"xyz":[0.268036938458090679,0.521662626601486656,0.101698609479129606],"hpluv":[127.715012949240432,206.361699793513822,77.3801492665193535],"hsluv":[127.715012949240432,96.3395071146262154,77.3801492665193535]},"#22dd33":{"lch":[77.4537875025684315,112.600723810091978,128.59932725776207],"luv":[77.4537875025684315,-70.24826089977104,88.0005956974969195],"rgb":[0.133333333333333331,0.866666666666666696,0.2],"xyz":[0.271124689190548385,0.522897726894469783,0.117960763336740743],"hpluv":[128.59932725776207,202.185786680839726,77.4537875025684315],"hsluv":[128.59932725776207,96.3699377868481122,77.4537875025684315]},"#22dd44":{"lch":[77.5598997380018,108.71293616133481,129.930302741787841],"luv":[77.5598997380018,-69.7779723132927217,83.3638834787812],"rgb":[0.133333333333333331,0.866666666666666696,0.266666666666666663],"xyz":[0.2755826844347673,0.524680924992157349,0.141439538289627381],"hpluv":[129.930302741787841,196.316024449944422,77.5598997380018],"hsluv":[129.930302741787841,96.4129906320409162,77.5598997380018]},"#22dd55":{"lch":[77.7014460191091416,103.73899221962921,131.815952634500974],"luv":[77.7014460191091416,-69.1669361195931,77.3156740549574266],"rgb":[0.133333333333333331,0.866666666666666696,0.333333333333333315],"xyz":[0.281545098474129285,0.527065890607902099,0.172841585563601297],"hpluv":[131.815952634500974,188.764163413831653,77.7014460191091416],"hsluv":[131.815952634500974,96.4690009350202189,77.7014460191091416]},"#22dd66":{"lch":[77.880896240080375,97.784990294992113,134.401120560320578],"luv":[77.880896240080375,-68.4179393254247117,69.8633659756971923],"rgb":[0.133333333333333331,0.866666666666666696,0.4],"xyz":[0.28913009424763747,0.530099888917305417,0.212789229970745258],"hpluv":[134.401120560320578,179.664283635232721,77.880896240080375],"hsluv":[134.401120560320578,96.5377748783722467,77.880896240080375]},"#22dd77":{"lch":[78.1003183749745205,91.0497694522495635,137.883451987021573],"luv":[78.1003183749745205,-67.5390964016577584,61.0616980975421],"rgb":[0.133333333333333331,0.866666666666666696,0.466666666666666674],"xyz":[0.298444107267839376,0.533825494125386268,0.261843031877143195],"hpluv":[137.883451987021573,169.299836923025936,78.1003183749745205],"hsluv":[137.883451987021573,96.6186469084632478,78.1003183749745205]},"#22dd88":{"lch":[78.3614307373917285,83.8424849668191143,142.529576014285681],"luv":[78.3614307373917285,-66.5430534683674608,51.0057283108209205],"rgb":[0.133333333333333331,0.866666666666666696,0.533333333333333326],"xyz":[0.309584524369783176,0.538281660966163811,0.320515895280715335],"hpluv":[142.529576014285681,158.150702843881334,78.3614307373917285],"hsluv":[142.529576014285681,96.7105501690208,78.3614307373917285]},"#22dd99":{"lch":[78.665635872828048,76.6094810635621144,148.680389056502293],"luv":[78.665635872828048,-65.4460211356496586,39.8224924677044854],"rgb":[0.133333333333333331,0.866666666666666696,0.6],"xyz":[0.322641488478855876,0.543504446609793,0.389282572921833214],"hpluv":[148.680389056502293,146.968629494944878,78.665635872828048],"hsluv":[148.680389056502293,96.8121015046769884,78.665635872828048]},"#22ddaa":{"lch":[79.0140446006893882,69.96699558248838,156.711923446039975],"luv":[79.0140446006893882,-64.2666918031728613,27.6617569130368608],"rgb":[0.133333333333333331,0.866666666666666696,0.66666666666666663],"xyz":[0.337699181444108432,0.549527523795894091,0.46858642253883187],"hpluv":[156.711923446039975,136.880679993502099,79.0140446006893882],"hsluv":[156.711923446039975,96.9216963326973513,79.0140446006893882]},"#22ddbb":{"lch":[79.4074947696843196,64.7136880558744849,166.88262774299784],"luv":[79.4074947696843196,-63.0251268096233161,14.6865520944819572],"rgb":[0.133333333333333331,0.866666666666666696,0.733333333333333282],"xyz":[0.354836773551445106,0.556382560638828849,0.558844407637473561],"hpluv":[166.88262774299784,129.476815865977585,79.4074947696843196],"hsluv":[166.88262774299784,97.0376060255481,79.4074947696843196]},"#22ddcc":{"lch":[79.8465673347569123,61.7508733998812431,179.012513434233142],"luv":[79.8465673347569123,-61.7417023409151184,1.06421693934889783],"rgb":[0.133333333333333331,0.866666666666666696,0.8],"xyz":[0.374129148995166805,0.564099510816317706,0.660450918307743717],"hpluv":[179.012513434233142,126.735630147597362,79.8465673347569123],"hsluv":[179.012513434233142,97.1580701030331824,79.8465673347569123]},"#22dddd":{"lch":[80.3316012938198867,61.8272738566169,192.177050630061245],"luv":[80.3316012938198867,-60.4361886569793,-13.0414298740249546],"rgb":[0.133333333333333331,0.866666666666666696,0.866666666666666696],"xyz":[0.395647474545800404,0.572706841036571213,0.773780766207749715],"hpluv":[192.177050630061245,130.583134255532286,80.3316012938198867],"hsluv":[192.177050630061245,97.2813767637234434,80.3316012938198867]},"#22ddee":{"lch":[80.8627083873859078,65.1993477029452606,204.924336649163848],"luv":[80.8627083873859078,-59.1270126845314579,-27.4763773429615092],"rgb":[0.133333333333333331,0.866666666666666696,0.933333333333333348],"xyz":[0.419459654811975113,0.58223171314304123,0.899191582276272938],"hpluv":[204.924336649163848,142.193638870282854,80.8627083873859078],"hsluv":[204.924336649163848,97.405927410883,80.8627083873859078]},"#22ddff":{"lch":[81.4397880620905141,71.5324096951162574,216.054756332513932],"luv":[81.4397880620905141,-57.8307265123863,-42.1009822669203544],"rgb":[0.133333333333333331,0.866666666666666696,1],"xyz":[0.445630703221806534,0.592700132506974,1.03702577056805478],"hpluv":[216.054756332513932,161.676156351457934,81.4397880620905141],"hsluv":[216.054756332513932,99.9999999999961,81.4397880620905141]},"#22ee00":{"lch":[82.639607109796458,126.437751030410212,127.039022267349651],"luv":[82.639607109796458,-76.1608929793909368,100.92583052028732],"rgb":[0.133333333333333331,0.933333333333333348,0],"xyz":[0.312328691160491334,0.614865369827271913,0.102219877098565962],"hpluv":[127.039022267349651,308.746810598848469,82.639607109796458],"hsluv":[127.039022267349651,100.000000000002203,82.639607109796458]},"#22ee11":{"lch":[82.6612418520526262,125.587498690937579,127.273852876359626],"luv":[82.6612418520526262,-76.0589691017437,99.9362449095734462],"rgb":[0.133333333333333331,0.933333333333333348,0.0666666666666666657],"xyz":[0.313340356660128438,0.615270036027126821,0.107547982063321598],"hpluv":[127.273852876359626,307.111076239802628,82.6612418520526262],"hsluv":[127.273852876359626,98.9080389542438638,82.6612418520526262]},"#22ee22":{"lch":[82.7013218186993271,124.026614606467561,127.715012949240375],"luv":[82.7013218186993271,-75.8713392100017643,98.112899341636421],"rgb":[0.133333333333333331,0.933333333333333348,0.133333333333333331],"xyz":[0.315215714798605495,0.616020179282517621,0.117424868259300791],"hpluv":[127.715012949240375,304.102865014696874,82.7013218186993271],"hsluv":[127.715012949240375,96.8972824334497176,82.7013218186993271]},"#22ee33":{"lch":[82.7672420886773921,121.499708898279266,128.458265706389938],"luv":[82.7672420886773921,-75.5660658728233443,95.1417308591278754],"rgb":[0.133333333333333331,0.933333333333333348,0.2],"xyz":[0.318303465531063201,0.617255279575500748,0.133687022116911941],"hpluv":[128.458265706389938,299.21821405622444,82.7672420886773921],"hsluv":[128.458265706389938,96.9191735237910308,82.7672420886773921]},"#22ee44":{"lch":[82.8622607061112575,117.945648419515081,129.569612755667265],"luv":[82.8622607061112575,-75.1331770294334,90.918544261133448],"rgb":[0.133333333333333331,0.933333333333333348,0.266666666666666663],"xyz":[0.322761460775282116,0.619038477673188314,0.15716579706979858],"hpluv":[129.569612755667265,292.317409010606752,82.8622607061112575],"hsluv":[129.569612755667265,96.9502397298715692,82.8622607061112575]},"#22ee55":{"lch":[82.9890600071846194,113.365618159982461,131.129866929811442],"luv":[82.9890600071846194,-74.5682726576598185,85.3893207236587],"rgb":[0.133333333333333331,0.933333333333333348,0.333333333333333315],"xyz":[0.328723874814644101,0.621423443288933064,0.188567844343772495],"hpluv":[131.129866929811442,283.372415217622233,82.9890600071846194],"hsluv":[131.129866929811442,96.9908233877961266,82.9890600071846194]},"#22ee66":{"lch":[83.1498978333136,107.825536766413322,133.243989823694022],"luv":[83.1498978333136,-73.8719849852999175,78.5447402013449647],"rgb":[0.133333333333333331,0.933333333333333348,0.4],"xyz":[0.336308870588152287,0.624457441598336382,0.228515488750916429],"hpluv":[133.243989823694022,272.476761047092111,83.1498978333136],"hsluv":[133.243989823694022,97.0409162623008683,83.1498978333136]},"#22ee77":{"lch":[83.3466879629012709,101.462411308546436,136.05169958656856],"luv":[83.3466879629012709,-73.0495185954435726,70.415827350948561],"rgb":[0.133333333333333331,0.933333333333333348,0.466666666666666674],"xyz":[0.345622883608354192,0.628183046806417233,0.277569290657314338],"hpluv":[136.05169958656856,259.869348467080897,83.3466879629012709],"hsluv":[136.05169958656856,97.1001922741487391,83.3466879629012709]},"#22ee88":{"lch":[83.5810478428977746,94.494960715205238,139.739189865999265],"luv":[83.5810478428977746,-72.1101014829990277,61.0690663485185681],"rgb":[0.133333333333333331,0.933333333333333348,0.533333333333333326],"xyz":[0.356763300710298,0.632639213647194776,0.336242154060886533],"hpluv":[139.739189865999265,245.976403795765407,83.5810478428977746],"hsluv":[139.739189865999265,97.1680458209452098,83.5810478428977746]},"#22ee99":{"lch":[83.8543293451422187,87.2401092672494514,144.548413258572367],"luv":[83.8543293451422187,-71.0663081347816,50.6005584263049286],"rgb":[0.133333333333333331,0.933333333333333348,0.6],"xyz":[0.369820264819370692,0.637861999290824,0.405008831702004413],"hpluv":[144.548413258572367,231.480208097577446,83.8543293451422187],"hsluv":[144.548413258572367,97.2436385928483844,83.8543293451422187]},"#22eeaa":{"lch":[84.1676401551603846,80.1359348037682508,150.771943883792943],"luv":[84.1676401551603846,-69.9332745317766324,39.1293388665967328],"rgb":[0.133333333333333331,0.933333333333333348,0.66666666666666663],"xyz":[0.384877957784623248,0.643885076476925056,0.484312681319003],"hpluv":[150.771943883792943,217.42312560604816,84.1676401551603846],"hsluv":[150.771943883792943,97.3259536357082311,84.1676401551603846]},"#22eebb":{"lch":[84.5218598825754697,73.7647249619211181,158.704077932293842],"luv":[84.5218598825754697,-68.7278540770417834,26.7902355844945639],"rgb":[0.133333333333333331,0.933333333333333348,0.733333333333333282],"xyz":[0.402015549891959922,0.650740113319859814,0.57457066641764476],"hpluv":[158.704077932293842,205.339796192481117,84.5218598825754697],"hsluv":[158.704077932293842,97.4138533690930331,84.5218598825754697]},"#22eecc":{"lch":[84.9176532530853621,68.8500130904050422,168.499772582144715],"luv":[84.9176532530853621,-67.467774257192545,13.7267526869778429],"rgb":[0.133333333333333331,0.933333333333333348,0.8],"xyz":[0.421307925335681621,0.658457063497348671,0.676177177087914916],"hpluv":[168.499772582144715,197.354512375483154,84.9176532530853621],"hsluv":[168.499772582144715,97.5061375012374896,84.9176532530853621]},"#22eedd":{"lch":[85.3554818050158275,66.1709053937965166,179.926877690260085],"luv":[85.3554818050158275,-66.170851505859261,0.0844489448895467398],"rgb":[0.133333333333333331,0.933333333333333348,0.866666666666666696],"xyz":[0.44282625088631522,0.667064393717602178,0.789507024987920913],"hpluv":[179.926877690260085,196.075052309852396,85.3554818050158275],"hsluv":[179.926877690260085,97.6015969291830174,85.3554818050158275]},"#22eeee":{"lch":[85.8356149635753667,66.3470894225537648,192.177050630061245],"luv":[85.8356149635753667,-64.8543104533760868,-13.9948094114017536],"rgb":[0.133333333333333331,0.933333333333333348,0.933333333333333348],"xyz":[0.46663843115248993,0.676589265824072195,0.914917841056444137],"hpluv":[192.177050630061245,204.089886920334152,85.8356149635753667],"hsluv":[192.177050630061245,97.6990604766853608,85.8356149635753667]},"#22eeff":{"lch":[86.35814102124138,69.583621560973242,204.067857145017655],"luv":[86.35814102124138,-63.5342376580599435,-28.377474072755291],"rgb":[0.133333333333333331,0.933333333333333348,1],"xyz":[0.492809479562321351,0.687057685188004919,1.05275202934822598],"hpluv":[204.067857145017655,223.225826840448832,86.35814102124138],"hsluv":[204.067857145017655,99.9999999999940883,86.35814102124138]},"#22ff00":{"lch":[87.8997189713237361,134.70927246092154,127.137510750393233],"luv":[87.8997189713237361,-81.328032504319566,107.388729464162736],"rgb":[0.133333333333333331,1,0],"xyz":[0.364181063590165166,0.718570114686621,0.119504001241790073],"hpluv":[127.137510750393233,493.515561032875894,87.8997189713237361],"hsluv":[127.137510750393233,100.000000000002359,87.8997189713237361]},"#22ff11":{"lch":[87.9192191859362708,133.935112153716517,127.338384986715198],"luv":[87.9192191859362708,-81.2344832365115792,106.487431187561],"rgb":[0.133333333333333331,1,0.0666666666666666657],"xyz":[0.36519272908980227,0.718974780886475928,0.124832106206545709],"hpluv":[127.338384986715198,491.550771148457443,87.9192191859362708],"hsluv":[127.338384986715198,99.9999999999918572,87.9192191859362708]},"#22ff22":{"lch":[87.9553480404818089,132.511927889398493,127.71501294924046],"luv":[87.9553480404818089,-81.0620967295481449,104.825319015849075],"rgb":[0.133333333333333331,1,0.133333333333333331],"xyz":[0.367068087228279327,0.719724924141866729,0.134708992402524902],"hpluv":[127.71501294924046,487.932270281505453,87.9553480404818089],"hsluv":[127.71501294924046,99.9999999999918,87.9553480404818089]},"#22ff33":{"lch":[88.0147790356886,130.202284180175667,128.347396099003475],"luv":[88.0147790356886,-80.7811428723405101,102.112887345201102],"rgb":[0.133333333333333331,1,0.2],"xyz":[0.370155837960737033,0.720960024434849855,0.150971146260136052],"hpluv":[128.347396099003475,482.0420586134328,88.0147790356886],"hsluv":[128.347396099003475,99.9999999999918572,88.0147790356886]},"#22ff44":{"lch":[88.1004639745127349,126.941230298117631,129.288082018787549],"luv":[88.1004639745127349,-80.3817123888383,98.2489504424236486],"rgb":[0.133333333333333331,1,0.266666666666666663],"xyz":[0.374613833204955948,0.722743222532537422,0.174449921213022691],"hpluv":[129.288082018787549,473.688351575452941,88.1004639745127349],"hsluv":[129.288082018787549,99.9999999999917719,88.1004639745127349]},"#22ff55":{"lch":[88.2148445849976497,122.715034192366474,130.599301535876663],"luv":[88.2148445849976497,-79.8586444797792865,93.1749779645044498],"rgb":[0.133333333333333331,1,0.333333333333333315],"xyz":[0.380576247244317933,0.725128188148282171,0.205851968486996606],"hpluv":[130.599301535876663,462.799362736769183,88.2148445849976497],"hsluv":[130.599301535876663,99.9999999999917,88.2148445849976497]},"#22ff66":{"lch":[88.3599902775167863,117.562049147645283,132.359544385640646],"luv":[88.3599902775167863,-79.2110524978463104,86.8702743288911279],"rgb":[0.133333333333333331,1,0.4],"xyz":[0.388161243017826119,0.72816218645768549,0.24579961289414054],"hpluv":[132.359544385640646,449.432018335727776,88.3599902775167863],"hsluv":[132.359544385640646,99.999999999991644,88.3599902775167863]},"#22ff77":{"lch":[88.5376718023346427,111.576626717172417,134.67079586388752],"luv":[88.5376718023346427,-78.441973739162,79.3486004003085839],"rgb":[0.133333333333333331,1,0.466666666666666674],"xyz":[0.397475256038028,0.731887791665766341,0.294853414800538449],"hpluv":[134.67079586388752,433.796433649144,88.5376718023346427],"hsluv":[134.67079586388752,99.9999999999914593,88.5376718023346427]},"#22ff88":{"lch":[88.7494051061703,104.915784817642518,137.666744209541747],"luv":[88.7494051061703,-77.5579802767934581,70.6546643845003786],"rgb":[0.133333333333333331,1,0.533333333333333326],"xyz":[0.408615673139971824,0.736343958506543883,0.353526278204110644],"hpluv":[137.666744209541747,416.300130961303353,88.7494051061703],"hsluv":[137.666744209541747,99.9999999999915161,88.7494051061703]},"#22ff99":{"lch":[88.996479539624346,97.8095196496336143,141.520869213027311],"luv":[88.996479539624346,-76.5687003963823827,60.8599725082183696],"rgb":[0.133333333333333331,1,0.6],"xyz":[0.42167263724904458,0.741566744150173096,0.422292955845228524],"hpluv":[141.520869213027311,397.621886071746928,88.996479539624346],"hsluv":[141.520869213027311,99.9999999999913882,88.996479539624346]},"#22ffaa":{"lch":[89.2799772586324281,90.5758041558366784,146.450029989774293],"luv":[89.2799772586324281,-75.4862499862398,50.057989986528554],"rgb":[0.133333333333333331,1,0.66666666666666663],"xyz":[0.43673033021429708,0.747589821336274163,0.50159680546222718],"hpluv":[146.450029989774293,378.829469872945424,89.2799772586324281],"hsluv":[146.450029989774293,99.9999999999911893,89.2799772586324281]},"#22ffbb":{"lch":[89.6007875020334552,83.6393655876379825,152.701818689515648],"luv":[89.6007875020334552,-74.3245992165371661,38.3587985630895787],"rgb":[0.133333333333333331,1,0.733333333333333282],"xyz":[0.453867922321633754,0.754444858179208921,0.591854790560868871],"hpluv":[152.701818689515648,361.553698033539774,89.6007875020334552],"hsluv":[152.701818689515648,99.9999999999909903,89.6007875020334552]},"#22ffcc":{"lch":[89.9596178804745,77.5461751086222,160.50148390925915],"luv":[89.9596178804745,-73.0989125181650223,25.8835519710636532],"rgb":[0.133333333333333331,1,0.8],"xyz":[0.473160297765355509,0.762161808356697779,0.693461301231139],"hpluv":[160.50148390925915,348.207300802542932,89.9596178804745],"hsluv":[160.50148390925915,99.999999999990834,89.9596178804745]},"#22ffdd":{"lch":[90.3570039795250466,72.9493687180361,169.926987012389134],"luv":[90.3570039795250466,-71.8249031216737421,12.7590629719491808],"rgb":[0.133333333333333331,1,0.866666666666666696],"xyz":[0.494678623315989,0.770769138576951285,0.806791149131145],"hpluv":[169.926987012389134,342.16275562632859,90.3570039795250466],"hsluv":[169.926987012389134,99.9999999999906,90.3570039795250466]},"#22ffee":{"lch":[90.793318095908873,70.5238201303846637,180.720785562676866],"luv":[90.793318095908873,-70.5182397089352,-0.887171987837557796],"rgb":[0.133333333333333331,1,0.933333333333333348],"xyz":[0.518490803582163817,0.780294010683421302,0.932201965199668248],"hpluv":[180.720785562676866,347.681124246536797,90.793318095908873],"hsluv":[180.720785562676866,99.9999999999901661,90.793318095908873]},"#22ffff":{"lch":[91.2687776254429082,70.7867026205843786,192.177050630061217],"luv":[91.2687776254429082,-69.1940343982234225,-14.9312715999851058],"rgb":[0.133333333333333331,1,1],"xyz":[0.544661851991995127,0.790762430047354,1.0700361534914502],"hpluv":[192.177050630061217,369.384676987995,91.2687776254429082],"hsluv":[192.177050630061217,99.9999999999901803,91.2687776254429082]},"#11aa00":{"lch":[60.6644104521350869,93.0873160838275,127.211890667698796],"luv":[60.6644104521350869,-56.2958954857129186,74.1351506854346241],"rgb":[0.0666666666666666657,0.66666666666666663,0],"xyz":[0.146052570780394131,0.288673842599075969,0.0480220097587461675],"hpluv":[127.211890667698796,194.713406103753528,60.6644104521350869],"hsluv":[127.211890667698796,100.000000000002444,60.6644104521350869]},"#11aa11":{"lch":[60.7002167335786424,91.7670835597914447,127.715012949240375],"luv":[60.7002167335786424,-56.1370762813229547,72.5935692169401],"rgb":[0.0666666666666666657,0.66666666666666663,0.0666666666666666657],"xyz":[0.147064236280031263,0.289078508798930822,0.0533501147235018],"hpluv":[127.715012949240375,191.838607973199288,60.7002167335786424],"hsluv":[127.715012949240375,97.6800439707354826,60.7002167335786424]},"#11aa22":{"lch":[60.7665037483511696,89.3702510768545153,128.6744569519864],"luv":[60.7665037483511696,-55.8469935821418844,69.7721655488506229],"rgb":[0.0666666666666666657,0.66666666666666663,0.133333333333333331],"xyz":[0.148939594418508264,0.289828652054321623,0.063227000919481],"hpluv":[128.6744569519864,186.624241227076766,60.7665037483511696],"hsluv":[128.6744569519864,97.7012125574833163,60.7665037483511696]},"#11aa33":{"lch":[60.8753956347493101,85.5662665428975799,130.333267948257316],"luv":[60.8753956347493101,-55.3812688292774595,65.2265362636212274],"rgb":[0.0666666666666666657,0.66666666666666663,0.2],"xyz":[0.152027345150966,0.291063752347304749,0.0794891547770921469],"hpluv":[130.333267948257316,178.361088002118152,60.8753956347493101],"hsluv":[130.333267948257316,97.7352371443594876,60.8753956347493101]},"#11aa44":{"lch":[61.0320681383245898,80.3855440613202603,132.913331110856149],"luv":[61.0320681383245898,-54.7338170014505394,58.8731260464924233],"rgb":[0.0666666666666666657,0.66666666666666663,0.266666666666666663],"xyz":[0.156485340395184885,0.292846950444992316,0.102967929729978785],"hpluv":[132.913331110856149,167.131840298358668,61.0320681383245898],"hsluv":[132.913331110856149,97.7826211010278428,61.0320681383245898]},"#11aa55":{"lch":[61.2406211479126199,74.0326893716562466,136.73626291081149],"luv":[61.2406211479126199,-53.9110982897111626,50.7388665304739064],"rgb":[0.0666666666666666657,0.66666666666666663,0.333333333333333315],"xyz":[0.162447754434546898,0.295231916060737176,0.134369977003952701],"hpluv":[136.73626291081149,153.399260409180499,61.2406211479126199],"hsluv":[136.73626291081149,97.8429805383323412,61.2406211479126199]},"#11aa66":{"lch":[61.5043118059827236,66.9183608277608926,142.276062400218507],"luv":[61.5043118059827236,-52.9302802927860938,40.944504442006675],"rgb":[0.0666666666666666657,0.66666666666666663,0.4],"xyz":[0.170032750208055056,0.298265914370140495,0.174317621411096635],"hpluv":[142.276062400218507,138.063556785316223,61.5043118059827236],"hsluv":[142.276062400218507,97.9151756761398246,61.5043118059827236]},"#11aa77":{"lch":[61.8256765996828648,59.7171413308715628,150.193024237310198],"luv":[61.8256765996828648,-51.8168585560505335,29.6841731923518672],"rgb":[0.0666666666666666657,0.66666666666666663,0.466666666666666674],"xyz":[0.179346763228257,0.30199151957822129,0.223371423317494544],"hpluv":[150.193024237310198,122.565843528602272,61.8256765996828648],"hsluv":[150.193024237310198,97.9974781059027578,61.8256765996828648]},"#11aa88":{"lch":[62.2066058842594,53.445591933814967,161.225226782668472],"luv":[62.2066058842594,-50.6018085779820197,17.201403018159084],"rgb":[0.0666666666666666657,0.66666666666666663,0.533333333333333326],"xyz":[0.190487180330200789,0.306447686418998888,0.282044286721066739],"hpluv":[161.225226782668472,109.022142353571084,62.2066058842594],"hsluv":[161.225226782668472,98.0877698343988698,62.2066058842594]},"#11aa99":{"lch":[62.6483970296267643,49.4620441969123803,175.635441576327452],"luv":[62.6483970296267643,-49.3186051456987613,3.76417356400704],"rgb":[0.0666666666666666657,0.66666666666666663,0.6],"xyz":[0.203544144439273517,0.311670472062628046,0.350810964362184619],"hpluv":[175.635441576327452,100.184705161952,62.6483970296267643],"hsluv":[175.635441576327452,98.1837511724305756,62.6483970296267643]},"#11aaaa":{"lch":[63.1517986220979424,49.10533458105958,192.177050630061103],"luv":[63.1517986220979424,-48.0004871585874326,-10.3579494522848794],"rgb":[0.0666666666666666657,0.66666666666666663,0.66666666666666663],"xyz":[0.218601837404526045,0.317693549248729168,0.430114813979183219],"hpluv":[192.177050630061103,98.6693521766944741,63.1517986220979424],"hsluv":[192.177050630061103,98.283131385506934,63.1517986220979424]},"#11aabb":{"lch":[63.7170519890822931,52.9100997091116483,208.088870357104184],"luv":[63.7170519890822931,-46.6782604891356812,-24.9122188681885817],"rgb":[0.0666666666666666657,0.66666666666666663,0.733333333333333282],"xyz":[0.235739429511862719,0.324548586091663926,0.520372799077825],"hpluv":[208.088870357104184,105.371274370578277,63.7170519890822931],"hsluv":[208.088870357104184,98.3837818799450474,63.7170519890822931]},"#11aacc":{"lch":[64.3439331362496603,60.2774830024396,221.163749704229559],"luv":[64.3439331362496603,-45.3787880982832661,-39.6754401089704345],"rgb":[0.0666666666666666657,0.66666666666666663,0.8],"xyz":[0.255031804955584418,0.332265536269152728,0.621979309748095122],"hpluv":[221.163749704229559,118.873987633214512,64.3439331362496603],"hsluv":[221.163749704229559,98.4838416101877385,64.3439331362496603]},"#11aadd":{"lch":[65.0317963778061738,70.0923801470555,230.985682804055784],"luv":[65.0317963778061738,-44.1241742926816372,-54.4609860144708762],"rgb":[0.0666666666666666657,0.66666666666666663,0.866666666666666696],"xyz":[0.276550130506218,0.340872866489406234,0.735309157648101119],"hpluv":[230.985682804055784,136.767964522831733,65.0317963778061738],"hsluv":[230.985682804055784,98.5817742563244,65.0317963778061738]},"#11aaee":{"lch":[65.7796198544585877,81.3683973110580325,238.155251398024461],"luv":[65.7796198544585877,-42.9315457639956293,-69.1208974137644248],"rgb":[0.0666666666666666657,0.66666666666666663,0.933333333333333348],"xyz":[0.300362310772392727,0.350397738595876251,0.860719973716624343],"hpluv":[238.155251398024461,156.965326989669,65.7796198544585877],"hsluv":[238.155251398024461,98.676383948407647,65.7796198544585877]},"#11aaff":{"lch":[66.5860524818013317,93.423779787985481,243.412392023658668],"luv":[66.5860524818013317,-41.8132782993845566,-83.5443139162218529],"rgb":[0.0666666666666666657,0.66666666666666663,1],"xyz":[0.326533359182224148,0.360866157959809,0.998554162008406188],"hpluv":[243.412392023658668,178.038321821181739,66.5860524818013317],"hsluv":[243.412392023658668,99.9999999999982805,66.5860524818013317]},"#11bb00":{"lch":[66.2579979425279788,101.837028338191359,127.308350947248712],"luv":[66.2579979425279788,-61.7238643700190792,80.9996599251199285],"rgb":[0.0666666666666666657,0.733333333333333282,0],"xyz":[0.180007068688992911,0.356582838416274528,0.0593401757282787864],"hpluv":[127.308350947248712,195.032386644097869,66.2579979425279788],"hsluv":[127.308350947248712,100.000000000002416,66.2579979425279788]},"#11bb11":{"lch":[66.2891028676776,100.667761827005108,127.715012949240403],"luv":[66.2891028676776,-61.5819268253258301,79.6345688739434507],"rgb":[0.0666666666666666657,0.733333333333333282,0.0666666666666666657],"xyz":[0.181018734188630043,0.356987504616129381,0.0646682806930344162],"hpluv":[127.715012949240403,192.702610495025482,66.2891028676776],"hsluv":[127.715012949240403,98.1199752505464318,66.2891028676776]},"#11bb22":{"lch":[66.3467009890152895,98.5365229927559199,128.48627008521666],"luv":[66.3467009890152895,-61.3219466901703356,77.130183570569983],"rgb":[0.0666666666666666657,0.733333333333333282,0.133333333333333331],"xyz":[0.182894092327107044,0.357737647871520181,0.0745451668890136088],"hpluv":[128.48627008521666,188.459149582366734,66.3467009890152895],"hsluv":[128.48627008521666,98.1339007760711155,66.3467009890152895]},"#11bb33":{"lch":[66.4413603116689586,95.1297105779412107,129.807139434656818],"luv":[66.4413603116689586,-60.9025570517959949,73.0790009455219121],"rgb":[0.0666666666666666657,0.733333333333333282,0.2],"xyz":[0.185981843059564778,0.358972748164503308,0.0908073207466247589],"hpluv":[129.807139434656818,181.684126992490178,66.4413603116689586],"hsluv":[129.807139434656818,98.1563849168539093,66.4413603116689586]},"#11bb44":{"lch":[66.5776441235544,90.4345556189602888,131.832147550242752],"luv":[66.5776441235544,-60.3153845158839061,67.3829595721343679],"rgb":[0.0666666666666666657,0.733333333333333282,0.266666666666666663],"xyz":[0.190439838303783665,0.360755946262190874,0.114286095699511397],"hpluv":[131.832147550242752,172.363503065423913,66.5776441235544],"hsluv":[131.832147550242752,98.1879073212924567,66.5776441235544]},"#11bb55":{"lch":[66.7592187944261,84.5672269635890501,134.774448398028227],"luv":[66.7592187944261,-59.5621947933412841,60.0329978237906374],"rgb":[0.0666666666666666657,0.733333333333333282,0.333333333333333315],"xyz":[0.196402252343145678,0.363140911877935735,0.145688142973485313],"hpluv":[134.774448398028227,160.742297130584,66.7592187944261],"hsluv":[134.774448398028227,98.2284201297941451,66.7592187944261]},"#11bb66":{"lch":[66.9890609579081513,77.7896938122995749,138.938350400658521],"luv":[66.9890609579081513,-58.6536805127572336,51.0977712402284752],"rgb":[0.0666666666666666657,0.733333333333333282,0.4],"xyz":[0.203987248116653835,0.366174910187339053,0.185635787380629275],"hpluv":[138.938350400658521,147.352496635070423,66.9890609579081513],"hsluv":[138.938350400658521,98.2774122804504486,66.9890609579081513]},"#11bb77":{"lch":[67.2695660469751573,70.5410036497719375,144.751753478195667],"luv":[67.2695660469751573,-57.6079608572489548,40.7106379437464625],"rgb":[0.0666666666666666657,0.733333333333333282,0.466666666666666674],"xyz":[0.213301261136855769,0.369900515395419849,0.234689589287027184],"hpluv":[144.751753478195667,133.064539371584743,67.2695660469751573],"hsluv":[144.751753478195667,98.33398740837616,67.2695660469751573]},"#11bb88":{"lch":[67.6026131767386289,63.4868829762913904,152.765342955174589],"luv":[67.6026131767386289,-56.44870944299889,29.0538725863731493],"rgb":[0.0666666666666666657,0.733333333333333282,0.533333333333333326],"xyz":[0.224441678238799569,0.374356682236197447,0.293362452690599351],"hpluv":[152.765342955174589,119.168054047142519,67.6026131767386289],"hsluv":[152.765342955174589,98.3969602233376293,67.6026131767386289]},"#11bb99":{"lch":[67.9896091217093357,57.5709210660889568,163.510238814203348],"luv":[67.9896091217093357,-55.2030563361408468,16.3411604100414145],"rgb":[0.0666666666666666657,0.733333333333333282,0.6],"xyz":[0.237498642347872296,0.379579467879826604,0.362129130331717231],"hpluv":[163.510238814203348,107.448401728013394,67.9896091217093357],"hsluv":[163.510238814203348,98.464964167861,67.9896091217093357]},"#11bbaa":{"lch":[68.431522322705149,53.97217733059707,177.026074660918823],"luv":[68.431522322705149,-53.8994902384006807,2.80015675382041573],"rgb":[0.0666666666666666657,0.733333333333333282,0.66666666666666663],"xyz":[0.252556335313124825,0.385602545065927726,0.441432979948715831],"hpluv":[177.026074660918823,100.081328983600983,68.431522322705149],"hsluv":[177.026074660918823,98.5365589333087684,68.431522322705149]},"#11bbbb":{"lch":[68.9289126417652511,53.7759127589290102,192.177050630061103],"luv":[68.9289126417652511,-52.5659794775517426,-11.3431298424003177],"rgb":[0.0666666666666666657,0.733333333333333282,0.733333333333333282],"xyz":[0.269693927420461499,0.392457581908862485,0.531690965047357578],"hpluv":[192.177050630061103,98.9978332941913095,68.9289126417652511],"hsluv":[192.177050630061103,98.6103267315429122,68.9289126417652511]},"#11bbcc":{"lch":[69.4819599404948463,57.3930965266865485,206.799543430538137],"luv":[69.4819599404948463,-51.2284702417124365,-25.8768499940688805],"rgb":[0.0666666666666666657,0.733333333333333282,0.8],"xyz":[0.288986302864183253,0.400174532086351287,0.633297475717627734],"hpluv":[206.799543430538137,104.81584090136549,69.4819599404948463],"hsluv":[206.799543430538137,98.6849492658553658,69.4819599404948463]},"#11bbdd":{"lch":[70.0904930703520535,64.3454332007566876,219.135570681285316],"luv":[70.0904930703520535,-49.9098388382008054,-40.6121011637893901],"rgb":[0.0666666666666666657,0.733333333333333282,0.866666666666666696],"xyz":[0.310504628414816741,0.408781862306604793,0.746627323617633731],"hpluv":[219.135570681285316,116.492493254234162,70.0904930703520535],"hsluv":[219.135570681285316,98.7592614999562244,70.0904930703520535]},"#11bbee":{"lch":[70.7540199625255184,73.7064384587933858,228.717665412779098],"luv":[70.7540199625255184,-48.6292974270947838,-55.3879996211006826],"rgb":[0.0666666666666666657,0.733333333333333282,0.933333333333333348],"xyz":[0.334316808680991506,0.41830673441307481,0.872038139686157],"hpluv":[228.717665412779098,132.188487390259695,70.7540199625255184],"hsluv":[228.717665412779098,98.8322822642660412,70.7540199625255184]},"#11bbff":{"lch":[71.471758937406932,84.600620314641418,235.923069973878228],"luv":[71.471758937406932,-47.4021956671632836,-70.0735099988154246],"rgb":[0.0666666666666666657,0.733333333333333282,1],"xyz":[0.360487857090822872,0.428775153777007534,1.00987232797793891],"hpluv":[235.923069973878228,150.202929688167188,71.471758937406932],"hsluv":[235.923069973878228,99.9999999999978115,71.471758937406932]},"#11cc00":{"lch":[71.760164015117,110.429324102022079,127.380540485202317],"luv":[71.760164015117,-67.042304751477019,87.7494444155603617],"rgb":[0.0666666666666666657,0.8,0],"xyz":[0.21823081199860983,0.433030325035509422,0.0720814234981507346],"hpluv":[127.380540485202317,195.272154443078705,71.760164015117],"hsluv":[127.380540485202317,100.000000000002245,71.760164015117]},"#11cc11":{"lch":[71.7874927519263366,109.385174124956521,127.715012949240432],"luv":[71.7874927519263366,-66.9146672826053219,86.5305935539869466],"rgb":[0.0666666666666666657,0.8,0.0666666666666666657],"xyz":[0.219242477498246963,0.433434991235364275,0.0774095284629063712],"hpluv":[127.715012949240432,193.352149077988855,71.7874927519263366],"hsluv":[127.715012949240432,98.4507061603193563,71.7874927519263366]},"#11cc22":{"lch":[71.8381079866900905,107.476295008714118,128.346772012349533],"luv":[71.8381079866900905,-66.680384726115463,84.2904519004221129],"rgb":[0.0666666666666666657,0.8,0.133333333333333331],"xyz":[0.221117835636723964,0.434185134490755076,0.0872864146588855638],"hpluv":[128.346772012349533,189.84411001864018,71.8381079866900905],"hsluv":[128.346772012349533,98.4601754700601361,71.8381079866900905]},"#11cc33":{"lch":[71.9213183931711626,104.40864440796355,129.421122123890029],"luv":[71.9213183931711626,-66.3010906987881441,80.6556284412913556],"rgb":[0.0666666666666666657,0.8,0.2],"xyz":[0.224205586369181697,0.435420234783738203,0.103548568516496714],"hpluv":[129.421122123890029,184.212095875088124,71.9213183931711626],"hsluv":[129.421122123890029,98.4755168761512749,71.9213183931711626]},"#11cc44":{"lch":[72.0411777660314669,100.144250866202455,131.050559631523186],"luv":[72.0411777660314669,-65.7672084530810395,75.5218198525557085],"rgb":[0.0666666666666666657,0.8,0.266666666666666663],"xyz":[0.228663581613400585,0.437203432881425769,0.127027343469383353],"hpluv":[131.050559631523186,176.394298837834185,72.0411777660314669],"hsluv":[131.050559631523186,98.4971346697200261,72.0411777660314669]},"#11cc55":{"lch":[72.2009771566369523,94.7439152050601621,133.383427271112737],"luv":[72.2009771566369523,-65.077446685205,68.8573554627095],"rgb":[0.0666666666666666657,0.8,0.333333333333333315],"xyz":[0.234625995652762598,0.439588398497170629,0.158429390743357268],"hpluv":[133.383427271112737,166.512782767528847,72.2009771566369523],"hsluv":[133.383427271112737,98.5251071985599225,72.2009771566369523]},"#11cc66":{"lch":[72.4034304155724,88.37638367841096,136.624435218533876],"luv":[72.4034304155724,-64.2379326004453333,60.6949191225620339],"rgb":[0.0666666666666666657,0.8,0.4],"xyz":[0.242210991426270755,0.442622396806573948,0.198377035150501202],"hpluv":[136.624435218533876,154.887514188688357,72.4034304155724],"hsluv":[136.624435218533876,98.5592219307307289,72.4034304155724]},"#11cc77":{"lch":[72.6507717937069657,81.3359578844494422,141.057484765247835],"luv":[72.6507717937069657,-63.261234579889333,51.1229326663597],"rgb":[0.0666666666666666657,0.8,0.466666666666666674],"xyz":[0.251525004446472689,0.446348002014654743,0.247430837056899111],"hpluv":[141.057484765247835,142.063228414279422,72.6507717937069657],"hsluv":[141.057484765247835,98.5990140248714795,72.6507717937069657]},"#11cc88":{"lch":[72.9448138267759703,74.0714793913140284,147.061910762632237],"luv":[72.9448138267759703,-62.1651250648783815,40.2750702654370087],"rgb":[0.0666666666666666657,0.8,0.533333333333333326],"xyz":[0.262665421548416489,0.450804168855432341,0.306103700460471306],"hpluv":[147.061910762632237,128.853412583983044,72.9448138267759703],"hsluv":[147.061910762632237,98.6438145792393755,72.9448138267759703]},"#11cc99":{"lch":[73.286985449663689,67.2264361640895203,155.087429558943455],"luv":[73.286985449663689,-60.9711251229010074,28.3181147072320734],"rgb":[0.0666666666666666657,0.8,0.6],"xyz":[0.275722385657489188,0.456026954499061499,0.374870378101589186],"hpluv":[155.087429558943455,116.399886643338576,73.286985449663689],"hsluv":[155.087429558943455,98.6928071276572609,73.286985449663689]},"#11ccaa":{"lch":[73.6783599756885224,61.6669147974486336,165.501022011161467],"luv":[73.6783599756885224,-59.7029534543248275,15.4390974304365383],"rgb":[0.0666666666666666657,0.8,0.66666666666666663],"xyz":[0.290780078622741744,0.462050031685162621,0.454174227718587786],"hpluv":[165.501022011161467,106.206622375239988,73.6783599756885224],"hsluv":[165.501022011161467,98.7450877264532494,73.6783599756885224]},"#11ccbb":{"lch":[74.1196780643846864,58.4137876130139801,178.201908682105085],"luv":[74.1196780643846864,-58.3850250256368426,1.83287644266177074],"rgb":[0.0666666666666666657,0.8,0.733333333333333282],"xyz":[0.307917670730078419,0.46890506852809738,0.544432212817229533],"hpluv":[178.201908682105085,100.004874571957387,74.1196780643846864],"hsluv":[178.201908682105085,98.7997230732590452,74.1196780643846864]},"#11cccc":{"lch":[74.6113685470067,58.3540675645504,192.177050630061103],"luv":[74.6113685470067,-57.0411279075965751,-12.3088150671508707],"rgb":[0.0666666666666666657,0.8,0.8],"xyz":[0.327210046173800118,0.476622018705586181,0.646038723487499689],"hpluv":[192.177050630061103,99.244272920381249,74.6113685470067],"hsluv":[192.177050630061103,98.8558017207376167,74.6113685470067]},"#11ccdd":{"lch":[75.1535687293590087,61.8087365466066316,205.702276410621693],"luv":[75.1535687293590087,-55.6933672323303881,-26.8061328768737823],"rgb":[0.0666666666666666657,0.8,0.866666666666666696],"xyz":[0.348728371724433717,0.485229348925839687,0.759368571387505686],"hpluv":[205.702276410621693,104.361325002032586,75.1535687293590087],"hsluv":[205.702276410621693,98.9124749687685352,75.1535687293590087]},"#11ccee":{"lch":[75.7461450403856418,68.3900229325434168,217.356690237772426],"luv":[75.7461450403856418,-54.3614174191380712,-41.4973677827407],"rgb":[0.0666666666666666657,0.8,0.933333333333333348],"xyz":[0.372540551990608426,0.494754221032309704,0.88477938745602891],"hpluv":[217.356690237772426,114.570165581500433,75.7461450403856418],"hsluv":[217.356690237772426,98.968985855810871,75.7461450403856418]},"#11ccff":{"lch":[76.3887144168947714,77.3228649101567811,226.666757851513921],"luv":[76.3887144168947714,-53.0620799518220849,-56.2426982736496726],"rgb":[0.0666666666666666657,0.8,1],"xyz":[0.398711600400439847,0.505222640396242428,1.02261357574781075],"hpluv":[226.666757851513921,131.304642630845649,76.3887144168947714],"hsluv":[226.666757851513921,99.9999999999969162,76.3887144168947714]},"#11dd00":{"lch":[77.1789729208637851,118.880191052714352,127.435820588671049],"luv":[77.1789729208637851,-72.2639845338074,94.3950017957916572],"rgb":[0.0666666666666666657,0.866666666666666696,0],"xyz":[0.260864802545785,0.518298306129860942,0.0862927536805420531],"hpluv":[127.435820588671049,210.367240137055802,77.1789729208637851],"hsluv":[127.435820588671049,100.000000000002302,77.1789729208637851]},"#11dd11":{"lch":[77.2032167276219,117.940964566200989,127.715012949240474],"luv":[77.2032167276219,-72.148538100067,93.2987651195291],"rgb":[0.0666666666666666657,0.866666666666666696,0.0666666666666666657],"xyz":[0.261876468045422084,0.51870297232971585,0.0916208586452976897],"hpluv":[127.715012949240474,208.973000844217893,77.2032167276219],"hsluv":[127.715012949240474,98.7048375113237739,77.2032167276219]},"#11dd22":{"lch":[77.2481249515021773,116.219968574506154,128.240715222563949],"luv":[77.2481249515021773,-71.936288170647174,91.2811674974022509],"rgb":[0.0666666666666666657,0.866666666666666696,0.133333333333333331],"xyz":[0.263751826183899141,0.519453115585106651,0.101497744841276882],"hpluv":[128.240715222563949,206.413967447437244,77.2481249515021773],"hsluv":[128.240715222563949,98.7114617332334348,77.2481249515021773]},"#11dd33":{"lch":[77.3219716074714114,113.443027450646795,129.129905575085218],"luv":[77.3219716074714114,-71.591714193384675,87.9996984996024],"rgb":[0.0666666666666666657,0.866666666666666696,0.2],"xyz":[0.266839576916356847,0.520688215878089777,0.117759898698888033],"hpluv":[129.129905575085218,202.273081507843187,77.3219716074714114],"hsluv":[129.129905575085218,98.7222220245650419,77.3219716074714114]},"#11dd44":{"lch":[77.4283833065767,109.557638087167803,130.467479357182611],"luv":[77.4283833065767,-71.1046976382296378,83.3486534805139],"rgb":[0.0666666666666666657,0.866666666666666696,0.266666666666666663],"xyz":[0.271297572160575762,0.522471413975777343,0.141238673651774671],"hpluv":[130.467479357182611,196.45511110559741,77.4283833065767],"hsluv":[130.467479357182611,98.737444128486942,77.4283833065767]},"#11dd55":{"lch":[77.5703274630482156,104.589066335953675,132.360930841179908],"luv":[77.5703274630482156,-70.4719757705036471,77.2824263854860192],"rgb":[0.0666666666666666657,0.866666666666666696,0.333333333333333315],"xyz":[0.277259986199937747,0.524856379591522093,0.172640720925748559],"hpluv":[132.360930841179908,188.974657198429043,77.5703274630482156],"hsluv":[132.360930841179908,98.7572451358875583,77.5703274630482156]},"#11dd66":{"lch":[77.7502795105496176,98.645271303892585,134.953797592355841],"luv":[77.7502795105496176,-69.6964700953403167,69.8089650895062732],"rgb":[0.0666666666666666657,0.866666666666666696,0.4],"xyz":[0.284844981973445932,0.527890377900925412,0.212588365332892548],"hpluv":[134.953797592355841,179.968822287066047,77.7502795105496176],"hsluv":[134.953797592355841,98.7815546318288114,77.7502795105496176]},"#11dd77":{"lch":[77.9703113413929714,91.9272626112809377,138.440937564009943],"luv":[77.9703113413929714,-68.7866216277350588,60.9837871589344616],"rgb":[0.0666666666666666657,0.866666666666666696,0.466666666666666674],"xyz":[0.294158994993647838,0.531615983109006263,0.261642167239290457],"hpluv":[138.440937564009943,169.723893920939275,77.9703113413929714],"hsluv":[138.440937564009943,98.8101351189296,77.9703113413929714]},"#11dd88":{"lch":[78.2321436880382919,84.7462074021241705,143.083472555296623],"luv":[78.2321436880382919,-67.7555613828794492,50.90288371727776],"rgb":[0.0666666666666666657,0.866666666666666696,0.533333333333333326],"xyz":[0.305299412095591638,0.536072149949783805,0.320315030642862597],"hpluv":[143.083472555296623,158.721324423216174,78.2321436880382919],"hsluv":[143.083472555296623,98.842607114853692,78.2321436880382919]},"#11dd99":{"lch":[78.5371801027425,77.5491781494168748,149.212222309724666],"luv":[78.5371801027425,-66.6201031545698,39.6942928810235145],"rgb":[0.0666666666666666657,0.866666666666666696,0.6],"xyz":[0.318356376204664393,0.541294935593413,0.389081708283980532],"hpluv":[149.212222309724666,147.710574340426348,78.5371801027425],"hsluv":[149.212222309724666,98.8784794246756746,78.5371801027425]},"#11ddaa":{"lch":[78.8865310768390771,70.9495750262721288,157.187121587348372],"luv":[78.8865310768390771,-65.3996173248364414,27.5087667875819264],"rgb":[0.0666666666666666657,0.866666666666666696,0.66666666666666663],"xyz":[0.333414069169916893,0.547318012779514085,0.468385557900979133],"hpluv":[157.187121587348372,137.807232739715857,78.8865310768390771],"hsluv":[157.187121587348372,98.9171828916172728,78.8865310768390771]},"#11ddbb":{"lch":[79.2810328759594398,65.7363215025974483,167.247861929956969],"luv":[79.2810328759594398,-64.1148749316804611,14.5102300873497096],"rgb":[0.0666666666666666657,0.866666666666666696,0.733333333333333282],"xyz":[0.350551661277253568,0.554173049622448843,0.558643542999620824],"hpluv":[167.247861929956969,130.572542181043048,79.2810328759594398],"hsluv":[167.247861929956969,98.9581049946704496,79.2810328759594398]},"#11ddcc":{"lch":[79.7212637056701396,62.7929370759791,179.209087927276954],"luv":[79.7212637056701396,-62.7869545437069903,0.866767416521026846],"rgb":[0.0666666666666666657,0.866666666666666696,0.8],"xyz":[0.369844036720975322,0.561889999799937701,0.660250053669891],"hpluv":[179.209087927276954,127.935201467087722,79.7212637056701396],"hsluv":[179.209087927276954,99.0006225499112,79.7212637056701396]},"#11dddd":{"lch":[80.2075587483664378,62.8503941808937796,192.177050630061132],"luv":[80.2075587483664378,-61.4362892449526,-13.2572400032679489],"rgb":[0.0666666666666666657,0.866666666666666696,0.866666666666666696],"xyz":[0.39136236227160881,0.570497330020191207,0.773579901569897],"hpluv":[192.177050630061132,131.767009082741112,80.2075587483664378],"hsluv":[192.177050630061132,99.0441302201931109,80.2075587483664378]},"#11ddee":{"lch":[80.7400249746916643,66.1629514334268691,204.757295278220823],"luv":[80.7400249746916643,-60.0819052998990202,-27.707414132610225],"rgb":[0.0666666666666666657,0.866666666666666696,0.933333333333333348],"xyz":[0.415174542537783575,0.580022202126661224,0.8989907176384202],"hpluv":[204.757295278220823,143.22067561241397,80.7400249746916643],"hsluv":[204.757295278220823,99.0880633014724594,80.7400249746916643]},"#11ddff":{"lch":[81.3185562290371848,72.4120095186264194,215.786316478612605],"luv":[81.3185562290371848,-58.7408753400219084,-42.3439332940817934],"rgb":[0.0666666666666666657,0.866666666666666696,1],"xyz":[0.441345590947614941,0.590490621490594,1.03682490593020216],"hpluv":[215.786316478612605,162.428807277722512,81.3185562290371848],"hsluv":[215.786316478612605,99.9999999999959925,81.3185562290371848]}}
\ No newline at end of file
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/hsluv.go b/vendor/github.com/lucasb-eyer/go-colorful/hsluv.go
new file mode 100644
index 0000000..d19fb64
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/hsluv.go
@@ -0,0 +1,207 @@
+package colorful
+
+import "math"
+
+// Source: https://github.com/hsluv/hsluv-go
+// Under MIT License
+// Modified so that Saturation and Luminance are in [0..1] instead of [0..100].
+
+// HSLuv uses a rounded version of the D65. This has no impact on the final RGB
+// values, but to keep high levels of accuracy for internal operations and when
+// comparing to the test values, this modified white reference is used internally.
+//
+// See this GitHub thread for details on these values:
+// https://github.com/hsluv/hsluv/issues/79
+var hSLuvD65 = [3]float64{0.95045592705167, 1.0, 1.089057750759878}
+
+func LuvLChToHSLuv(l, c, h float64) (float64, float64, float64) {
+ // [-1..1] but the code expects it to be [-100..100]
+ c *= 100.0
+ l *= 100.0
+
+ var s, max float64
+ if l > 99.9999999 || l < 0.00000001 {
+ s = 0.0
+ } else {
+ max = maxChromaForLH(l, h)
+ s = c / max * 100.0
+ }
+ return h, clamp01(s / 100.0), clamp01(l / 100.0)
+}
+
+func HSLuvToLuvLCh(h, s, l float64) (float64, float64, float64) {
+ l *= 100.0
+ s *= 100.0
+
+ var c, max float64
+ if l > 99.9999999 || l < 0.00000001 {
+ c = 0.0
+ } else {
+ max = maxChromaForLH(l, h)
+ c = max / 100.0 * s
+ }
+
+ // c is [-100..100], but for LCh it's supposed to be almost [-1..1]
+ return clamp01(l / 100.0), c / 100.0, h
+}
+
+func LuvLChToHPLuv(l, c, h float64) (float64, float64, float64) {
+ // [-1..1] but the code expects it to be [-100..100]
+ c *= 100.0
+ l *= 100.0
+
+ var s, max float64
+ if l > 99.9999999 || l < 0.00000001 {
+ s = 0.0
+ } else {
+ max = maxSafeChromaForL(l)
+ s = c / max * 100.0
+ }
+ return h, s / 100.0, l / 100.0
+}
+
+func HPLuvToLuvLCh(h, s, l float64) (float64, float64, float64) {
+ // [-1..1] but the code expects it to be [-100..100]
+ l *= 100.0
+ s *= 100.0
+
+ var c, max float64
+ if l > 99.9999999 || l < 0.00000001 {
+ c = 0.0
+ } else {
+ max = maxSafeChromaForL(l)
+ c = max / 100.0 * s
+ }
+ return l / 100.0, c / 100.0, h
+}
+
+// HSLuv creates a new Color from values in the HSLuv color space.
+// Hue in [0..360], a Saturation [0..1], and a Luminance (lightness) in [0..1].
+//
+// The returned color values are clamped (using .Clamped), so this will never output
+// an invalid color.
+func HSLuv(h, s, l float64) Color {
+ // HSLuv -> LuvLCh -> CIELUV -> CIEXYZ -> Linear RGB -> sRGB
+ l, u, v := LuvLChToLuv(HSLuvToLuvLCh(h, s, l))
+ return LinearRgb(XyzToLinearRgb(LuvToXyzWhiteRef(l, u, v, hSLuvD65))).Clamped()
+}
+
+// HPLuv creates a new Color from values in the HPLuv color space.
+// Hue in [0..360], a Saturation [0..1], and a Luminance (lightness) in [0..1].
+//
+// The returned color values are clamped (using .Clamped), so this will never output
+// an invalid color.
+func HPLuv(h, s, l float64) Color {
+ // HPLuv -> LuvLCh -> CIELUV -> CIEXYZ -> Linear RGB -> sRGB
+ l, u, v := LuvLChToLuv(HPLuvToLuvLCh(h, s, l))
+ return LinearRgb(XyzToLinearRgb(LuvToXyzWhiteRef(l, u, v, hSLuvD65))).Clamped()
+}
+
+// HSLuv returns the Hue, Saturation and Luminance of the color in the HSLuv
+// color space. Hue in [0..360], a Saturation [0..1], and a Luminance
+// (lightness) in [0..1].
+func (col Color) HSLuv() (h, s, l float64) {
+ // sRGB -> Linear RGB -> CIEXYZ -> CIELUV -> LuvLCh -> HSLuv
+ return LuvLChToHSLuv(col.LuvLChWhiteRef(hSLuvD65))
+}
+
+// HPLuv returns the Hue, Saturation and Luminance of the color in the HSLuv
+// color space. Hue in [0..360], a Saturation [0..1], and a Luminance
+// (lightness) in [0..1].
+//
+// Note that HPLuv can only represent pastel colors, and so the Saturation
+// value could be much larger than 1 for colors it can't represent.
+func (col Color) HPLuv() (h, s, l float64) {
+ return LuvLChToHPLuv(col.LuvLChWhiteRef(hSLuvD65))
+}
+
+// DistanceHSLuv calculates Euclidan distance in the HSLuv colorspace. No idea
+// how useful this is.
+//
+// The Hue value is divided by 100 before the calculation, so that H, S, and L
+// have the same relative ranges.
+func (c1 Color) DistanceHSLuv(c2 Color) float64 {
+ h1, s1, l1 := c1.HSLuv()
+ h2, s2, l2 := c2.HSLuv()
+ return math.Sqrt(sq((h1-h2)/100.0) + sq(s1-s2) + sq(l1-l2))
+}
+
+// DistanceHPLuv calculates Euclidean distance in the HPLuv colorspace. No idea
+// how useful this is.
+//
+// The Hue value is divided by 100 before the calculation, so that H, S, and L
+// have the same relative ranges.
+func (c1 Color) DistanceHPLuv(c2 Color) float64 {
+ h1, s1, l1 := c1.HPLuv()
+ h2, s2, l2 := c2.HPLuv()
+ return math.Sqrt(sq((h1-h2)/100.0) + sq(s1-s2) + sq(l1-l2))
+}
+
+var m = [3][3]float64{
+ {3.2409699419045214, -1.5373831775700935, -0.49861076029300328},
+ {-0.96924363628087983, 1.8759675015077207, 0.041555057407175613},
+ {0.055630079696993609, -0.20397695888897657, 1.0569715142428786},
+}
+
+const kappa = 903.2962962962963
+const epsilon = 0.0088564516790356308
+
+func maxChromaForLH(l, h float64) float64 {
+ hRad := h / 360.0 * math.Pi * 2.0
+ minLength := math.MaxFloat64
+ for _, line := range getBounds(l) {
+ length := lengthOfRayUntilIntersect(hRad, line[0], line[1])
+ if length > 0.0 && length < minLength {
+ minLength = length
+ }
+ }
+ return minLength
+}
+
+func getBounds(l float64) [6][2]float64 {
+ var sub2 float64
+ var ret [6][2]float64
+ sub1 := math.Pow(l+16.0, 3.0) / 1560896.0
+ if sub1 > epsilon {
+ sub2 = sub1
+ } else {
+ sub2 = l / kappa
+ }
+ for i := range m {
+ for k := 0; k < 2; k++ {
+ top1 := (284517.0*m[i][0] - 94839.0*m[i][2]) * sub2
+ top2 := (838422.0*m[i][2]+769860.0*m[i][1]+731718.0*m[i][0])*l*sub2 - 769860.0*float64(k)*l
+ bottom := (632260.0*m[i][2]-126452.0*m[i][1])*sub2 + 126452.0*float64(k)
+ ret[i*2+k][0] = top1 / bottom
+ ret[i*2+k][1] = top2 / bottom
+ }
+ }
+ return ret
+}
+
+func lengthOfRayUntilIntersect(theta, x, y float64) (length float64) {
+ length = y / (math.Sin(theta) - x*math.Cos(theta))
+ return
+}
+
+func maxSafeChromaForL(l float64) float64 {
+ minLength := math.MaxFloat64
+ for _, line := range getBounds(l) {
+ m1 := line[0]
+ b1 := line[1]
+ x := intersectLineLine(m1, b1, -1.0/m1, 0.0)
+ dist := distanceFromPole(x, b1+x*m1)
+ if dist < minLength {
+ minLength = dist
+ }
+ }
+ return minLength
+}
+
+func intersectLineLine(x1, y1, x2, y2 float64) float64 {
+ return (y1 - y2) / (x2 - x1)
+}
+
+func distanceFromPole(x, y float64) float64 {
+ return math.Sqrt(math.Pow(x, 2.0) + math.Pow(y, 2.0))
+}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/soft_palettegen.go b/vendor/github.com/lucasb-eyer/go-colorful/soft_palettegen.go
new file mode 100644
index 0000000..9f7bf6f
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/soft_palettegen.go
@@ -0,0 +1,185 @@
+// Largely inspired by the descriptions in http://lab.medialab.sciences-po.fr/iwanthue/
+// but written from scratch.
+
+package colorful
+
+import (
+ "fmt"
+ "math"
+ "math/rand"
+)
+
+// The algorithm works in L*a*b* color space and converts to RGB in the end.
+// L* in [0..1], a* and b* in [-1..1]
+type lab_t struct {
+ L, A, B float64
+}
+
+type SoftPaletteSettings struct {
+ // A function which can be used to restrict the allowed color-space.
+ CheckColor func(l, a, b float64) bool
+
+ // The higher, the better quality but the slower. Usually two figures.
+ Iterations int
+
+ // Use up to 160000 or 8000 samples of the L*a*b* space (and thus calls to CheckColor).
+ // Set this to true only if your CheckColor shapes the Lab space weirdly.
+ ManySamples bool
+}
+
+// Yeah, windows-stype Foo, FooEx, screw you golang...
+// Uses K-means to cluster the color-space and return the means of the clusters
+// as a new palette of distinctive colors. Falls back to K-medoid if the mean
+// happens to fall outside of the color-space, which can only happen if you
+// specify a CheckColor function.
+func SoftPaletteEx(colorsCount int, settings SoftPaletteSettings) ([]Color, error) {
+
+ // Checks whether it's a valid RGB and also fulfills the potentially provided constraint.
+ check := func(col lab_t) bool {
+ c := Lab(col.L, col.A, col.B)
+ return c.IsValid() && (settings.CheckColor == nil || settings.CheckColor(col.L, col.A, col.B))
+ }
+
+ // Sample the color space. These will be the points k-means is run on.
+ dl := 0.05
+ dab := 0.1
+ if settings.ManySamples {
+ dl = 0.01
+ dab = 0.05
+ }
+
+ samples := make([]lab_t, 0, int(1.0/dl*2.0/dab*2.0/dab))
+ for l := 0.0; l <= 1.0; l += dl {
+ for a := -1.0; a <= 1.0; a += dab {
+ for b := -1.0; b <= 1.0; b += dab {
+ if check(lab_t{l, a, b}) {
+ samples = append(samples, lab_t{l, a, b})
+ }
+ }
+ }
+ }
+
+ // That would cause some infinite loops down there...
+ if len(samples) < colorsCount {
+ return nil, fmt.Errorf("palettegen: more colors requested (%v) than samples available (%v). Your requested color count may be wrong, you might want to use many samples or your constraint function makes the valid color space too small", colorsCount, len(samples))
+ } else if len(samples) == colorsCount {
+ return labs2cols(samples), nil // Oops?
+ }
+
+ // We take the initial means out of the samples, so they are in fact medoids.
+ // This helps us avoid infinite loops or arbitrary cutoffs with too restrictive constraints.
+ means := make([]lab_t, colorsCount)
+ for i := 0; i < colorsCount; i++ {
+ for means[i] = samples[rand.Intn(len(samples))]; in(means, i, means[i]); means[i] = samples[rand.Intn(len(samples))] {
+ }
+ }
+
+ clusters := make([]int, len(samples))
+ samples_used := make([]bool, len(samples))
+
+ // The actual k-means/medoid iterations
+ for i := 0; i < settings.Iterations; i++ {
+ // Reassing the samples to clusters, i.e. to their closest mean.
+ // By the way, also check if any sample is used as a medoid and if so, mark that.
+ for isample, sample := range samples {
+ samples_used[isample] = false
+ mindist := math.Inf(+1)
+ for imean, mean := range means {
+ dist := lab_dist(sample, mean)
+ if dist < mindist {
+ mindist = dist
+ clusters[isample] = imean
+ }
+
+ // Mark samples which are used as a medoid.
+ if lab_eq(sample, mean) {
+ samples_used[isample] = true
+ }
+ }
+ }
+
+ // Compute new means according to the samples.
+ for imean := range means {
+ // The new mean is the average of all samples belonging to it..
+ nsamples := 0
+ newmean := lab_t{0.0, 0.0, 0.0}
+ for isample, sample := range samples {
+ if clusters[isample] == imean {
+ nsamples++
+ newmean.L += sample.L
+ newmean.A += sample.A
+ newmean.B += sample.B
+ }
+ }
+ if nsamples > 0 {
+ newmean.L /= float64(nsamples)
+ newmean.A /= float64(nsamples)
+ newmean.B /= float64(nsamples)
+ } else {
+ // That mean doesn't have any samples? Get a new mean from the sample list!
+ var inewmean int
+ for inewmean = rand.Intn(len(samples_used)); samples_used[inewmean]; inewmean = rand.Intn(len(samples_used)) {
+ }
+ newmean = samples[inewmean]
+ samples_used[inewmean] = true
+ }
+
+ // But now we still need to check whether the new mean is an allowed color.
+ if nsamples > 0 && check(newmean) {
+ // It does, life's good (TM)
+ means[imean] = newmean
+ } else {
+ // New mean isn't an allowed color or doesn't have any samples!
+ // Switch to medoid mode and pick the closest (unused) sample.
+ // This should always find something thanks to len(samples) >= colorsCount
+ mindist := math.Inf(+1)
+ for isample, sample := range samples {
+ if !samples_used[isample] {
+ dist := lab_dist(sample, newmean)
+ if dist < mindist {
+ mindist = dist
+ newmean = sample
+ }
+ }
+ }
+ }
+ }
+ }
+ return labs2cols(means), nil
+}
+
+// A wrapper which uses common parameters.
+func SoftPalette(colorsCount int) ([]Color, error) {
+ return SoftPaletteEx(colorsCount, SoftPaletteSettings{nil, 50, false})
+}
+
+func in(haystack []lab_t, upto int, needle lab_t) bool {
+ for i := 0; i < upto && i < len(haystack); i++ {
+ if haystack[i] == needle {
+ return true
+ }
+ }
+ return false
+}
+
+const LAB_DELTA = 1e-6
+
+func lab_eq(lab1, lab2 lab_t) bool {
+ return math.Abs(lab1.L-lab2.L) < LAB_DELTA &&
+ math.Abs(lab1.A-lab2.A) < LAB_DELTA &&
+ math.Abs(lab1.B-lab2.B) < LAB_DELTA
+}
+
+// That's faster than using colorful's DistanceLab since we would have to
+// convert back and forth for that. Here is no conversion.
+func lab_dist(lab1, lab2 lab_t) float64 {
+ return math.Sqrt(sq(lab1.L-lab2.L) + sq(lab1.A-lab2.A) + sq(lab1.B-lab2.B))
+}
+
+func labs2cols(labs []lab_t) (cols []Color) {
+ cols = make([]Color, len(labs))
+ for k, v := range labs {
+ cols[k] = Lab(v.L, v.A, v.B)
+ }
+ return cols
+}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/warm_palettegen.go b/vendor/github.com/lucasb-eyer/go-colorful/warm_palettegen.go
new file mode 100644
index 0000000..00f42a5
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/warm_palettegen.go
@@ -0,0 +1,25 @@
+package colorful
+
+import (
+ "math/rand"
+)
+
+// Uses the HSV color space to generate colors with similar S,V but distributed
+// evenly along their Hue. This is fast but not always pretty.
+// If you've got time to spare, use Lab (the non-fast below).
+func FastWarmPalette(colorsCount int) (colors []Color) {
+ colors = make([]Color, colorsCount)
+
+ for i := 0; i < colorsCount; i++ {
+ colors[i] = Hsv(float64(i)*(360.0/float64(colorsCount)), 0.55+rand.Float64()*0.2, 0.35+rand.Float64()*0.2)
+ }
+ return
+}
+
+func WarmPalette(colorsCount int) ([]Color, error) {
+ warmy := func(l, a, b float64) bool {
+ _, c, _ := LabToHcl(l, a, b)
+ return 0.1 <= c && c <= 0.4 && 0.2 <= l && l <= 0.5
+ }
+ return SoftPaletteEx(colorsCount, SoftPaletteSettings{warmy, 50, true})
+}
diff --git a/vendor/github.com/mattn/go-isatty/LICENSE b/vendor/github.com/mattn/go-isatty/LICENSE
new file mode 100644
index 0000000..65dc692
--- /dev/null
+++ b/vendor/github.com/mattn/go-isatty/LICENSE
@@ -0,0 +1,9 @@
+Copyright (c) Yasuhiro MATSUMOTO
+
+MIT License (Expat)
+
+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/vendor/github.com/mattn/go-isatty/README.md b/vendor/github.com/mattn/go-isatty/README.md
new file mode 100644
index 0000000..3841835
--- /dev/null
+++ b/vendor/github.com/mattn/go-isatty/README.md
@@ -0,0 +1,50 @@
+# go-isatty
+
+[](http://godoc.org/github.com/mattn/go-isatty)
+[](https://codecov.io/gh/mattn/go-isatty)
+[](https://coveralls.io/github/mattn/go-isatty?branch=master)
+[](https://goreportcard.com/report/mattn/go-isatty)
+
+isatty for golang
+
+## Usage
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/mattn/go-isatty"
+ "os"
+)
+
+func main() {
+ if isatty.IsTerminal(os.Stdout.Fd()) {
+ fmt.Println("Is Terminal")
+ } else if isatty.IsCygwinTerminal(os.Stdout.Fd()) {
+ fmt.Println("Is Cygwin/MSYS2 Terminal")
+ } else {
+ fmt.Println("Is Not Terminal")
+ }
+}
+```
+
+## Installation
+
+```
+$ go get github.com/mattn/go-isatty
+```
+
+## License
+
+MIT
+
+## Author
+
+Yasuhiro Matsumoto (a.k.a mattn)
+
+## Thanks
+
+* k-takata: base idea for IsCygwinTerminal
+
+ https://github.com/k-takata/go-iscygpty
diff --git a/vendor/github.com/mattn/go-isatty/doc.go b/vendor/github.com/mattn/go-isatty/doc.go
new file mode 100644
index 0000000..17d4f90
--- /dev/null
+++ b/vendor/github.com/mattn/go-isatty/doc.go
@@ -0,0 +1,2 @@
+// Package isatty implements interface to isatty
+package isatty
diff --git a/vendor/github.com/mattn/go-isatty/go.test.sh b/vendor/github.com/mattn/go-isatty/go.test.sh
new file mode 100644
index 0000000..012162b
--- /dev/null
+++ b/vendor/github.com/mattn/go-isatty/go.test.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+set -e
+echo "" > coverage.txt
+
+for d in $(go list ./... | grep -v vendor); do
+ go test -race -coverprofile=profile.out -covermode=atomic "$d"
+ if [ -f profile.out ]; then
+ cat profile.out >> coverage.txt
+ rm profile.out
+ fi
+done
diff --git a/vendor/github.com/mattn/go-isatty/isatty_bsd.go b/vendor/github.com/mattn/go-isatty/isatty_bsd.go
new file mode 100644
index 0000000..d0ea68f
--- /dev/null
+++ b/vendor/github.com/mattn/go-isatty/isatty_bsd.go
@@ -0,0 +1,20 @@
+//go:build (darwin || freebsd || openbsd || netbsd || dragonfly || hurd) && !appengine && !tinygo
+// +build darwin freebsd openbsd netbsd dragonfly hurd
+// +build !appengine
+// +build !tinygo
+
+package isatty
+
+import "golang.org/x/sys/unix"
+
+// IsTerminal return true if the file descriptor is terminal.
+func IsTerminal(fd uintptr) bool {
+ _, err := unix.IoctlGetTermios(int(fd), unix.TIOCGETA)
+ return err == nil
+}
+
+// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
+// terminal. This is also always false on this environment.
+func IsCygwinTerminal(fd uintptr) bool {
+ return false
+}
diff --git a/vendor/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go
new file mode 100644
index 0000000..7402e06
--- /dev/null
+++ b/vendor/github.com/mattn/go-isatty/isatty_others.go
@@ -0,0 +1,17 @@
+//go:build (appengine || js || nacl || tinygo || wasm) && !windows
+// +build appengine js nacl tinygo wasm
+// +build !windows
+
+package isatty
+
+// IsTerminal returns true if the file descriptor is terminal which
+// is always false on js and appengine classic which is a sandboxed PaaS.
+func IsTerminal(fd uintptr) bool {
+ return false
+}
+
+// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
+// terminal. This is also always false on this environment.
+func IsCygwinTerminal(fd uintptr) bool {
+ return false
+}
diff --git a/vendor/github.com/mattn/go-isatty/isatty_plan9.go b/vendor/github.com/mattn/go-isatty/isatty_plan9.go
new file mode 100644
index 0000000..bae7f9b
--- /dev/null
+++ b/vendor/github.com/mattn/go-isatty/isatty_plan9.go
@@ -0,0 +1,23 @@
+//go:build plan9
+// +build plan9
+
+package isatty
+
+import (
+ "syscall"
+)
+
+// IsTerminal returns true if the given file descriptor is a terminal.
+func IsTerminal(fd uintptr) bool {
+ path, err := syscall.Fd2path(int(fd))
+ if err != nil {
+ return false
+ }
+ return path == "/dev/cons" || path == "/mnt/term/dev/cons"
+}
+
+// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
+// terminal. This is also always false on this environment.
+func IsCygwinTerminal(fd uintptr) bool {
+ return false
+}
diff --git a/vendor/github.com/mattn/go-isatty/isatty_solaris.go b/vendor/github.com/mattn/go-isatty/isatty_solaris.go
new file mode 100644
index 0000000..0c3acf2
--- /dev/null
+++ b/vendor/github.com/mattn/go-isatty/isatty_solaris.go
@@ -0,0 +1,21 @@
+//go:build solaris && !appengine
+// +build solaris,!appengine
+
+package isatty
+
+import (
+ "golang.org/x/sys/unix"
+)
+
+// IsTerminal returns true if the given file descriptor is a terminal.
+// see: https://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libc/port/gen/isatty.c
+func IsTerminal(fd uintptr) bool {
+ _, err := unix.IoctlGetTermio(int(fd), unix.TCGETA)
+ return err == nil
+}
+
+// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
+// terminal. This is also always false on this environment.
+func IsCygwinTerminal(fd uintptr) bool {
+ return false
+}
diff --git a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go
new file mode 100644
index 0000000..0337d8c
--- /dev/null
+++ b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go
@@ -0,0 +1,20 @@
+//go:build (linux || aix || zos) && !appengine && !tinygo
+// +build linux aix zos
+// +build !appengine
+// +build !tinygo
+
+package isatty
+
+import "golang.org/x/sys/unix"
+
+// IsTerminal return true if the file descriptor is terminal.
+func IsTerminal(fd uintptr) bool {
+ _, err := unix.IoctlGetTermios(int(fd), unix.TCGETS)
+ return err == nil
+}
+
+// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
+// terminal. This is also always false on this environment.
+func IsCygwinTerminal(fd uintptr) bool {
+ return false
+}
diff --git a/vendor/github.com/mattn/go-isatty/isatty_windows.go b/vendor/github.com/mattn/go-isatty/isatty_windows.go
new file mode 100644
index 0000000..8e3c991
--- /dev/null
+++ b/vendor/github.com/mattn/go-isatty/isatty_windows.go
@@ -0,0 +1,125 @@
+//go:build windows && !appengine
+// +build windows,!appengine
+
+package isatty
+
+import (
+ "errors"
+ "strings"
+ "syscall"
+ "unicode/utf16"
+ "unsafe"
+)
+
+const (
+ objectNameInfo uintptr = 1
+ fileNameInfo = 2
+ fileTypePipe = 3
+)
+
+var (
+ kernel32 = syscall.NewLazyDLL("kernel32.dll")
+ ntdll = syscall.NewLazyDLL("ntdll.dll")
+ procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
+ procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx")
+ procGetFileType = kernel32.NewProc("GetFileType")
+ procNtQueryObject = ntdll.NewProc("NtQueryObject")
+)
+
+func init() {
+ // Check if GetFileInformationByHandleEx is available.
+ if procGetFileInformationByHandleEx.Find() != nil {
+ procGetFileInformationByHandleEx = nil
+ }
+}
+
+// IsTerminal return true if the file descriptor is terminal.
+func IsTerminal(fd uintptr) bool {
+ var st uint32
+ r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0)
+ return r != 0 && e == 0
+}
+
+// Check pipe name is used for cygwin/msys2 pty.
+// Cygwin/MSYS2 PTY has a name like:
+// \{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master
+func isCygwinPipeName(name string) bool {
+ token := strings.Split(name, "-")
+ if len(token) < 5 {
+ return false
+ }
+
+ if token[0] != `\msys` &&
+ token[0] != `\cygwin` &&
+ token[0] != `\Device\NamedPipe\msys` &&
+ token[0] != `\Device\NamedPipe\cygwin` {
+ return false
+ }
+
+ if token[1] == "" {
+ return false
+ }
+
+ if !strings.HasPrefix(token[2], "pty") {
+ return false
+ }
+
+ if token[3] != `from` && token[3] != `to` {
+ return false
+ }
+
+ if token[4] != "master" {
+ return false
+ }
+
+ return true
+}
+
+// getFileNameByHandle use the undocomented ntdll NtQueryObject to get file full name from file handler
+// since GetFileInformationByHandleEx is not available under windows Vista and still some old fashion
+// guys are using Windows XP, this is a workaround for those guys, it will also work on system from
+// Windows vista to 10
+// see https://stackoverflow.com/a/18792477 for details
+func getFileNameByHandle(fd uintptr) (string, error) {
+ if procNtQueryObject == nil {
+ return "", errors.New("ntdll.dll: NtQueryObject not supported")
+ }
+
+ var buf [4 + syscall.MAX_PATH]uint16
+ var result int
+ r, _, e := syscall.Syscall6(procNtQueryObject.Addr(), 5,
+ fd, objectNameInfo, uintptr(unsafe.Pointer(&buf)), uintptr(2*len(buf)), uintptr(unsafe.Pointer(&result)), 0)
+ if r != 0 {
+ return "", e
+ }
+ return string(utf16.Decode(buf[4 : 4+buf[0]/2])), nil
+}
+
+// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
+// terminal.
+func IsCygwinTerminal(fd uintptr) bool {
+ if procGetFileInformationByHandleEx == nil {
+ name, err := getFileNameByHandle(fd)
+ if err != nil {
+ return false
+ }
+ return isCygwinPipeName(name)
+ }
+
+ // Cygwin/msys's pty is a pipe.
+ ft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0)
+ if ft != fileTypePipe || e != 0 {
+ return false
+ }
+
+ var buf [2 + syscall.MAX_PATH]uint16
+ r, _, e := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(),
+ 4, fd, fileNameInfo, uintptr(unsafe.Pointer(&buf)),
+ uintptr(len(buf)*2), 0, 0)
+ if r == 0 || e != 0 {
+ return false
+ }
+
+ l := *(*uint32)(unsafe.Pointer(&buf))
+ return isCygwinPipeName(string(utf16.Decode(buf[2 : 2+l/2])))
+}
diff --git a/vendor/github.com/mattn/go-localereader/README.md b/vendor/github.com/mattn/go-localereader/README.md
new file mode 100644
index 0000000..9e10953
--- /dev/null
+++ b/vendor/github.com/mattn/go-localereader/README.md
@@ -0,0 +1,23 @@
+# go-localereader
+
+CodePage decoder for Windows
+
+## Usage
+
+```
+io.Copy(os.Stdout, localereader.NewAcpReader(bytes.Reader(bytesSjis)))
+```
+
+## Installation
+
+```
+$ go get github.com/mattn/go-localereader
+```
+
+## License
+
+MIT
+
+## Author
+
+Yasuhiro Matsumoto (a.k.a. mattn)
diff --git a/vendor/github.com/mattn/go-localereader/localereader.go b/vendor/github.com/mattn/go-localereader/localereader.go
new file mode 100644
index 0000000..47a3137
--- /dev/null
+++ b/vendor/github.com/mattn/go-localereader/localereader.go
@@ -0,0 +1,19 @@
+package localereader
+
+import (
+ "bytes"
+ "io"
+)
+
+func NewReader(r io.Reader) io.Reader {
+ return newReader(r)
+}
+
+func UTF8(b []byte) ([]byte, error) {
+ var buf bytes.Buffer
+ n, err := io.Copy(&buf, newReader(bytes.NewReader(b)))
+ if err != nil {
+ return nil, err
+ }
+ return buf.Bytes()[:n], nil
+}
diff --git a/vendor/github.com/mattn/go-localereader/localereader_unix.go b/vendor/github.com/mattn/go-localereader/localereader_unix.go
new file mode 100644
index 0000000..d85e12e
--- /dev/null
+++ b/vendor/github.com/mattn/go-localereader/localereader_unix.go
@@ -0,0 +1,11 @@
+// +build !windows
+
+package localereader
+
+import (
+ "io"
+)
+
+func newReader(r io.Reader) io.Reader {
+ return r
+}
diff --git a/vendor/github.com/mattn/go-localereader/localereader_windows.go b/vendor/github.com/mattn/go-localereader/localereader_windows.go
new file mode 100644
index 0000000..57c238f
--- /dev/null
+++ b/vendor/github.com/mattn/go-localereader/localereader_windows.go
@@ -0,0 +1,85 @@
+// +build windows
+
+package localereader
+
+import (
+ "io"
+ "syscall"
+ "unicode/utf8"
+ "unsafe"
+
+ "golang.org/x/text/transform"
+)
+
+const (
+ CP_ACP = 0
+ MB_ERR_INVALID_CHARS = 8
+)
+
+var (
+ modkernel32 = syscall.NewLazyDLL("kernel32.dll")
+ procMultiByteToWideChar = modkernel32.NewProc("MultiByteToWideChar")
+ procIsDBCSLeadByte = modkernel32.NewProc("IsDBCSLeadByte")
+)
+
+type codepageDecoder struct {
+ transform.NopResetter
+
+ cp int
+}
+
+func (codepageDecoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ r, size := rune(0), 0
+loop:
+ for ; nSrc < len(src); nSrc += size {
+ switch c0 := src[nSrc]; {
+ case c0 < utf8.RuneSelf:
+ r, size = rune(c0), 1
+
+ default:
+ br, _, _ := procIsDBCSLeadByte.Call(uintptr(src[nSrc]))
+ if br == 0 {
+ r = rune(src[nSrc])
+ size = 1
+ break
+ }
+ if nSrc >= len(src)-1 {
+ r = rune(src[nSrc])
+ size = 1
+ break
+ }
+ n, _, _ := procMultiByteToWideChar.Call(CP_ACP, 0, uintptr(unsafe.Pointer(&src[nSrc])), uintptr(2), uintptr(0), 0)
+ if n <= 0 {
+ err = syscall.GetLastError()
+ break
+ }
+ var us [1]uint16
+ rc, _, _ := procMultiByteToWideChar.Call(CP_ACP, 0, uintptr(unsafe.Pointer(&src[nSrc])), uintptr(2), uintptr(unsafe.Pointer(&us[0])), 1)
+ if rc == 0 {
+ size = 1
+ break
+ }
+ r = rune(us[0])
+ size = 2
+ }
+ if nDst+utf8.RuneLen(r) > len(dst) {
+ err = transform.ErrShortDst
+ break loop
+ }
+ nDst += utf8.EncodeRune(dst[nDst:], r)
+ }
+ return nDst, nSrc, err
+
+}
+
+func newReader(r io.Reader) io.Reader {
+ return transform.NewReader(r, NewAcpDecoder())
+}
+
+func NewCodePageDecoder(cp int) transform.Transformer {
+ return &codepageDecoder{cp: cp}
+}
+
+func NewAcpDecoder() transform.Transformer {
+ return &codepageDecoder{cp: CP_ACP}
+}
diff --git a/vendor/github.com/mattn/go-runewidth/LICENSE b/vendor/github.com/mattn/go-runewidth/LICENSE
new file mode 100644
index 0000000..91b5cef
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Yasuhiro Matsumoto
+
+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/vendor/github.com/mattn/go-runewidth/README.md b/vendor/github.com/mattn/go-runewidth/README.md
new file mode 100644
index 0000000..5e2cfd9
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/README.md
@@ -0,0 +1,27 @@
+go-runewidth
+============
+
+[](https://github.com/mattn/go-runewidth/actions?query=workflow%3Atest)
+[](https://codecov.io/gh/mattn/go-runewidth)
+[](http://godoc.org/github.com/mattn/go-runewidth)
+[](https://goreportcard.com/report/github.com/mattn/go-runewidth)
+
+Provides functions to get fixed width of the character or string.
+
+Usage
+-----
+
+```go
+runewidth.StringWidth("つのだ☆HIRO") == 12
+```
+
+
+Author
+------
+
+Yasuhiro Matsumoto
+
+License
+-------
+
+under the MIT License: http://mattn.mit-license.org/2013
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth.go b/vendor/github.com/mattn/go-runewidth/runewidth.go
new file mode 100644
index 0000000..7dfbb3b
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/runewidth.go
@@ -0,0 +1,358 @@
+package runewidth
+
+import (
+ "os"
+ "strings"
+
+ "github.com/rivo/uniseg"
+)
+
+//go:generate go run script/generate.go
+
+var (
+ // EastAsianWidth will be set true if the current locale is CJK
+ EastAsianWidth bool
+
+ // StrictEmojiNeutral should be set false if handle broken fonts
+ StrictEmojiNeutral bool = true
+
+ // DefaultCondition is a condition in current locale
+ DefaultCondition = &Condition{
+ EastAsianWidth: false,
+ StrictEmojiNeutral: true,
+ }
+)
+
+func init() {
+ handleEnv()
+}
+
+func handleEnv() {
+ env := os.Getenv("RUNEWIDTH_EASTASIAN")
+ if env == "" {
+ EastAsianWidth = IsEastAsian()
+ } else {
+ EastAsianWidth = env == "1"
+ }
+ // update DefaultCondition
+ if DefaultCondition.EastAsianWidth != EastAsianWidth {
+ DefaultCondition.EastAsianWidth = EastAsianWidth
+ if len(DefaultCondition.combinedLut) > 0 {
+ DefaultCondition.combinedLut = DefaultCondition.combinedLut[:0]
+ CreateLUT()
+ }
+ }
+}
+
+type interval struct {
+ first rune
+ last rune
+}
+
+type table []interval
+
+func inTables(r rune, ts ...table) bool {
+ for _, t := range ts {
+ if inTable(r, t) {
+ return true
+ }
+ }
+ return false
+}
+
+func inTable(r rune, t table) bool {
+ if r < t[0].first {
+ return false
+ }
+
+ bot := 0
+ top := len(t) - 1
+ for top >= bot {
+ mid := (bot + top) >> 1
+
+ switch {
+ case t[mid].last < r:
+ bot = mid + 1
+ case t[mid].first > r:
+ top = mid - 1
+ default:
+ return true
+ }
+ }
+
+ return false
+}
+
+var private = table{
+ {0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD},
+}
+
+var nonprint = table{
+ {0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD},
+ {0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F},
+ {0x2028, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF},
+ {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF},
+}
+
+// Condition have flag EastAsianWidth whether the current locale is CJK or not.
+type Condition struct {
+ combinedLut []byte
+ EastAsianWidth bool
+ StrictEmojiNeutral bool
+}
+
+// NewCondition return new instance of Condition which is current locale.
+func NewCondition() *Condition {
+ return &Condition{
+ EastAsianWidth: EastAsianWidth,
+ StrictEmojiNeutral: StrictEmojiNeutral,
+ }
+}
+
+// RuneWidth returns the number of cells in r.
+// See http://www.unicode.org/reports/tr11/
+func (c *Condition) RuneWidth(r rune) int {
+ if r < 0 || r > 0x10FFFF {
+ return 0
+ }
+ if len(c.combinedLut) > 0 {
+ return int(c.combinedLut[r>>1]>>(uint(r&1)*4)) & 3
+ }
+ // optimized version, verified by TestRuneWidthChecksums()
+ if !c.EastAsianWidth {
+ switch {
+ case r < 0x20:
+ return 0
+ case (r >= 0x7F && r <= 0x9F) || r == 0xAD: // nonprint
+ return 0
+ case r < 0x300:
+ return 1
+ case inTable(r, narrow):
+ return 1
+ case inTables(r, nonprint, combining):
+ return 0
+ case inTable(r, doublewidth):
+ return 2
+ default:
+ return 1
+ }
+ } else {
+ switch {
+ case inTables(r, nonprint, combining):
+ return 0
+ case inTable(r, narrow):
+ return 1
+ case inTables(r, ambiguous, doublewidth):
+ return 2
+ case !c.StrictEmojiNeutral && inTables(r, ambiguous, emoji, narrow):
+ return 2
+ default:
+ return 1
+ }
+ }
+}
+
+// CreateLUT will create an in-memory lookup table of 557056 bytes for faster operation.
+// This should not be called concurrently with other operations on c.
+// If options in c is changed, CreateLUT should be called again.
+func (c *Condition) CreateLUT() {
+ const max = 0x110000
+ lut := c.combinedLut
+ if len(c.combinedLut) != 0 {
+ // Remove so we don't use it.
+ c.combinedLut = nil
+ } else {
+ lut = make([]byte, max/2)
+ }
+ for i := range lut {
+ i32 := int32(i * 2)
+ x0 := c.RuneWidth(i32)
+ x1 := c.RuneWidth(i32 + 1)
+ lut[i] = uint8(x0) | uint8(x1)<<4
+ }
+ c.combinedLut = lut
+}
+
+// StringWidth return width as you can see
+func (c *Condition) StringWidth(s string) (width int) {
+ g := uniseg.NewGraphemes(s)
+ for g.Next() {
+ var chWidth int
+ for _, r := range g.Runes() {
+ chWidth = c.RuneWidth(r)
+ if chWidth > 0 {
+ break // Our best guess at this point is to use the width of the first non-zero-width rune.
+ }
+ }
+ width += chWidth
+ }
+ return
+}
+
+// Truncate return string truncated with w cells
+func (c *Condition) Truncate(s string, w int, tail string) string {
+ if c.StringWidth(s) <= w {
+ return s
+ }
+ w -= c.StringWidth(tail)
+ var width int
+ pos := len(s)
+ g := uniseg.NewGraphemes(s)
+ for g.Next() {
+ var chWidth int
+ for _, r := range g.Runes() {
+ chWidth = c.RuneWidth(r)
+ if chWidth > 0 {
+ break // See StringWidth() for details.
+ }
+ }
+ if width+chWidth > w {
+ pos, _ = g.Positions()
+ break
+ }
+ width += chWidth
+ }
+ return s[:pos] + tail
+}
+
+// TruncateLeft cuts w cells from the beginning of the `s`.
+func (c *Condition) TruncateLeft(s string, w int, prefix string) string {
+ if c.StringWidth(s) <= w {
+ return prefix
+ }
+
+ var width int
+ pos := len(s)
+
+ g := uniseg.NewGraphemes(s)
+ for g.Next() {
+ var chWidth int
+ for _, r := range g.Runes() {
+ chWidth = c.RuneWidth(r)
+ if chWidth > 0 {
+ break // See StringWidth() for details.
+ }
+ }
+
+ if width+chWidth > w {
+ if width < w {
+ _, pos = g.Positions()
+ prefix += strings.Repeat(" ", width+chWidth-w)
+ } else {
+ pos, _ = g.Positions()
+ }
+
+ break
+ }
+
+ width += chWidth
+ }
+
+ return prefix + s[pos:]
+}
+
+// Wrap return string wrapped with w cells
+func (c *Condition) Wrap(s string, w int) string {
+ width := 0
+ out := ""
+ for _, r := range s {
+ cw := c.RuneWidth(r)
+ if r == '\n' {
+ out += string(r)
+ width = 0
+ continue
+ } else if width+cw > w {
+ out += "\n"
+ width = 0
+ out += string(r)
+ width += cw
+ continue
+ }
+ out += string(r)
+ width += cw
+ }
+ return out
+}
+
+// FillLeft return string filled in left by spaces in w cells
+func (c *Condition) FillLeft(s string, w int) string {
+ width := c.StringWidth(s)
+ count := w - width
+ if count > 0 {
+ b := make([]byte, count)
+ for i := range b {
+ b[i] = ' '
+ }
+ return string(b) + s
+ }
+ return s
+}
+
+// FillRight return string filled in left by spaces in w cells
+func (c *Condition) FillRight(s string, w int) string {
+ width := c.StringWidth(s)
+ count := w - width
+ if count > 0 {
+ b := make([]byte, count)
+ for i := range b {
+ b[i] = ' '
+ }
+ return s + string(b)
+ }
+ return s
+}
+
+// RuneWidth returns the number of cells in r.
+// See http://www.unicode.org/reports/tr11/
+func RuneWidth(r rune) int {
+ return DefaultCondition.RuneWidth(r)
+}
+
+// IsAmbiguousWidth returns whether is ambiguous width or not.
+func IsAmbiguousWidth(r rune) bool {
+ return inTables(r, private, ambiguous)
+}
+
+// IsNeutralWidth returns whether is neutral width or not.
+func IsNeutralWidth(r rune) bool {
+ return inTable(r, neutral)
+}
+
+// StringWidth return width as you can see
+func StringWidth(s string) (width int) {
+ return DefaultCondition.StringWidth(s)
+}
+
+// Truncate return string truncated with w cells
+func Truncate(s string, w int, tail string) string {
+ return DefaultCondition.Truncate(s, w, tail)
+}
+
+// TruncateLeft cuts w cells from the beginning of the `s`.
+func TruncateLeft(s string, w int, prefix string) string {
+ return DefaultCondition.TruncateLeft(s, w, prefix)
+}
+
+// Wrap return string wrapped with w cells
+func Wrap(s string, w int) string {
+ return DefaultCondition.Wrap(s, w)
+}
+
+// FillLeft return string filled in left by spaces in w cells
+func FillLeft(s string, w int) string {
+ return DefaultCondition.FillLeft(s, w)
+}
+
+// FillRight return string filled in left by spaces in w cells
+func FillRight(s string, w int) string {
+ return DefaultCondition.FillRight(s, w)
+}
+
+// CreateLUT will create an in-memory lookup table of 557055 bytes for faster operation.
+// This should not be called concurrently with other operations.
+func CreateLUT() {
+ if len(DefaultCondition.combinedLut) > 0 {
+ return
+ }
+ DefaultCondition.CreateLUT()
+}
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_appengine.go b/vendor/github.com/mattn/go-runewidth/runewidth_appengine.go
new file mode 100644
index 0000000..84b6528
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/runewidth_appengine.go
@@ -0,0 +1,9 @@
+//go:build appengine
+// +build appengine
+
+package runewidth
+
+// IsEastAsian return true if the current locale is CJK
+func IsEastAsian() bool {
+ return false
+}
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_js.go b/vendor/github.com/mattn/go-runewidth/runewidth_js.go
new file mode 100644
index 0000000..c2abbc2
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/runewidth_js.go
@@ -0,0 +1,9 @@
+//go:build js && !appengine
+// +build js,!appengine
+
+package runewidth
+
+func IsEastAsian() bool {
+ // TODO: Implement this for the web. Detect east asian in a compatible way, and return true.
+ return false
+}
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_posix.go b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go
new file mode 100644
index 0000000..5a31d73
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go
@@ -0,0 +1,81 @@
+//go:build !windows && !js && !appengine
+// +build !windows,!js,!appengine
+
+package runewidth
+
+import (
+ "os"
+ "regexp"
+ "strings"
+)
+
+var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`)
+
+var mblenTable = map[string]int{
+ "utf-8": 6,
+ "utf8": 6,
+ "jis": 8,
+ "eucjp": 3,
+ "euckr": 2,
+ "euccn": 2,
+ "sjis": 2,
+ "cp932": 2,
+ "cp51932": 2,
+ "cp936": 2,
+ "cp949": 2,
+ "cp950": 2,
+ "big5": 2,
+ "gbk": 2,
+ "gb2312": 2,
+}
+
+func isEastAsian(locale string) bool {
+ charset := strings.ToLower(locale)
+ r := reLoc.FindStringSubmatch(locale)
+ if len(r) == 2 {
+ charset = strings.ToLower(r[1])
+ }
+
+ if strings.HasSuffix(charset, "@cjk_narrow") {
+ return false
+ }
+
+ for pos, b := range []byte(charset) {
+ if b == '@' {
+ charset = charset[:pos]
+ break
+ }
+ }
+ max := 1
+ if m, ok := mblenTable[charset]; ok {
+ max = m
+ }
+ if max > 1 && (charset[0] != 'u' ||
+ strings.HasPrefix(locale, "ja") ||
+ strings.HasPrefix(locale, "ko") ||
+ strings.HasPrefix(locale, "zh")) {
+ return true
+ }
+ return false
+}
+
+// IsEastAsian return true if the current locale is CJK
+func IsEastAsian() bool {
+ locale := os.Getenv("LC_ALL")
+ if locale == "" {
+ locale = os.Getenv("LC_CTYPE")
+ }
+ if locale == "" {
+ locale = os.Getenv("LANG")
+ }
+
+ // ignore C locale
+ if locale == "POSIX" || locale == "C" {
+ return false
+ }
+ if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') {
+ return false
+ }
+
+ return isEastAsian(locale)
+}
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_table.go b/vendor/github.com/mattn/go-runewidth/runewidth_table.go
new file mode 100644
index 0000000..ad025ad
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/runewidth_table.go
@@ -0,0 +1,450 @@
+// Code generated by script/generate.go. DO NOT EDIT.
+
+package runewidth
+
+var combining = table{
+ {0x0300, 0x036F}, {0x0483, 0x0489}, {0x07EB, 0x07F3},
+ {0x0C00, 0x0C00}, {0x0C04, 0x0C04}, {0x0CF3, 0x0CF3},
+ {0x0D00, 0x0D01}, {0x135D, 0x135F}, {0x1A7F, 0x1A7F},
+ {0x1AB0, 0x1ACE}, {0x1B6B, 0x1B73}, {0x1DC0, 0x1DFF},
+ {0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2DE0, 0x2DFF},
+ {0x3099, 0x309A}, {0xA66F, 0xA672}, {0xA674, 0xA67D},
+ {0xA69E, 0xA69F}, {0xA6F0, 0xA6F1}, {0xA8E0, 0xA8F1},
+ {0xFE20, 0xFE2F}, {0x101FD, 0x101FD}, {0x10376, 0x1037A},
+ {0x10EAB, 0x10EAC}, {0x10F46, 0x10F50}, {0x10F82, 0x10F85},
+ {0x11300, 0x11301}, {0x1133B, 0x1133C}, {0x11366, 0x1136C},
+ {0x11370, 0x11374}, {0x16AF0, 0x16AF4}, {0x1CF00, 0x1CF2D},
+ {0x1CF30, 0x1CF46}, {0x1D165, 0x1D169}, {0x1D16D, 0x1D172},
+ {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD},
+ {0x1D242, 0x1D244}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018},
+ {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, {0x1E026, 0x1E02A},
+ {0x1E08F, 0x1E08F}, {0x1E8D0, 0x1E8D6},
+}
+
+var doublewidth = table{
+ {0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A},
+ {0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3},
+ {0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653},
+ {0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1},
+ {0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5},
+ {0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA},
+ {0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA},
+ {0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B},
+ {0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E},
+ {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797},
+ {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C},
+ {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99},
+ {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x303E},
+ {0x3041, 0x3096}, {0x3099, 0x30FF}, {0x3105, 0x312F},
+ {0x3131, 0x318E}, {0x3190, 0x31E3}, {0x31EF, 0x321E},
+ {0x3220, 0x3247}, {0x3250, 0x4DBF}, {0x4E00, 0xA48C},
+ {0xA490, 0xA4C6}, {0xA960, 0xA97C}, {0xAC00, 0xD7A3},
+ {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52},
+ {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60},
+ {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE4}, {0x16FF0, 0x16FF1},
+ {0x17000, 0x187F7}, {0x18800, 0x18CD5}, {0x18D00, 0x18D08},
+ {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1AFFD, 0x1AFFE},
+ {0x1B000, 0x1B122}, {0x1B132, 0x1B132}, {0x1B150, 0x1B152},
+ {0x1B155, 0x1B155}, {0x1B164, 0x1B167}, {0x1B170, 0x1B2FB},
+ {0x1F004, 0x1F004}, {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E},
+ {0x1F191, 0x1F19A}, {0x1F200, 0x1F202}, {0x1F210, 0x1F23B},
+ {0x1F240, 0x1F248}, {0x1F250, 0x1F251}, {0x1F260, 0x1F265},
+ {0x1F300, 0x1F320}, {0x1F32D, 0x1F335}, {0x1F337, 0x1F37C},
+ {0x1F37E, 0x1F393}, {0x1F3A0, 0x1F3CA}, {0x1F3CF, 0x1F3D3},
+ {0x1F3E0, 0x1F3F0}, {0x1F3F4, 0x1F3F4}, {0x1F3F8, 0x1F43E},
+ {0x1F440, 0x1F440}, {0x1F442, 0x1F4FC}, {0x1F4FF, 0x1F53D},
+ {0x1F54B, 0x1F54E}, {0x1F550, 0x1F567}, {0x1F57A, 0x1F57A},
+ {0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A4}, {0x1F5FB, 0x1F64F},
+ {0x1F680, 0x1F6C5}, {0x1F6CC, 0x1F6CC}, {0x1F6D0, 0x1F6D2},
+ {0x1F6D5, 0x1F6D7}, {0x1F6DC, 0x1F6DF}, {0x1F6EB, 0x1F6EC},
+ {0x1F6F4, 0x1F6FC}, {0x1F7E0, 0x1F7EB}, {0x1F7F0, 0x1F7F0},
+ {0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1F9FF},
+ {0x1FA70, 0x1FA7C}, {0x1FA80, 0x1FA88}, {0x1FA90, 0x1FABD},
+ {0x1FABF, 0x1FAC5}, {0x1FACE, 0x1FADB}, {0x1FAE0, 0x1FAE8},
+ {0x1FAF0, 0x1FAF8}, {0x20000, 0x2FFFD}, {0x30000, 0x3FFFD},
+}
+
+var ambiguous = table{
+ {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8},
+ {0x00AA, 0x00AA}, {0x00AD, 0x00AE}, {0x00B0, 0x00B4},
+ {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6},
+ {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1},
+ {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED},
+ {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA},
+ {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101},
+ {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B},
+ {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133},
+ {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144},
+ {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153},
+ {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE},
+ {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4},
+ {0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA},
+ {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261},
+ {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB},
+ {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB},
+ {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0300, 0x036F},
+ {0x0391, 0x03A1}, {0x03A3, 0x03A9}, {0x03B1, 0x03C1},
+ {0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F},
+ {0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016},
+ {0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022},
+ {0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033},
+ {0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E},
+ {0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084},
+ {0x20AC, 0x20AC}, {0x2103, 0x2103}, {0x2105, 0x2105},
+ {0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116},
+ {0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B},
+ {0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B},
+ {0x2170, 0x2179}, {0x2189, 0x2189}, {0x2190, 0x2199},
+ {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4},
+ {0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203},
+ {0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F},
+ {0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A},
+ {0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225},
+ {0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237},
+ {0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C},
+ {0x2252, 0x2252}, {0x2260, 0x2261}, {0x2264, 0x2267},
+ {0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283},
+ {0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299},
+ {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312},
+ {0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573},
+ {0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1},
+ {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7},
+ {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8},
+ {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, {0x25E2, 0x25E5},
+ {0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609},
+ {0x260E, 0x260F}, {0x261C, 0x261C}, {0x261E, 0x261E},
+ {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661},
+ {0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D},
+ {0x266F, 0x266F}, {0x269E, 0x269F}, {0x26BF, 0x26BF},
+ {0x26C6, 0x26CD}, {0x26CF, 0x26D3}, {0x26D5, 0x26E1},
+ {0x26E3, 0x26E3}, {0x26E8, 0x26E9}, {0x26EB, 0x26F1},
+ {0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC},
+ {0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F},
+ {0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF},
+ {0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A},
+ {0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D},
+ {0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF},
+ {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD},
+}
+var narrow = table{
+ {0x0020, 0x007E}, {0x00A2, 0x00A3}, {0x00A5, 0x00A6},
+ {0x00AC, 0x00AC}, {0x00AF, 0x00AF}, {0x27E6, 0x27ED},
+ {0x2985, 0x2986},
+}
+
+var neutral = table{
+ {0x0000, 0x001F}, {0x007F, 0x00A0}, {0x00A9, 0x00A9},
+ {0x00AB, 0x00AB}, {0x00B5, 0x00B5}, {0x00BB, 0x00BB},
+ {0x00C0, 0x00C5}, {0x00C7, 0x00CF}, {0x00D1, 0x00D6},
+ {0x00D9, 0x00DD}, {0x00E2, 0x00E5}, {0x00E7, 0x00E7},
+ {0x00EB, 0x00EB}, {0x00EE, 0x00EF}, {0x00F1, 0x00F1},
+ {0x00F4, 0x00F6}, {0x00FB, 0x00FB}, {0x00FD, 0x00FD},
+ {0x00FF, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112},
+ {0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A},
+ {0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E},
+ {0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C},
+ {0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A},
+ {0x016C, 0x01CD}, {0x01CF, 0x01CF}, {0x01D1, 0x01D1},
+ {0x01D3, 0x01D3}, {0x01D5, 0x01D5}, {0x01D7, 0x01D7},
+ {0x01D9, 0x01D9}, {0x01DB, 0x01DB}, {0x01DD, 0x0250},
+ {0x0252, 0x0260}, {0x0262, 0x02C3}, {0x02C5, 0x02C6},
+ {0x02C8, 0x02C8}, {0x02CC, 0x02CC}, {0x02CE, 0x02CF},
+ {0x02D1, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE},
+ {0x02E0, 0x02FF}, {0x0370, 0x0377}, {0x037A, 0x037F},
+ {0x0384, 0x038A}, {0x038C, 0x038C}, {0x038E, 0x0390},
+ {0x03AA, 0x03B0}, {0x03C2, 0x03C2}, {0x03CA, 0x0400},
+ {0x0402, 0x040F}, {0x0450, 0x0450}, {0x0452, 0x052F},
+ {0x0531, 0x0556}, {0x0559, 0x058A}, {0x058D, 0x058F},
+ {0x0591, 0x05C7}, {0x05D0, 0x05EA}, {0x05EF, 0x05F4},
+ {0x0600, 0x070D}, {0x070F, 0x074A}, {0x074D, 0x07B1},
+ {0x07C0, 0x07FA}, {0x07FD, 0x082D}, {0x0830, 0x083E},
+ {0x0840, 0x085B}, {0x085E, 0x085E}, {0x0860, 0x086A},
+ {0x0870, 0x088E}, {0x0890, 0x0891}, {0x0898, 0x0983},
+ {0x0985, 0x098C}, {0x098F, 0x0990}, {0x0993, 0x09A8},
+ {0x09AA, 0x09B0}, {0x09B2, 0x09B2}, {0x09B6, 0x09B9},
+ {0x09BC, 0x09C4}, {0x09C7, 0x09C8}, {0x09CB, 0x09CE},
+ {0x09D7, 0x09D7}, {0x09DC, 0x09DD}, {0x09DF, 0x09E3},
+ {0x09E6, 0x09FE}, {0x0A01, 0x0A03}, {0x0A05, 0x0A0A},
+ {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30},
+ {0x0A32, 0x0A33}, {0x0A35, 0x0A36}, {0x0A38, 0x0A39},
+ {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42}, {0x0A47, 0x0A48},
+ {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, {0x0A59, 0x0A5C},
+ {0x0A5E, 0x0A5E}, {0x0A66, 0x0A76}, {0x0A81, 0x0A83},
+ {0x0A85, 0x0A8D}, {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8},
+ {0x0AAA, 0x0AB0}, {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9},
+ {0x0ABC, 0x0AC5}, {0x0AC7, 0x0AC9}, {0x0ACB, 0x0ACD},
+ {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE3}, {0x0AE6, 0x0AF1},
+ {0x0AF9, 0x0AFF}, {0x0B01, 0x0B03}, {0x0B05, 0x0B0C},
+ {0x0B0F, 0x0B10}, {0x0B13, 0x0B28}, {0x0B2A, 0x0B30},
+ {0x0B32, 0x0B33}, {0x0B35, 0x0B39}, {0x0B3C, 0x0B44},
+ {0x0B47, 0x0B48}, {0x0B4B, 0x0B4D}, {0x0B55, 0x0B57},
+ {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B63}, {0x0B66, 0x0B77},
+ {0x0B82, 0x0B83}, {0x0B85, 0x0B8A}, {0x0B8E, 0x0B90},
+ {0x0B92, 0x0B95}, {0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C},
+ {0x0B9E, 0x0B9F}, {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA},
+ {0x0BAE, 0x0BB9}, {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8},
+ {0x0BCA, 0x0BCD}, {0x0BD0, 0x0BD0}, {0x0BD7, 0x0BD7},
+ {0x0BE6, 0x0BFA}, {0x0C00, 0x0C0C}, {0x0C0E, 0x0C10},
+ {0x0C12, 0x0C28}, {0x0C2A, 0x0C39}, {0x0C3C, 0x0C44},
+ {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56},
+ {0x0C58, 0x0C5A}, {0x0C5D, 0x0C5D}, {0x0C60, 0x0C63},
+ {0x0C66, 0x0C6F}, {0x0C77, 0x0C8C}, {0x0C8E, 0x0C90},
+ {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9},
+ {0x0CBC, 0x0CC4}, {0x0CC6, 0x0CC8}, {0x0CCA, 0x0CCD},
+ {0x0CD5, 0x0CD6}, {0x0CDD, 0x0CDE}, {0x0CE0, 0x0CE3},
+ {0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF3}, {0x0D00, 0x0D0C},
+ {0x0D0E, 0x0D10}, {0x0D12, 0x0D44}, {0x0D46, 0x0D48},
+ {0x0D4A, 0x0D4F}, {0x0D54, 0x0D63}, {0x0D66, 0x0D7F},
+ {0x0D81, 0x0D83}, {0x0D85, 0x0D96}, {0x0D9A, 0x0DB1},
+ {0x0DB3, 0x0DBB}, {0x0DBD, 0x0DBD}, {0x0DC0, 0x0DC6},
+ {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4}, {0x0DD6, 0x0DD6},
+ {0x0DD8, 0x0DDF}, {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF4},
+ {0x0E01, 0x0E3A}, {0x0E3F, 0x0E5B}, {0x0E81, 0x0E82},
+ {0x0E84, 0x0E84}, {0x0E86, 0x0E8A}, {0x0E8C, 0x0EA3},
+ {0x0EA5, 0x0EA5}, {0x0EA7, 0x0EBD}, {0x0EC0, 0x0EC4},
+ {0x0EC6, 0x0EC6}, {0x0EC8, 0x0ECE}, {0x0ED0, 0x0ED9},
+ {0x0EDC, 0x0EDF}, {0x0F00, 0x0F47}, {0x0F49, 0x0F6C},
+ {0x0F71, 0x0F97}, {0x0F99, 0x0FBC}, {0x0FBE, 0x0FCC},
+ {0x0FCE, 0x0FDA}, {0x1000, 0x10C5}, {0x10C7, 0x10C7},
+ {0x10CD, 0x10CD}, {0x10D0, 0x10FF}, {0x1160, 0x1248},
+ {0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258},
+ {0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D},
+ {0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE},
+ {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6},
+ {0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A},
+ {0x135D, 0x137C}, {0x1380, 0x1399}, {0x13A0, 0x13F5},
+ {0x13F8, 0x13FD}, {0x1400, 0x169C}, {0x16A0, 0x16F8},
+ {0x1700, 0x1715}, {0x171F, 0x1736}, {0x1740, 0x1753},
+ {0x1760, 0x176C}, {0x176E, 0x1770}, {0x1772, 0x1773},
+ {0x1780, 0x17DD}, {0x17E0, 0x17E9}, {0x17F0, 0x17F9},
+ {0x1800, 0x1819}, {0x1820, 0x1878}, {0x1880, 0x18AA},
+ {0x18B0, 0x18F5}, {0x1900, 0x191E}, {0x1920, 0x192B},
+ {0x1930, 0x193B}, {0x1940, 0x1940}, {0x1944, 0x196D},
+ {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9},
+ {0x19D0, 0x19DA}, {0x19DE, 0x1A1B}, {0x1A1E, 0x1A5E},
+ {0x1A60, 0x1A7C}, {0x1A7F, 0x1A89}, {0x1A90, 0x1A99},
+ {0x1AA0, 0x1AAD}, {0x1AB0, 0x1ACE}, {0x1B00, 0x1B4C},
+ {0x1B50, 0x1B7E}, {0x1B80, 0x1BF3}, {0x1BFC, 0x1C37},
+ {0x1C3B, 0x1C49}, {0x1C4D, 0x1C88}, {0x1C90, 0x1CBA},
+ {0x1CBD, 0x1CC7}, {0x1CD0, 0x1CFA}, {0x1D00, 0x1F15},
+ {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D},
+ {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B},
+ {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4},
+ {0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3}, {0x1FD6, 0x1FDB},
+ {0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFE},
+ {0x2000, 0x200F}, {0x2011, 0x2012}, {0x2017, 0x2017},
+ {0x201A, 0x201B}, {0x201E, 0x201F}, {0x2023, 0x2023},
+ {0x2028, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034},
+ {0x2036, 0x203A}, {0x203C, 0x203D}, {0x203F, 0x2064},
+ {0x2066, 0x2071}, {0x2075, 0x207E}, {0x2080, 0x2080},
+ {0x2085, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8},
+ {0x20AA, 0x20AB}, {0x20AD, 0x20C0}, {0x20D0, 0x20F0},
+ {0x2100, 0x2102}, {0x2104, 0x2104}, {0x2106, 0x2108},
+ {0x210A, 0x2112}, {0x2114, 0x2115}, {0x2117, 0x2120},
+ {0x2123, 0x2125}, {0x2127, 0x212A}, {0x212C, 0x2152},
+ {0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F},
+ {0x217A, 0x2188}, {0x218A, 0x218B}, {0x219A, 0x21B7},
+ {0x21BA, 0x21D1}, {0x21D3, 0x21D3}, {0x21D5, 0x21E6},
+ {0x21E8, 0x21FF}, {0x2201, 0x2201}, {0x2204, 0x2206},
+ {0x2209, 0x220A}, {0x220C, 0x220E}, {0x2210, 0x2210},
+ {0x2212, 0x2214}, {0x2216, 0x2219}, {0x221B, 0x221C},
+ {0x2221, 0x2222}, {0x2224, 0x2224}, {0x2226, 0x2226},
+ {0x222D, 0x222D}, {0x222F, 0x2233}, {0x2238, 0x223B},
+ {0x223E, 0x2247}, {0x2249, 0x224B}, {0x224D, 0x2251},
+ {0x2253, 0x225F}, {0x2262, 0x2263}, {0x2268, 0x2269},
+ {0x226C, 0x226D}, {0x2270, 0x2281}, {0x2284, 0x2285},
+ {0x2288, 0x2294}, {0x2296, 0x2298}, {0x229A, 0x22A4},
+ {0x22A6, 0x22BE}, {0x22C0, 0x2311}, {0x2313, 0x2319},
+ {0x231C, 0x2328}, {0x232B, 0x23E8}, {0x23ED, 0x23EF},
+ {0x23F1, 0x23F2}, {0x23F4, 0x2426}, {0x2440, 0x244A},
+ {0x24EA, 0x24EA}, {0x254C, 0x254F}, {0x2574, 0x257F},
+ {0x2590, 0x2591}, {0x2596, 0x259F}, {0x25A2, 0x25A2},
+ {0x25AA, 0x25B1}, {0x25B4, 0x25B5}, {0x25B8, 0x25BB},
+ {0x25BE, 0x25BF}, {0x25C2, 0x25C5}, {0x25C9, 0x25CA},
+ {0x25CC, 0x25CD}, {0x25D2, 0x25E1}, {0x25E6, 0x25EE},
+ {0x25F0, 0x25FC}, {0x25FF, 0x2604}, {0x2607, 0x2608},
+ {0x260A, 0x260D}, {0x2610, 0x2613}, {0x2616, 0x261B},
+ {0x261D, 0x261D}, {0x261F, 0x263F}, {0x2641, 0x2641},
+ {0x2643, 0x2647}, {0x2654, 0x265F}, {0x2662, 0x2662},
+ {0x2666, 0x2666}, {0x266B, 0x266B}, {0x266E, 0x266E},
+ {0x2670, 0x267E}, {0x2680, 0x2692}, {0x2694, 0x269D},
+ {0x26A0, 0x26A0}, {0x26A2, 0x26A9}, {0x26AC, 0x26BC},
+ {0x26C0, 0x26C3}, {0x26E2, 0x26E2}, {0x26E4, 0x26E7},
+ {0x2700, 0x2704}, {0x2706, 0x2709}, {0x270C, 0x2727},
+ {0x2729, 0x273C}, {0x273E, 0x274B}, {0x274D, 0x274D},
+ {0x274F, 0x2752}, {0x2756, 0x2756}, {0x2758, 0x2775},
+ {0x2780, 0x2794}, {0x2798, 0x27AF}, {0x27B1, 0x27BE},
+ {0x27C0, 0x27E5}, {0x27EE, 0x2984}, {0x2987, 0x2B1A},
+ {0x2B1D, 0x2B4F}, {0x2B51, 0x2B54}, {0x2B5A, 0x2B73},
+ {0x2B76, 0x2B95}, {0x2B97, 0x2CF3}, {0x2CF9, 0x2D25},
+ {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67},
+ {0x2D6F, 0x2D70}, {0x2D7F, 0x2D96}, {0x2DA0, 0x2DA6},
+ {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE},
+ {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6},
+ {0x2DD8, 0x2DDE}, {0x2DE0, 0x2E5D}, {0x303F, 0x303F},
+ {0x4DC0, 0x4DFF}, {0xA4D0, 0xA62B}, {0xA640, 0xA6F7},
+ {0xA700, 0xA7CA}, {0xA7D0, 0xA7D1}, {0xA7D3, 0xA7D3},
+ {0xA7D5, 0xA7D9}, {0xA7F2, 0xA82C}, {0xA830, 0xA839},
+ {0xA840, 0xA877}, {0xA880, 0xA8C5}, {0xA8CE, 0xA8D9},
+ {0xA8E0, 0xA953}, {0xA95F, 0xA95F}, {0xA980, 0xA9CD},
+ {0xA9CF, 0xA9D9}, {0xA9DE, 0xA9FE}, {0xAA00, 0xAA36},
+ {0xAA40, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA5C, 0xAAC2},
+ {0xAADB, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E},
+ {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E},
+ {0xAB30, 0xAB6B}, {0xAB70, 0xABED}, {0xABF0, 0xABF9},
+ {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDFFF},
+ {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB36},
+ {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41},
+ {0xFB43, 0xFB44}, {0xFB46, 0xFBC2}, {0xFBD3, 0xFD8F},
+ {0xFD92, 0xFDC7}, {0xFDCF, 0xFDCF}, {0xFDF0, 0xFDFF},
+ {0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC},
+ {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFC}, {0x10000, 0x1000B},
+ {0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D},
+ {0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA},
+ {0x10100, 0x10102}, {0x10107, 0x10133}, {0x10137, 0x1018E},
+ {0x10190, 0x1019C}, {0x101A0, 0x101A0}, {0x101D0, 0x101FD},
+ {0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x102E0, 0x102FB},
+ {0x10300, 0x10323}, {0x1032D, 0x1034A}, {0x10350, 0x1037A},
+ {0x10380, 0x1039D}, {0x1039F, 0x103C3}, {0x103C8, 0x103D5},
+ {0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3},
+ {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563},
+ {0x1056F, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592},
+ {0x10594, 0x10595}, {0x10597, 0x105A1}, {0x105A3, 0x105B1},
+ {0x105B3, 0x105B9}, {0x105BB, 0x105BC}, {0x10600, 0x10736},
+ {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10780, 0x10785},
+ {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10800, 0x10805},
+ {0x10808, 0x10808}, {0x1080A, 0x10835}, {0x10837, 0x10838},
+ {0x1083C, 0x1083C}, {0x1083F, 0x10855}, {0x10857, 0x1089E},
+ {0x108A7, 0x108AF}, {0x108E0, 0x108F2}, {0x108F4, 0x108F5},
+ {0x108FB, 0x1091B}, {0x1091F, 0x10939}, {0x1093F, 0x1093F},
+ {0x10980, 0x109B7}, {0x109BC, 0x109CF}, {0x109D2, 0x10A03},
+ {0x10A05, 0x10A06}, {0x10A0C, 0x10A13}, {0x10A15, 0x10A17},
+ {0x10A19, 0x10A35}, {0x10A38, 0x10A3A}, {0x10A3F, 0x10A48},
+ {0x10A50, 0x10A58}, {0x10A60, 0x10A9F}, {0x10AC0, 0x10AE6},
+ {0x10AEB, 0x10AF6}, {0x10B00, 0x10B35}, {0x10B39, 0x10B55},
+ {0x10B58, 0x10B72}, {0x10B78, 0x10B91}, {0x10B99, 0x10B9C},
+ {0x10BA9, 0x10BAF}, {0x10C00, 0x10C48}, {0x10C80, 0x10CB2},
+ {0x10CC0, 0x10CF2}, {0x10CFA, 0x10D27}, {0x10D30, 0x10D39},
+ {0x10E60, 0x10E7E}, {0x10E80, 0x10EA9}, {0x10EAB, 0x10EAD},
+ {0x10EB0, 0x10EB1}, {0x10EFD, 0x10F27}, {0x10F30, 0x10F59},
+ {0x10F70, 0x10F89}, {0x10FB0, 0x10FCB}, {0x10FE0, 0x10FF6},
+ {0x11000, 0x1104D}, {0x11052, 0x11075}, {0x1107F, 0x110C2},
+ {0x110CD, 0x110CD}, {0x110D0, 0x110E8}, {0x110F0, 0x110F9},
+ {0x11100, 0x11134}, {0x11136, 0x11147}, {0x11150, 0x11176},
+ {0x11180, 0x111DF}, {0x111E1, 0x111F4}, {0x11200, 0x11211},
+ {0x11213, 0x11241}, {0x11280, 0x11286}, {0x11288, 0x11288},
+ {0x1128A, 0x1128D}, {0x1128F, 0x1129D}, {0x1129F, 0x112A9},
+ {0x112B0, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11303},
+ {0x11305, 0x1130C}, {0x1130F, 0x11310}, {0x11313, 0x11328},
+ {0x1132A, 0x11330}, {0x11332, 0x11333}, {0x11335, 0x11339},
+ {0x1133B, 0x11344}, {0x11347, 0x11348}, {0x1134B, 0x1134D},
+ {0x11350, 0x11350}, {0x11357, 0x11357}, {0x1135D, 0x11363},
+ {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11400, 0x1145B},
+ {0x1145D, 0x11461}, {0x11480, 0x114C7}, {0x114D0, 0x114D9},
+ {0x11580, 0x115B5}, {0x115B8, 0x115DD}, {0x11600, 0x11644},
+ {0x11650, 0x11659}, {0x11660, 0x1166C}, {0x11680, 0x116B9},
+ {0x116C0, 0x116C9}, {0x11700, 0x1171A}, {0x1171D, 0x1172B},
+ {0x11730, 0x11746}, {0x11800, 0x1183B}, {0x118A0, 0x118F2},
+ {0x118FF, 0x11906}, {0x11909, 0x11909}, {0x1190C, 0x11913},
+ {0x11915, 0x11916}, {0x11918, 0x11935}, {0x11937, 0x11938},
+ {0x1193B, 0x11946}, {0x11950, 0x11959}, {0x119A0, 0x119A7},
+ {0x119AA, 0x119D7}, {0x119DA, 0x119E4}, {0x11A00, 0x11A47},
+ {0x11A50, 0x11AA2}, {0x11AB0, 0x11AF8}, {0x11B00, 0x11B09},
+ {0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, {0x11C38, 0x11C45},
+ {0x11C50, 0x11C6C}, {0x11C70, 0x11C8F}, {0x11C92, 0x11CA7},
+ {0x11CA9, 0x11CB6}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09},
+ {0x11D0B, 0x11D36}, {0x11D3A, 0x11D3A}, {0x11D3C, 0x11D3D},
+ {0x11D3F, 0x11D47}, {0x11D50, 0x11D59}, {0x11D60, 0x11D65},
+ {0x11D67, 0x11D68}, {0x11D6A, 0x11D8E}, {0x11D90, 0x11D91},
+ {0x11D93, 0x11D98}, {0x11DA0, 0x11DA9}, {0x11EE0, 0x11EF8},
+ {0x11F00, 0x11F10}, {0x11F12, 0x11F3A}, {0x11F3E, 0x11F59},
+ {0x11FB0, 0x11FB0}, {0x11FC0, 0x11FF1}, {0x11FFF, 0x12399},
+ {0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543},
+ {0x12F90, 0x12FF2}, {0x13000, 0x13455}, {0x14400, 0x14646},
+ {0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A60, 0x16A69},
+ {0x16A6E, 0x16ABE}, {0x16AC0, 0x16AC9}, {0x16AD0, 0x16AED},
+ {0x16AF0, 0x16AF5}, {0x16B00, 0x16B45}, {0x16B50, 0x16B59},
+ {0x16B5B, 0x16B61}, {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F},
+ {0x16E40, 0x16E9A}, {0x16F00, 0x16F4A}, {0x16F4F, 0x16F87},
+ {0x16F8F, 0x16F9F}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C},
+ {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BCA3},
+ {0x1CF00, 0x1CF2D}, {0x1CF30, 0x1CF46}, {0x1CF50, 0x1CFC3},
+ {0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D1EA},
+ {0x1D200, 0x1D245}, {0x1D2C0, 0x1D2D3}, {0x1D2E0, 0x1D2F3},
+ {0x1D300, 0x1D356}, {0x1D360, 0x1D378}, {0x1D400, 0x1D454},
+ {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2},
+ {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9},
+ {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505},
+ {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C},
+ {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544},
+ {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5},
+ {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1DA8B}, {0x1DA9B, 0x1DA9F},
+ {0x1DAA1, 0x1DAAF}, {0x1DF00, 0x1DF1E}, {0x1DF25, 0x1DF2A},
+ {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021},
+ {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E030, 0x1E06D},
+ {0x1E08F, 0x1E08F}, {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D},
+ {0x1E140, 0x1E149}, {0x1E14E, 0x1E14F}, {0x1E290, 0x1E2AE},
+ {0x1E2C0, 0x1E2F9}, {0x1E2FF, 0x1E2FF}, {0x1E4D0, 0x1E4F9},
+ {0x1E7E0, 0x1E7E6}, {0x1E7E8, 0x1E7EB}, {0x1E7ED, 0x1E7EE},
+ {0x1E7F0, 0x1E7FE}, {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6},
+ {0x1E900, 0x1E94B}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F},
+ {0x1EC71, 0x1ECB4}, {0x1ED01, 0x1ED3D}, {0x1EE00, 0x1EE03},
+ {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24},
+ {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37},
+ {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42},
+ {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B},
+ {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54},
+ {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B},
+ {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62},
+ {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72},
+ {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E},
+ {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3},
+ {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x1EEF0, 0x1EEF1},
+ {0x1F000, 0x1F003}, {0x1F005, 0x1F02B}, {0x1F030, 0x1F093},
+ {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, {0x1F0C1, 0x1F0CE},
+ {0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10F}, {0x1F12E, 0x1F12F},
+ {0x1F16A, 0x1F16F}, {0x1F1AD, 0x1F1AD}, {0x1F1E6, 0x1F1FF},
+ {0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D},
+ {0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF},
+ {0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F},
+ {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A},
+ {0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594},
+ {0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F},
+ {0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6D3, 0x1F6D4},
+ {0x1F6E0, 0x1F6EA}, {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F776},
+ {0x1F77B, 0x1F7D9}, {0x1F800, 0x1F80B}, {0x1F810, 0x1F847},
+ {0x1F850, 0x1F859}, {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD},
+ {0x1F8B0, 0x1F8B1}, {0x1F900, 0x1F90B}, {0x1F93B, 0x1F93B},
+ {0x1F946, 0x1F946}, {0x1FA00, 0x1FA53}, {0x1FA60, 0x1FA6D},
+ {0x1FB00, 0x1FB92}, {0x1FB94, 0x1FBCA}, {0x1FBF0, 0x1FBF9},
+ {0xE0001, 0xE0001}, {0xE0020, 0xE007F},
+}
+
+var emoji = table{
+ {0x203C, 0x203C}, {0x2049, 0x2049}, {0x2122, 0x2122},
+ {0x2139, 0x2139}, {0x2194, 0x2199}, {0x21A9, 0x21AA},
+ {0x231A, 0x231B}, {0x2328, 0x2328}, {0x2388, 0x2388},
+ {0x23CF, 0x23CF}, {0x23E9, 0x23F3}, {0x23F8, 0x23FA},
+ {0x24C2, 0x24C2}, {0x25AA, 0x25AB}, {0x25B6, 0x25B6},
+ {0x25C0, 0x25C0}, {0x25FB, 0x25FE}, {0x2600, 0x2605},
+ {0x2607, 0x2612}, {0x2614, 0x2685}, {0x2690, 0x2705},
+ {0x2708, 0x2712}, {0x2714, 0x2714}, {0x2716, 0x2716},
+ {0x271D, 0x271D}, {0x2721, 0x2721}, {0x2728, 0x2728},
+ {0x2733, 0x2734}, {0x2744, 0x2744}, {0x2747, 0x2747},
+ {0x274C, 0x274C}, {0x274E, 0x274E}, {0x2753, 0x2755},
+ {0x2757, 0x2757}, {0x2763, 0x2767}, {0x2795, 0x2797},
+ {0x27A1, 0x27A1}, {0x27B0, 0x27B0}, {0x27BF, 0x27BF},
+ {0x2934, 0x2935}, {0x2B05, 0x2B07}, {0x2B1B, 0x2B1C},
+ {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x3030, 0x3030},
+ {0x303D, 0x303D}, {0x3297, 0x3297}, {0x3299, 0x3299},
+ {0x1F000, 0x1F0FF}, {0x1F10D, 0x1F10F}, {0x1F12F, 0x1F12F},
+ {0x1F16C, 0x1F171}, {0x1F17E, 0x1F17F}, {0x1F18E, 0x1F18E},
+ {0x1F191, 0x1F19A}, {0x1F1AD, 0x1F1E5}, {0x1F201, 0x1F20F},
+ {0x1F21A, 0x1F21A}, {0x1F22F, 0x1F22F}, {0x1F232, 0x1F23A},
+ {0x1F23C, 0x1F23F}, {0x1F249, 0x1F3FA}, {0x1F400, 0x1F53D},
+ {0x1F546, 0x1F64F}, {0x1F680, 0x1F6FF}, {0x1F774, 0x1F77F},
+ {0x1F7D5, 0x1F7FF}, {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F},
+ {0x1F85A, 0x1F85F}, {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F8FF},
+ {0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1FAFF},
+ {0x1FC00, 0x1FFFD},
+}
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_windows.go b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go
new file mode 100644
index 0000000..5f987a3
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go
@@ -0,0 +1,28 @@
+//go:build windows && !appengine
+// +build windows,!appengine
+
+package runewidth
+
+import (
+ "syscall"
+)
+
+var (
+ kernel32 = syscall.NewLazyDLL("kernel32")
+ procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP")
+)
+
+// IsEastAsian return true if the current locale is CJK
+func IsEastAsian() bool {
+ r1, _, _ := procGetConsoleOutputCP.Call()
+ if r1 == 0 {
+ return false
+ }
+
+ switch int(r1) {
+ case 932, 51932, 936, 949, 950:
+ return true
+ }
+
+ return false
+}
diff --git a/vendor/github.com/muesli/ansi/.gitignore b/vendor/github.com/muesli/ansi/.gitignore
new file mode 100644
index 0000000..66fd13c
--- /dev/null
+++ b/vendor/github.com/muesli/ansi/.gitignore
@@ -0,0 +1,15 @@
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Dependency directories (remove the comment below to include it)
+# vendor/
diff --git a/vendor/github.com/muesli/ansi/.golangci.yml b/vendor/github.com/muesli/ansi/.golangci.yml
new file mode 100644
index 0000000..cd299e2
--- /dev/null
+++ b/vendor/github.com/muesli/ansi/.golangci.yml
@@ -0,0 +1,27 @@
+run:
+ tests: false
+
+issues:
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ enable:
+ - bodyclose
+ - dupl
+ - exportloopref
+ - goconst
+ - godot
+ - godox
+ - goimports
+ - golint
+ - goprintffuncname
+ - gosec
+ - ifshort
+ - misspell
+ - prealloc
+ - rowserrcheck
+ - sqlclosecheck
+ - unconvert
+ - unparam
+ - whitespace
diff --git a/vendor/github.com/muesli/ansi/LICENSE b/vendor/github.com/muesli/ansi/LICENSE
new file mode 100644
index 0000000..bd9cdc6
--- /dev/null
+++ b/vendor/github.com/muesli/ansi/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Christian Muehlhaeuser
+
+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/vendor/github.com/muesli/ansi/README.md b/vendor/github.com/muesli/ansi/README.md
new file mode 100644
index 0000000..f9d0fe9
--- /dev/null
+++ b/vendor/github.com/muesli/ansi/README.md
@@ -0,0 +1,31 @@
+# ansi
+
+[](https://github.com/muesli/ansi/releases)
+[](https://github.com/muesli/ansi/actions)
+[](https://coveralls.io/github/muesli/ansi?branch=master)
+[](https://goreportcard.com/report/muesli/ansi)
+[](https://pkg.go.dev/github.com/muesli/ansi)
+
+Raw ANSI sequence helpers
+
+## ANSI Writer
+
+```go
+import "github.com/muesli/ansi"
+
+w := ansi.Writer{Forward: os.Stdout}
+w.Write([]byte("\x1b[31mHello, world!\x1b[0m"))
+w.Close()
+```
+
+## Compressor
+
+The ANSI compressor eliminates unnecessary/redundant ANSI sequences.
+
+```go
+import "github.com/muesli/ansi/compressor"
+
+w := compressor.Writer{Forward: os.Stdout}
+w.Write([]byte("\x1b[31mHello, world!\x1b[0m"))
+w.Close()
+```
diff --git a/vendor/github.com/muesli/ansi/ansi.go b/vendor/github.com/muesli/ansi/ansi.go
new file mode 100644
index 0000000..f3d0700
--- /dev/null
+++ b/vendor/github.com/muesli/ansi/ansi.go
@@ -0,0 +1,7 @@
+package ansi
+
+const Marker = '\x1B'
+
+func IsTerminator(c rune) bool {
+ return (c >= 0x40 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a)
+}
diff --git a/vendor/github.com/muesli/ansi/buffer.go b/vendor/github.com/muesli/ansi/buffer.go
new file mode 100644
index 0000000..471bcaf
--- /dev/null
+++ b/vendor/github.com/muesli/ansi/buffer.go
@@ -0,0 +1,40 @@
+package ansi
+
+import (
+ "bytes"
+
+ "github.com/mattn/go-runewidth"
+)
+
+// Buffer is a buffer aware of ANSI escape sequences.
+type Buffer struct {
+ bytes.Buffer
+}
+
+// PrintableRuneWidth returns the cell width of all printable runes in the
+// buffer.
+func (w Buffer) PrintableRuneWidth() int {
+ return PrintableRuneWidth(w.String())
+}
+
+// PrintableRuneWidth returns the cell width of the given string.
+func PrintableRuneWidth(s string) int {
+ var n int
+ var ansi bool
+
+ for _, c := range s {
+ if c == Marker {
+ // ANSI escape sequence
+ ansi = true
+ } else if ansi {
+ if IsTerminator(c) {
+ // ANSI sequence terminated
+ ansi = false
+ }
+ } else {
+ n += runewidth.RuneWidth(c)
+ }
+ }
+
+ return n
+}
diff --git a/vendor/github.com/muesli/ansi/compressor/writer.go b/vendor/github.com/muesli/ansi/compressor/writer.go
new file mode 100644
index 0000000..98c5482
--- /dev/null
+++ b/vendor/github.com/muesli/ansi/compressor/writer.go
@@ -0,0 +1,132 @@
+package compressor
+
+import (
+ "bytes"
+ "io"
+ "unicode/utf8"
+
+ "github.com/muesli/ansi"
+)
+
+type Writer struct {
+ Forward io.Writer
+
+ ansi bool
+ ansiseq bytes.Buffer
+ lastseq bytes.Buffer
+ prevlastseq bytes.Buffer
+ resetreq bool
+ runeBuf []byte
+ compressed int
+ uncompressed int
+}
+
+// Bytes is shorthand for declaring a new default compressor instance,
+// used to immediately compress a byte slice.
+func Bytes(b []byte) []byte {
+ var buf bytes.Buffer
+ f := Writer{
+ Forward: &buf,
+ }
+ _, _ = f.Write(b)
+ _ = f.Close()
+
+ return buf.Bytes()
+}
+
+// String is shorthand for declaring a new default compressor instance,
+// used to immediately compress a string.
+func String(s string) string {
+ return string(Bytes([]byte(s)))
+}
+
+// Write is used to write content to the ANSI buffer.
+func (w *Writer) Write(b []byte) (int, error) {
+ w.uncompressed += len(b)
+
+ for _, c := range string(b) {
+ if c == ansi.Marker {
+ // ANSI escape sequence
+ w.ansi = true
+ _, _ = w.ansiseq.WriteRune(c)
+ } else if w.ansi {
+ _, _ = w.ansiseq.WriteRune(c)
+ if ansi.IsTerminator(c) {
+ // ANSI sequence terminated
+ w.ansi = false
+
+ terminated := false
+ if bytes.HasSuffix(w.ansiseq.Bytes(), []byte("[0m")) {
+ // reset sequence
+ w.prevlastseq.Reset()
+ w.prevlastseq.Write(w.lastseq.Bytes())
+
+ w.lastseq.Reset()
+ terminated = true
+ w.resetreq = true
+ } else if c == 'm' {
+ // color code
+ _, _ = w.lastseq.Write(w.ansiseq.Bytes())
+ }
+
+ if !terminated {
+ // did we reset the sequence just to restore it again?
+ if bytes.Equal(w.ansiseq.Bytes(), w.prevlastseq.Bytes()) {
+ w.resetreq = false
+ w.ansiseq.Reset()
+ }
+
+ w.prevlastseq.Reset()
+
+ if w.resetreq {
+ w.ResetAnsi()
+ }
+
+ _, _ = w.Forward.Write(w.ansiseq.Bytes())
+ w.compressed += w.ansiseq.Len()
+ }
+
+ w.ansiseq.Reset()
+ }
+ } else {
+ if w.resetreq {
+ w.ResetAnsi()
+ }
+
+ _, err := w.writeRune(c)
+ if err != nil {
+ return 0, err
+ }
+ }
+ }
+
+ return len(b), nil
+}
+
+func (w *Writer) writeRune(r rune) (int, error) {
+ if w.runeBuf == nil {
+ w.runeBuf = make([]byte, utf8.UTFMax)
+ }
+ n := utf8.EncodeRune(w.runeBuf, r)
+ w.compressed += n
+ return w.Forward.Write(w.runeBuf[:n])
+}
+
+// Close finishes the compression operation. Always call it before trying to
+// retrieve the final result.
+func (w *Writer) Close() error {
+ if w.resetreq {
+ w.ResetAnsi()
+ }
+
+ // log.Println("Written uncompressed: ", w.uncompressed)
+ // log.Println("Written compressed: ", w.compressed)
+
+ return nil
+}
+
+func (w *Writer) ResetAnsi() {
+ w.prevlastseq.Reset()
+ _, _ = w.Forward.Write([]byte("\x1b[0m"))
+ w.resetreq = false
+}
diff --git a/vendor/github.com/muesli/ansi/writer.go b/vendor/github.com/muesli/ansi/writer.go
new file mode 100644
index 0000000..a6aaa1e
--- /dev/null
+++ b/vendor/github.com/muesli/ansi/writer.go
@@ -0,0 +1,76 @@
+package ansi
+
+import (
+ "bytes"
+ "io"
+ "unicode/utf8"
+)
+
+type Writer struct {
+ Forward io.Writer
+
+ ansi bool
+ ansiseq bytes.Buffer
+ lastseq bytes.Buffer
+ seqchanged bool
+ runeBuf []byte
+}
+
+// Write is used to write content to the ANSI buffer.
+func (w *Writer) Write(b []byte) (int, error) {
+ for _, c := range string(b) {
+ if c == Marker {
+ // ANSI escape sequence
+ w.ansi = true
+ w.seqchanged = true
+ _, _ = w.ansiseq.WriteRune(c)
+ } else if w.ansi {
+ _, _ = w.ansiseq.WriteRune(c)
+ if IsTerminator(c) {
+ // ANSI sequence terminated
+ w.ansi = false
+
+ if bytes.HasSuffix(w.ansiseq.Bytes(), []byte("[0m")) {
+ // reset sequence
+ w.lastseq.Reset()
+ w.seqchanged = false
+ } else if c == 'm' {
+ // color code
+ _, _ = w.lastseq.Write(w.ansiseq.Bytes())
+ }
+
+ _, _ = w.ansiseq.WriteTo(w.Forward)
+ }
+ } else {
+ _, err := w.writeRune(c)
+ if err != nil {
+ return 0, err
+ }
+ }
+ }
+
+ return len(b), nil
+}
+
+func (w *Writer) writeRune(r rune) (int, error) {
+ if w.runeBuf == nil {
+ w.runeBuf = make([]byte, utf8.UTFMax)
+ }
+ n := utf8.EncodeRune(w.runeBuf, r)
+ return w.Forward.Write(w.runeBuf[:n])
+}
+
+func (w *Writer) LastSequence() string {
+ return w.lastseq.String()
+}
+
+func (w *Writer) ResetAnsi() {
+ if !w.seqchanged {
+ return
+ }
+ _, _ = w.Forward.Write([]byte("\x1b[0m"))
+}
+
+func (w *Writer) RestoreAnsi() {
+ _, _ = w.Forward.Write(w.lastseq.Bytes())
+}
diff --git a/vendor/github.com/muesli/cancelreader/.gitignore b/vendor/github.com/muesli/cancelreader/.gitignore
new file mode 100644
index 0000000..66fd13c
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/.gitignore
@@ -0,0 +1,15 @@
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Dependency directories (remove the comment below to include it)
+# vendor/
diff --git a/vendor/github.com/muesli/cancelreader/.golangci-soft.yml b/vendor/github.com/muesli/cancelreader/.golangci-soft.yml
new file mode 100644
index 0000000..ef456e0
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/.golangci-soft.yml
@@ -0,0 +1,47 @@
+run:
+ tests: false
+
+issues:
+ include:
+ - EXC0001
+ - EXC0005
+ - EXC0011
+ - EXC0012
+ - EXC0013
+
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ enable:
+ # - dupl
+ - exhaustive
+ # - exhaustivestruct
+ - goconst
+ - godot
+ - godox
+ - gomnd
+ - gomoddirectives
+ - goprintffuncname
+ - ifshort
+ # - lll
+ - misspell
+ - nakedret
+ - nestif
+ - noctx
+ - nolintlint
+ - prealloc
+ - wrapcheck
+
+ # disable default linters, they are already enabled in .golangci.yml
+ disable:
+ - deadcode
+ - errcheck
+ - gosimple
+ - govet
+ - ineffassign
+ - staticcheck
+ - structcheck
+ - typecheck
+ - unused
+ - varcheck
diff --git a/vendor/github.com/muesli/cancelreader/.golangci.yml b/vendor/github.com/muesli/cancelreader/.golangci.yml
new file mode 100644
index 0000000..a5a91d0
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/.golangci.yml
@@ -0,0 +1,29 @@
+run:
+ tests: false
+
+issues:
+ include:
+ - EXC0001
+ - EXC0005
+ - EXC0011
+ - EXC0012
+ - EXC0013
+
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ enable:
+ - bodyclose
+ - exportloopref
+ - goimports
+ - gosec
+ - nilerr
+ - predeclared
+ - revive
+ - rowserrcheck
+ - sqlclosecheck
+ - tparallel
+ - unconvert
+ - unparam
+ - whitespace
diff --git a/vendor/github.com/muesli/cancelreader/LICENSE b/vendor/github.com/muesli/cancelreader/LICENSE
new file mode 100644
index 0000000..4b19b92
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 Erik Geiser and Christian Muehlhaeuser
+
+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/vendor/github.com/muesli/cancelreader/README.md b/vendor/github.com/muesli/cancelreader/README.md
new file mode 100644
index 0000000..83609fb
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/README.md
@@ -0,0 +1,64 @@
+# CancelReader
+
+[](https://github.com/muesli/cancelreader/releases)
+[](https://pkg.go.dev/github.com/muesli/cancelreader)
+[](/LICENSE)
+[](https://github.com/muesli/cancelreader/actions)
+[](https://goreportcard.com/report/muesli/cancelreader)
+
+A cancelable reader for Go
+
+This package is based on the fantastic work of [Erik Geiser](https://github.com/erikgeiser)
+in Charm's [Bubble Tea](https://github.com/charmbracelet/bubbletea) framework.
+
+## Usage
+
+`NewReader` returns a reader with a `Cancel` function. If the input reader is a
+`File`, the cancel function can be used to interrupt a blocking `Read` call.
+In this case, the cancel function returns true if the call was canceled
+successfully. If the input reader is not a `File`, the cancel function does
+nothing and always returns false.
+
+```go
+r, err := cancelreader.NewReader(file)
+if err != nil {
+ // handle error
+ ...
+}
+
+// cancel after five seconds
+go func() {
+ time.Sleep(5 * time.Second)
+ r.Cancel()
+}()
+
+// keep reading
+for {
+ var buf [1024]byte
+ _, err := r.Read(buf[:])
+
+ if errors.Is(err, cancelreader.ErrCanceled) {
+ fmt.Println("canceled!")
+ break
+ }
+ if err != nil {
+ // handle other errors
+ ...
+ }
+
+ // handle data
+ ...
+}
+```
+
+## Implementations
+
+- The Linux implementation is based on the epoll mechanism
+- The BSD and macOS implementation is based on the kqueue mechanism
+- The generic Unix implementation is based on the posix select syscall
+
+## Caution
+
+The Windows implementation is based on WaitForMultipleObject with overlapping
+reads from CONIN$. At this point it only supports canceling reads from
+`os.Stdin`.
diff --git a/vendor/github.com/muesli/cancelreader/cancelreader.go b/vendor/github.com/muesli/cancelreader/cancelreader.go
new file mode 100644
index 0000000..18d3825
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/cancelreader.go
@@ -0,0 +1,93 @@
+package cancelreader
+
+import (
+ "fmt"
+ "io"
+ "sync"
+)
+
+// ErrCanceled gets returned when trying to read from a canceled reader.
+var ErrCanceled = fmt.Errorf("read canceled")
+
+// CancelReader is a io.Reader whose Read() calls can be canceled without data
+// being consumed. The cancelReader has to be closed.
+type CancelReader interface {
+ io.ReadCloser
+
+ // Cancel cancels ongoing and future reads an returns true if it succeeded.
+ Cancel() bool
+}
+
+// File represents an input/output resource with a file descriptor.
+type File interface {
+ io.ReadWriteCloser
+
+ // Fd returns its file descriptor
+ Fd() uintptr
+
+ // Name returns its file name.
+ Name() string
+}
+
+// fallbackCancelReader implements cancelReader but does not actually support
+// cancelation during an ongoing Read() call. Thus, Cancel() always returns
+// false. However, after calling Cancel(), new Read() calls immediately return
+// errCanceled and don't consume any data anymore.
+type fallbackCancelReader struct {
+ r io.Reader
+ cancelMixin
+}
+
+// newFallbackCancelReader is a fallback for NewReader that cannot actually
+// cancel an ongoing read but will immediately return on future reads if it has
+// been canceled.
+func newFallbackCancelReader(reader io.Reader) (CancelReader, error) {
+ return &fallbackCancelReader{r: reader}, nil
+}
+
+func (r *fallbackCancelReader) Read(data []byte) (int, error) {
+ if r.isCanceled() {
+ return 0, ErrCanceled
+ }
+
+ n, err := r.r.Read(data)
+ /*
+ If the underlying reader is a blocking reader (e.g. an open connection),
+ it might happen that 1 goroutine cancels the reader while its stuck in
+ the read call waiting for something.
+ If that happens, we should still cancel the read.
+ */
+ if r.isCanceled() {
+ return 0, ErrCanceled
+ }
+ return n, err // nolint: wrapcheck
+}
+
+func (r *fallbackCancelReader) Cancel() bool {
+ r.setCanceled()
+ return false
+}
+
+func (r *fallbackCancelReader) Close() error {
+ return nil
+}
+
+// cancelMixin represents a goroutine-safe cancelation status.
+type cancelMixin struct {
+ unsafeCanceled bool
+ lock sync.Mutex
+}
+
+func (c *cancelMixin) isCanceled() bool {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ return c.unsafeCanceled
+}
+
+func (c *cancelMixin) setCanceled() {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ c.unsafeCanceled = true
+}
diff --git a/vendor/github.com/muesli/cancelreader/cancelreader_bsd.go b/vendor/github.com/muesli/cancelreader/cancelreader_bsd.go
new file mode 100644
index 0000000..3ddb6cf
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/cancelreader_bsd.go
@@ -0,0 +1,146 @@
+//go:build darwin || freebsd || netbsd || openbsd || dragonfly
+// +build darwin freebsd netbsd openbsd dragonfly
+
+package cancelreader
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "strings"
+
+ "golang.org/x/sys/unix"
+)
+
+// NewReader returns a reader and a cancel function. If the input reader is a
+// File, the cancel function can be used to interrupt a blocking read call.
+// In this case, the cancel function returns true if the call was canceled
+// successfully. If the input reader is not a File, the cancel function
+// does nothing and always returns false. The BSD and macOS implementation is
+// based on the kqueue mechanism.
+func NewReader(reader io.Reader) (CancelReader, error) {
+ file, ok := reader.(File)
+ if !ok {
+ return newFallbackCancelReader(reader)
+ }
+
+ // kqueue returns instantly when polling /dev/tty so fallback to select
+ if file.Name() == "/dev/tty" {
+ return newSelectCancelReader(reader)
+ }
+
+ kQueue, err := unix.Kqueue()
+ if err != nil {
+ return nil, fmt.Errorf("create kqueue: %w", err)
+ }
+
+ r := &kqueueCancelReader{
+ file: file,
+ kQueue: kQueue,
+ }
+
+ r.cancelSignalReader, r.cancelSignalWriter, err = os.Pipe()
+ if err != nil {
+ _ = unix.Close(kQueue)
+ return nil, err
+ }
+
+ unix.SetKevent(&r.kQueueEvents[0], int(file.Fd()), unix.EVFILT_READ, unix.EV_ADD)
+ unix.SetKevent(&r.kQueueEvents[1], int(r.cancelSignalReader.Fd()), unix.EVFILT_READ, unix.EV_ADD)
+
+ return r, nil
+}
+
+type kqueueCancelReader struct {
+ file File
+ cancelSignalReader File
+ cancelSignalWriter File
+ cancelMixin
+ kQueue int
+ kQueueEvents [2]unix.Kevent_t
+}
+
+func (r *kqueueCancelReader) Read(data []byte) (int, error) {
+ if r.isCanceled() {
+ return 0, ErrCanceled
+ }
+
+ err := r.wait()
+ if err != nil {
+ if errors.Is(err, ErrCanceled) {
+ // remove signal from pipe
+ var b [1]byte
+ _, errRead := r.cancelSignalReader.Read(b[:])
+ if errRead != nil {
+ return 0, fmt.Errorf("reading cancel signal: %w", errRead)
+ }
+ }
+
+ return 0, err
+ }
+
+ return r.file.Read(data)
+}
+
+func (r *kqueueCancelReader) Cancel() bool {
+ r.setCanceled()
+
+ // send cancel signal
+ _, err := r.cancelSignalWriter.Write([]byte{'c'})
+ return err == nil
+}
+
+func (r *kqueueCancelReader) Close() error {
+ var errMsgs []string
+
+ // close kqueue
+ err := unix.Close(r.kQueue)
+ if err != nil {
+ errMsgs = append(errMsgs, fmt.Sprintf("closing kqueue: %v", err))
+ }
+
+ // close pipe
+ err = r.cancelSignalWriter.Close()
+ if err != nil {
+ errMsgs = append(errMsgs, fmt.Sprintf("closing cancel signal writer: %v", err))
+ }
+
+ err = r.cancelSignalReader.Close()
+ if err != nil {
+ errMsgs = append(errMsgs, fmt.Sprintf("closing cancel signal reader: %v", err))
+ }
+
+ if len(errMsgs) > 0 {
+ return fmt.Errorf(strings.Join(errMsgs, ", "))
+ }
+
+ return nil
+}
+
+func (r *kqueueCancelReader) wait() error {
+ events := make([]unix.Kevent_t, 1)
+
+ for {
+ _, err := unix.Kevent(r.kQueue, r.kQueueEvents[:], events, nil)
+ if errors.Is(err, unix.EINTR) {
+ continue // try again if the syscall was interrupted
+ }
+
+ if err != nil {
+ return fmt.Errorf("kevent: %w", err)
+ }
+
+ break
+ }
+
+ ident := uint64(events[0].Ident)
+ switch ident {
+ case uint64(r.file.Fd()):
+ return nil
+ case uint64(r.cancelSignalReader.Fd()):
+ return ErrCanceled
+ }
+
+ return fmt.Errorf("unknown error")
+}
diff --git a/vendor/github.com/muesli/cancelreader/cancelreader_default.go b/vendor/github.com/muesli/cancelreader/cancelreader_default.go
new file mode 100644
index 0000000..8e275fa
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/cancelreader_default.go
@@ -0,0 +1,12 @@
+//go:build !darwin && !windows && !linux && !solaris && !freebsd && !netbsd && !openbsd && !dragonfly
+// +build !darwin,!windows,!linux,!solaris,!freebsd,!netbsd,!openbsd,!dragonfly
+
+package cancelreader
+
+import "io"
+
+// NewReader returns a fallbackCancelReader that satisfies the CancelReader but
+// does not actually support cancellation.
+func NewReader(reader io.Reader) (CancelReader, error) {
+ return newFallbackCancelReader(reader)
+}
diff --git a/vendor/github.com/muesli/cancelreader/cancelreader_linux.go b/vendor/github.com/muesli/cancelreader/cancelreader_linux.go
new file mode 100644
index 0000000..09f7369
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/cancelreader_linux.go
@@ -0,0 +1,154 @@
+//go:build linux
+// +build linux
+
+package cancelreader
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "strings"
+
+ "golang.org/x/sys/unix"
+)
+
+// NewReader returns a reader and a cancel function. If the input reader is a
+// File, the cancel function can be used to interrupt a blocking read call.
+// In this case, the cancel function returns true if the call was canceled
+// successfully. If the input reader is not a File, the cancel function
+// does nothing and always returns false. The Linux implementation is based on
+// the epoll mechanism.
+func NewReader(reader io.Reader) (CancelReader, error) {
+ file, ok := reader.(File)
+ if !ok {
+ return newFallbackCancelReader(reader)
+ }
+
+ epoll, err := unix.EpollCreate1(0)
+ if err != nil {
+ return nil, fmt.Errorf("create epoll: %w", err)
+ }
+
+ r := &epollCancelReader{
+ file: file,
+ epoll: epoll,
+ }
+
+ r.cancelSignalReader, r.cancelSignalWriter, err = os.Pipe()
+ if err != nil {
+ _ = unix.Close(epoll)
+ return nil, err
+ }
+
+ err = unix.EpollCtl(epoll, unix.EPOLL_CTL_ADD, int(file.Fd()), &unix.EpollEvent{
+ Events: unix.EPOLLIN,
+ Fd: int32(file.Fd()),
+ })
+ if err != nil {
+ _ = unix.Close(epoll)
+ return nil, fmt.Errorf("add reader to epoll interest list")
+ }
+
+ err = unix.EpollCtl(epoll, unix.EPOLL_CTL_ADD, int(r.cancelSignalReader.Fd()), &unix.EpollEvent{
+ Events: unix.EPOLLIN,
+ Fd: int32(r.cancelSignalReader.Fd()),
+ })
+ if err != nil {
+ _ = unix.Close(epoll)
+ return nil, fmt.Errorf("add reader to epoll interest list")
+ }
+
+ return r, nil
+}
+
+type epollCancelReader struct {
+ file File
+ cancelSignalReader File
+ cancelSignalWriter File
+ cancelMixin
+ epoll int
+}
+
+func (r *epollCancelReader) Read(data []byte) (int, error) {
+ if r.isCanceled() {
+ return 0, ErrCanceled
+ }
+
+ err := r.wait()
+ if err != nil {
+ if errors.Is(err, ErrCanceled) {
+ // remove signal from pipe
+ var b [1]byte
+ _, readErr := r.cancelSignalReader.Read(b[:])
+ if readErr != nil {
+ return 0, fmt.Errorf("reading cancel signal: %w", readErr)
+ }
+ }
+
+ return 0, err
+ }
+
+ return r.file.Read(data)
+}
+
+func (r *epollCancelReader) Cancel() bool {
+ r.setCanceled()
+
+ // send cancel signal
+ _, err := r.cancelSignalWriter.Write([]byte{'c'})
+ return err == nil
+}
+
+func (r *epollCancelReader) Close() error {
+ var errMsgs []string
+
+ // close kqueue
+ err := unix.Close(r.epoll)
+ if err != nil {
+ errMsgs = append(errMsgs, fmt.Sprintf("closing epoll: %v", err))
+ }
+
+ // close pipe
+ err = r.cancelSignalWriter.Close()
+ if err != nil {
+ errMsgs = append(errMsgs, fmt.Sprintf("closing cancel signal writer: %v", err))
+ }
+
+ err = r.cancelSignalReader.Close()
+ if err != nil {
+ errMsgs = append(errMsgs, fmt.Sprintf("closing cancel signal reader: %v", err))
+ }
+
+ if len(errMsgs) > 0 {
+ return fmt.Errorf(strings.Join(errMsgs, ", "))
+ }
+
+ return nil
+}
+
+func (r *epollCancelReader) wait() error {
+ events := make([]unix.EpollEvent, 1)
+
+ for {
+ _, err := unix.EpollWait(r.epoll, events, -1)
+ if errors.Is(err, unix.EINTR) {
+ continue // try again if the syscall was interrupted
+ }
+
+ if err != nil {
+ return fmt.Errorf("kevent: %w", err)
+ }
+
+ break
+ }
+
+ switch events[0].Fd {
+ case int32(r.file.Fd()):
+ return nil
+ case int32(r.cancelSignalReader.Fd()):
+ return ErrCanceled
+ }
+
+ return fmt.Errorf("unknown error")
+}
diff --git a/vendor/github.com/muesli/cancelreader/cancelreader_select.go b/vendor/github.com/muesli/cancelreader/cancelreader_select.go
new file mode 100644
index 0000000..03f2a3e
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/cancelreader_select.go
@@ -0,0 +1,136 @@
+//go:build solaris || darwin || freebsd || netbsd || openbsd || dragonfly
+// +build solaris darwin freebsd netbsd openbsd dragonfly
+
+package cancelreader
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "strings"
+
+ "golang.org/x/sys/unix"
+)
+
+// newSelectCancelReader returns a reader and a cancel function. If the input
+// reader is a File, the cancel function can be used to interrupt a
+// blocking call read call. In this case, the cancel function returns true if
+// the call was canceled successfully. If the input reader is not a File or
+// the file descriptor is 1024 or larger, the cancel function does nothing and
+// always returns false. The generic unix implementation is based on the posix
+// select syscall.
+func newSelectCancelReader(reader io.Reader) (CancelReader, error) {
+ file, ok := reader.(File)
+ if !ok || file.Fd() >= unix.FD_SETSIZE {
+ return newFallbackCancelReader(reader)
+ }
+ r := &selectCancelReader{file: file}
+
+ var err error
+
+ r.cancelSignalReader, r.cancelSignalWriter, err = os.Pipe()
+ if err != nil {
+ return nil, err
+ }
+
+ return r, nil
+}
+
+type selectCancelReader struct {
+ file File
+ cancelSignalReader File
+ cancelSignalWriter File
+ cancelMixin
+}
+
+func (r *selectCancelReader) Read(data []byte) (int, error) {
+ if r.isCanceled() {
+ return 0, ErrCanceled
+ }
+
+ for {
+ err := waitForRead(r.file, r.cancelSignalReader)
+ if err != nil {
+ if errors.Is(err, unix.EINTR) {
+ continue // try again if the syscall was interrupted
+ }
+
+ if errors.Is(err, ErrCanceled) {
+ // remove signal from pipe
+ var b [1]byte
+ _, readErr := r.cancelSignalReader.Read(b[:])
+ if readErr != nil {
+ return 0, fmt.Errorf("reading cancel signal: %w", readErr)
+ }
+ }
+
+ return 0, err
+ }
+
+ return r.file.Read(data)
+ }
+}
+
+func (r *selectCancelReader) Cancel() bool {
+ r.setCanceled()
+
+ // send cancel signal
+ _, err := r.cancelSignalWriter.Write([]byte{'c'})
+ return err == nil
+}
+
+func (r *selectCancelReader) Close() error {
+ var errMsgs []string
+
+ // close pipe
+ err := r.cancelSignalWriter.Close()
+ if err != nil {
+ errMsgs = append(errMsgs, fmt.Sprintf("closing cancel signal writer: %v", err))
+ }
+
+ err = r.cancelSignalReader.Close()
+ if err != nil {
+ errMsgs = append(errMsgs, fmt.Sprintf("closing cancel signal reader: %v", err))
+ }
+
+ if len(errMsgs) > 0 {
+ return fmt.Errorf(strings.Join(errMsgs, ", "))
+ }
+
+ return nil
+}
+
+func waitForRead(reader, abort File) error {
+ readerFd := int(reader.Fd())
+ abortFd := int(abort.Fd())
+
+ maxFd := readerFd
+ if abortFd > maxFd {
+ maxFd = abortFd
+ }
+
+ // this is a limitation of the select syscall
+ if maxFd >= unix.FD_SETSIZE {
+ return fmt.Errorf("cannot select on file descriptor %d which is larger than 1024", maxFd)
+ }
+
+ fdSet := &unix.FdSet{}
+ fdSet.Set(int(reader.Fd()))
+ fdSet.Set(int(abort.Fd()))
+
+ _, err := unix.Select(maxFd+1, fdSet, nil, nil, nil)
+ if err != nil {
+ return fmt.Errorf("select: %w", err)
+ }
+
+ if fdSet.IsSet(abortFd) {
+ return ErrCanceled
+ }
+
+ if fdSet.IsSet(readerFd) {
+ return nil
+ }
+
+ return fmt.Errorf("select returned without setting a file descriptor")
+}
diff --git a/vendor/github.com/muesli/cancelreader/cancelreader_unix.go b/vendor/github.com/muesli/cancelreader/cancelreader_unix.go
new file mode 100644
index 0000000..3c10ee0
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/cancelreader_unix.go
@@ -0,0 +1,18 @@
+//go:build solaris
+// +build solaris
+
+package cancelreader
+
+import (
+ "io"
+)
+
+// NewReader returns a reader and a cancel function. If the input reader is a
+// File, the cancel function can be used to interrupt a blocking read call.
+// In this case, the cancel function returns true if the call was canceled
+// successfully. If the input reader is not a File or the file descriptor
+// is 1024 or larger, the cancel function does nothing and always returns false.
+// The generic unix implementation is based on the posix select syscall.
+func NewReader(reader io.Reader) (CancelReader, error) {
+ return newSelectCancelReader(reader)
+}
diff --git a/vendor/github.com/muesli/cancelreader/cancelreader_windows.go b/vendor/github.com/muesli/cancelreader/cancelreader_windows.go
new file mode 100644
index 0000000..c1dc8d5
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/cancelreader_windows.go
@@ -0,0 +1,244 @@
+//go:build windows
+// +build windows
+
+package cancelreader
+
+import (
+ "fmt"
+ "io"
+ "os"
+ "syscall"
+ "time"
+ "unicode/utf16"
+
+ "golang.org/x/sys/windows"
+)
+
+var fileShareValidFlags uint32 = 0x00000007
+
+// NewReader returns a reader and a cancel function. If the input reader is a
+// File with the same file descriptor as os.Stdin, the cancel function can
+// be used to interrupt a blocking read call. In this case, the cancel function
+// returns true if the call was canceled successfully. If the input reader is
+// not a File with the same file descriptor as os.Stdin, the cancel
+// function does nothing and always returns false. The Windows implementation
+// is based on WaitForMultipleObject with overlapping reads from CONIN$.
+func NewReader(reader io.Reader) (CancelReader, error) {
+ if f, ok := reader.(File); !ok || f.Fd() != os.Stdin.Fd() {
+ return newFallbackCancelReader(reader)
+ }
+
+ // it is necessary to open CONIN$ (NOT windows.STD_INPUT_HANDLE) in
+ // overlapped mode to be able to use it with WaitForMultipleObjects.
+ conin, err := windows.CreateFile(
+ &(utf16.Encode([]rune("CONIN$\x00"))[0]), windows.GENERIC_READ|windows.GENERIC_WRITE,
+ fileShareValidFlags, nil, windows.OPEN_EXISTING, windows.FILE_FLAG_OVERLAPPED, 0)
+ if err != nil {
+ return nil, fmt.Errorf("open CONIN$ in overlapping mode: %w", err)
+ }
+
+ resetConsole, err := prepareConsole(conin)
+ if err != nil {
+ return nil, fmt.Errorf("prepare console: %w", err)
+ }
+
+ // flush input, otherwise it can contain events which trigger
+ // WaitForMultipleObjects but which ReadFile cannot read, resulting in an
+ // un-cancelable read
+ err = flushConsoleInputBuffer(conin)
+ if err != nil {
+ return nil, fmt.Errorf("flush console input buffer: %w", err)
+ }
+
+ cancelEvent, err := windows.CreateEvent(nil, 0, 0, nil)
+ if err != nil {
+ return nil, fmt.Errorf("create stop event: %w", err)
+ }
+
+ return &winCancelReader{
+ conin: conin,
+ cancelEvent: cancelEvent,
+ resetConsole: resetConsole,
+ blockingReadSignal: make(chan struct{}, 1),
+ }, nil
+}
+
+type winCancelReader struct {
+ conin windows.Handle
+ cancelEvent windows.Handle
+ cancelMixin
+
+ resetConsole func() error
+ blockingReadSignal chan struct{}
+}
+
+func (r *winCancelReader) Read(data []byte) (int, error) {
+ if r.isCanceled() {
+ return 0, ErrCanceled
+ }
+
+ err := r.wait()
+ if err != nil {
+ return 0, err
+ }
+
+ if r.isCanceled() {
+ return 0, ErrCanceled
+ }
+
+ // windows.Read does not work on overlapping windows.Handles
+ return r.readAsync(data)
+}
+
+// Cancel cancels ongoing and future Read() calls and returns true if the
+// cancelation of the ongoing Read() was successful. On Windows Terminal,
+// WaitForMultipleObjects sometimes immediately returns without input being
+// available. In this case, graceful cancelation is not possible and Cancel()
+// returns false.
+func (r *winCancelReader) Cancel() bool {
+ r.setCanceled()
+
+ select {
+ case r.blockingReadSignal <- struct{}{}:
+ err := windows.SetEvent(r.cancelEvent)
+ if err != nil {
+ return false
+ }
+ <-r.blockingReadSignal
+ case <-time.After(100 * time.Millisecond):
+ // Read() hangs in a GetOverlappedResult which is likely due to
+ // WaitForMultipleObjects returning without input being available
+ // so we cannot cancel this ongoing read.
+ return false
+ }
+
+ return true
+}
+
+func (r *winCancelReader) Close() error {
+ err := windows.CloseHandle(r.cancelEvent)
+ if err != nil {
+ return fmt.Errorf("closing cancel event handle: %w", err)
+ }
+
+ err = r.resetConsole()
+ if err != nil {
+ return err
+ }
+
+ err = windows.Close(r.conin)
+ if err != nil {
+ return fmt.Errorf("closing CONIN$")
+ }
+
+ return nil
+}
+
+func (r *winCancelReader) wait() error {
+ event, err := windows.WaitForMultipleObjects([]windows.Handle{r.conin, r.cancelEvent}, false, windows.INFINITE)
+ switch {
+ case windows.WAIT_OBJECT_0 <= event && event < windows.WAIT_OBJECT_0+2:
+ if event == windows.WAIT_OBJECT_0+1 {
+ return ErrCanceled
+ }
+
+ if event == windows.WAIT_OBJECT_0 {
+ return nil
+ }
+
+ return fmt.Errorf("unexpected wait object is ready: %d", event-windows.WAIT_OBJECT_0)
+ case windows.WAIT_ABANDONED <= event && event < windows.WAIT_ABANDONED+2:
+ return fmt.Errorf("abandoned")
+ case event == uint32(windows.WAIT_TIMEOUT):
+ return fmt.Errorf("timeout")
+ case event == windows.WAIT_FAILED:
+ return fmt.Errorf("failed")
+ default:
+ return fmt.Errorf("unexpected error: %w", error(err))
+ }
+}
+
+// readAsync is necessary to read from a windows.Handle in overlapping mode.
+func (r *winCancelReader) readAsync(data []byte) (int, error) {
+ hevent, err := windows.CreateEvent(nil, 0, 0, nil)
+ if err != nil {
+ return 0, fmt.Errorf("create event: %w", err)
+ }
+
+ overlapped := windows.Overlapped{
+ HEvent: hevent,
+ }
+
+ var n uint32
+
+ err = windows.ReadFile(r.conin, data, &n, &overlapped)
+ if err != nil && err != windows.ERROR_IO_PENDING {
+ return int(n), err
+ }
+
+ r.blockingReadSignal <- struct{}{}
+ err = windows.GetOverlappedResult(r.conin, &overlapped, &n, true)
+ if err != nil {
+ return int(n), nil
+ }
+ <-r.blockingReadSignal
+
+ return int(n), nil
+}
+
+func prepareConsole(input windows.Handle) (reset func() error, err error) {
+ var originalMode uint32
+
+ err = windows.GetConsoleMode(input, &originalMode)
+ if err != nil {
+ return nil, fmt.Errorf("get console mode: %w", err)
+ }
+
+ var newMode uint32
+ newMode &^= windows.ENABLE_ECHO_INPUT
+ newMode &^= windows.ENABLE_LINE_INPUT
+ newMode &^= windows.ENABLE_MOUSE_INPUT
+ newMode &^= windows.ENABLE_WINDOW_INPUT
+ newMode &^= windows.ENABLE_PROCESSED_INPUT
+
+ newMode |= windows.ENABLE_EXTENDED_FLAGS
+ newMode |= windows.ENABLE_INSERT_MODE
+ newMode |= windows.ENABLE_QUICK_EDIT_MODE
+
+ // Enabling virtual terminal input is necessary for processing certain
+ // types of input like X10 mouse events and arrows keys with the current
+ // bytes-based input reader. It does, however, prevent cancelReader from
+ // being able to cancel input. The planned solution for this is to read
+ // Windows events in a more native fashion, rather than the current simple
+ // bytes-based input reader which works well on unix systems.
+ newMode |= windows.ENABLE_VIRTUAL_TERMINAL_INPUT
+
+ err = windows.SetConsoleMode(input, newMode)
+ if err != nil {
+ return nil, fmt.Errorf("set console mode: %w", err)
+ }
+
+ return func() error {
+ err := windows.SetConsoleMode(input, originalMode)
+ if err != nil {
+ return fmt.Errorf("reset console mode: %w", err)
+ }
+
+ return nil
+ }, nil
+}
+
+var (
+ modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
+ procFlushConsoleInputBuffer = modkernel32.NewProc("FlushConsoleInputBuffer")
+)
+
+func flushConsoleInputBuffer(consoleInput windows.Handle) error {
+ r, _, e := syscall.Syscall(procFlushConsoleInputBuffer.Addr(), 1,
+ uintptr(consoleInput), 0, 0)
+ if r == 0 {
+ return error(e)
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/muesli/termenv/.gitignore b/vendor/github.com/muesli/termenv/.gitignore
new file mode 100644
index 0000000..66fd13c
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/.gitignore
@@ -0,0 +1,15 @@
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Dependency directories (remove the comment below to include it)
+# vendor/
diff --git a/vendor/github.com/muesli/termenv/.golangci-soft.yml b/vendor/github.com/muesli/termenv/.golangci-soft.yml
new file mode 100644
index 0000000..ef456e0
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/.golangci-soft.yml
@@ -0,0 +1,47 @@
+run:
+ tests: false
+
+issues:
+ include:
+ - EXC0001
+ - EXC0005
+ - EXC0011
+ - EXC0012
+ - EXC0013
+
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ enable:
+ # - dupl
+ - exhaustive
+ # - exhaustivestruct
+ - goconst
+ - godot
+ - godox
+ - gomnd
+ - gomoddirectives
+ - goprintffuncname
+ - ifshort
+ # - lll
+ - misspell
+ - nakedret
+ - nestif
+ - noctx
+ - nolintlint
+ - prealloc
+ - wrapcheck
+
+ # disable default linters, they are already enabled in .golangci.yml
+ disable:
+ - deadcode
+ - errcheck
+ - gosimple
+ - govet
+ - ineffassign
+ - staticcheck
+ - structcheck
+ - typecheck
+ - unused
+ - varcheck
diff --git a/vendor/github.com/muesli/termenv/.golangci.yml b/vendor/github.com/muesli/termenv/.golangci.yml
new file mode 100644
index 0000000..a5a91d0
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/.golangci.yml
@@ -0,0 +1,29 @@
+run:
+ tests: false
+
+issues:
+ include:
+ - EXC0001
+ - EXC0005
+ - EXC0011
+ - EXC0012
+ - EXC0013
+
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ enable:
+ - bodyclose
+ - exportloopref
+ - goimports
+ - gosec
+ - nilerr
+ - predeclared
+ - revive
+ - rowserrcheck
+ - sqlclosecheck
+ - tparallel
+ - unconvert
+ - unparam
+ - whitespace
diff --git a/vendor/github.com/muesli/termenv/LICENSE b/vendor/github.com/muesli/termenv/LICENSE
new file mode 100644
index 0000000..8532c45
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Christian Muehlhaeuser
+
+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/vendor/github.com/muesli/termenv/README.md b/vendor/github.com/muesli/termenv/README.md
new file mode 100644
index 0000000..29dcf01
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/README.md
@@ -0,0 +1,431 @@
+
+
+`termenv` lets you safely use advanced styling options on the terminal. It
+gathers information about the terminal environment in terms of its ANSI & color
+support and offers you convenient methods to colorize and style your output,
+without you having to deal with all kinds of weird ANSI escape sequences and
+color conversions.
+
+## Features
+
+- RGB/TrueColor support
+- Detects the supported color range of your terminal
+- Automatically converts colors to the best matching, available colors
+- Terminal theme (light/dark) detection
+- Chainable syntax
+- Nested styles
+
+## Installation
+
+```bash
+go get github.com/muesli/termenv
+```
+
+## Usage
+
+```go
+output := termenv.NewOutput(os.Stdout)
+```
+
+`termenv` queries the terminal's capabilities it is running in, so you can
+safely use advanced features, like RGB colors or ANSI styles. `output.Profile`
+returns the supported profile:
+
+- `termenv.Ascii` - no ANSI support detected, ASCII only
+- `termenv.ANSI` - 16 color ANSI support
+- `termenv.ANSI256` - Extended 256 color ANSI support
+- `termenv.TrueColor` - RGB/TrueColor support
+
+Alternatively, you can use `termenv.EnvColorProfile` which evaluates the
+terminal like `ColorProfile`, but also respects the `NO_COLOR` and
+`CLICOLOR_FORCE` environment variables.
+
+You can also query the terminal for its color scheme, so you know whether your
+app is running in a light- or dark-themed environment:
+
+```go
+// Returns terminal's foreground color
+color := output.ForegroundColor()
+
+// Returns terminal's background color
+color := output.BackgroundColor()
+
+// Returns whether terminal uses a dark-ish background
+darkTheme := output.HasDarkBackground()
+```
+
+### Manual Profile Selection
+
+If you don't want to rely on the automatic detection, you can manually select
+the profile you want to use:
+
+```go
+output := termenv.NewOutput(os.Stdout, termenv.WithProfile(termenv.TrueColor))
+```
+
+## Colors
+
+`termenv` supports multiple color profiles: Ascii (black & white only),
+ANSI (16 colors), ANSI Extended (256 colors), and TrueColor (24-bit RGB). Colors
+will automatically be degraded to the best matching available color in the
+desired profile:
+
+`TrueColor` => `ANSI 256 Colors` => `ANSI 16 Colors` => `Ascii`
+
+```go
+s := output.String("Hello World")
+
+// Supports hex values
+// Will automatically degrade colors on terminals not supporting RGB
+s.Foreground(output.Color("#abcdef"))
+// but also supports ANSI colors (0-255)
+s.Background(output.Color("69"))
+// ...or the color.Color interface
+s.Foreground(output.FromColor(color.RGBA{255, 128, 0, 255}))
+
+// Combine fore- & background colors
+s.Foreground(output.Color("#ffffff")).Background(output.Color("#0000ff"))
+
+// Supports the fmt.Stringer interface
+fmt.Println(s)
+```
+
+## Styles
+
+You can use a chainable syntax to compose your own styles:
+
+```go
+s := output.String("foobar")
+
+// Text styles
+s.Bold()
+s.Faint()
+s.Italic()
+s.CrossOut()
+s.Underline()
+s.Overline()
+
+// Reverse swaps current fore- & background colors
+s.Reverse()
+
+// Blinking text
+s.Blink()
+
+// Combine multiple options
+s.Bold().Underline()
+```
+
+## Template Helpers
+
+`termenv` provides a set of helper functions to style your Go templates:
+
+```go
+// load template helpers
+f := output.TemplateFuncs()
+tpl := template.New("tpl").Funcs(f)
+
+// apply bold style in a template
+bold := `{{ Bold "Hello World" }}`
+
+// examples for colorized templates
+col := `{{ Color "#ff0000" "#0000ff" "Red on Blue" }}`
+fg := `{{ Foreground "#ff0000" "Red Foreground" }}`
+bg := `{{ Background "#0000ff" "Blue Background" }}`
+
+// wrap styles
+wrap := `{{ Bold (Underline "Hello World") }}`
+
+// parse and render
+tpl, err = tpl.Parse(bold)
+
+var buf bytes.Buffer
+tpl.Execute(&buf, nil)
+fmt.Println(&buf)
+```
+
+Other available helper functions are: `Faint`, `Italic`, `CrossOut`,
+`Underline`, `Overline`, `Reverse`, and `Blink`.
+
+## Positioning
+
+```go
+// Move the cursor to a given position
+output.MoveCursor(row, column)
+
+// Save the cursor position
+output.SaveCursorPosition()
+
+// Restore a saved cursor position
+output.RestoreCursorPosition()
+
+// Move the cursor up a given number of lines
+output.CursorUp(n)
+
+// Move the cursor down a given number of lines
+output.CursorDown(n)
+
+// Move the cursor up a given number of lines
+output.CursorForward(n)
+
+// Move the cursor backwards a given number of cells
+output.CursorBack(n)
+
+// Move the cursor down a given number of lines and place it at the beginning
+// of the line
+output.CursorNextLine(n)
+
+// Move the cursor up a given number of lines and place it at the beginning of
+// the line
+output.CursorPrevLine(n)
+```
+
+## Screen
+
+```go
+// Reset the terminal to its default style, removing any active styles
+output.Reset()
+
+// RestoreScreen restores a previously saved screen state
+output.RestoreScreen()
+
+// SaveScreen saves the screen state
+output.SaveScreen()
+
+// Switch to the altscreen. The former view can be restored with ExitAltScreen()
+output.AltScreen()
+
+// Exit the altscreen and return to the former terminal view
+output.ExitAltScreen()
+
+// Clear the visible portion of the terminal
+output.ClearScreen()
+
+// Clear the current line
+output.ClearLine()
+
+// Clear a given number of lines
+output.ClearLines(n)
+
+// Set the scrolling region of the terminal
+output.ChangeScrollingRegion(top, bottom)
+
+// Insert the given number of lines at the top of the scrollable region, pushing
+// lines below down
+output.InsertLines(n)
+
+// Delete the given number of lines, pulling any lines in the scrollable region
+// below up
+output.DeleteLines(n)
+```
+
+## Session
+
+```go
+// SetWindowTitle sets the terminal window title
+output.SetWindowTitle(title)
+
+// SetForegroundColor sets the default foreground color
+output.SetForegroundColor(color)
+
+// SetBackgroundColor sets the default background color
+output.SetBackgroundColor(color)
+
+// SetCursorColor sets the cursor color
+output.SetCursorColor(color)
+
+// Hide the cursor
+output.HideCursor()
+
+// Show the cursor
+output.ShowCursor()
+
+// Copy to clipboard
+output.Copy(message)
+
+// Copy to primary clipboard (X11)
+output.CopyPrimary(message)
+
+// Trigger notification
+output.Notify(title, body)
+```
+
+## Mouse
+
+```go
+// Enable X10 mouse mode, only button press events are sent
+output.EnableMousePress()
+
+// Disable X10 mouse mode
+output.DisableMousePress()
+
+// Enable Mouse Tracking mode
+output.EnableMouse()
+
+// Disable Mouse Tracking mode
+output.DisableMouse()
+
+// Enable Hilite Mouse Tracking mode
+output.EnableMouseHilite()
+
+// Disable Hilite Mouse Tracking mode
+output.DisableMouseHilite()
+
+// Enable Cell Motion Mouse Tracking mode
+output.EnableMouseCellMotion()
+
+// Disable Cell Motion Mouse Tracking mode
+output.DisableMouseCellMotion()
+
+// Enable All Motion Mouse mode
+output.EnableMouseAllMotion()
+
+// Disable All Motion Mouse mode
+output.DisableMouseAllMotion()
+```
+
+## Bracketed Paste
+
+```go
+// Enables bracketed paste mode
+termenv.EnableBracketedPaste()
+
+// Disables bracketed paste mode
+termenv.DisableBracketedPaste()
+```
+
+## Terminal Feature Support
+
+### Color Support
+
+- 24-bit (RGB): alacritty, foot, iTerm, kitty, Konsole, st, tmux, vte-based, wezterm, Windows Terminal
+- 8-bit (256): rxvt, screen, xterm, Apple Terminal
+- 4-bit (16): Linux Console
+
+### Control Sequences
+
+
+Click to show feature matrix
+
+| Terminal | Query Color Scheme | Query Cursor Position | Set Window Title | Change Cursor Color | Change Default Foreground Setting | Change Default Background Setting | Bracketed Paste | Extended Mouse (SGR) | Pixels Mouse (SGR-Pixels) |
+| ---------------- | :----------------: | :-------------------: | :--------------: | :-----------------: | :-------------------------------: | :-------------------------------: | :-------------: | :------------------: | :-----------------------: |
+| alacritty | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
+| foot | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| kitty | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| Konsole | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ |
+| rxvt | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
+| urxvt | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
+| screen | ⛔[^mux] | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
+| st | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
+| tmux | ⛔[^mux] | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
+| vte-based[^vte] | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
+| wezterm | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| xterm | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ |
+| Linux Console | ❌ | ✅ | ⛔ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
+| Apple Terminal | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ |
+| iTerm | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ |
+| Windows cmd | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
+| Windows Terminal | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
+
+[^vte]: This covers all vte-based terminals, including Gnome Terminal, guake, Pantheon Terminal, Terminator, Tilix, XFCE Terminal.
+[^mux]: Unavailable as multiplexers (like tmux or screen) can be connected to multiple terminals (with different color settings) at the same time.
+
+You can help improve this list! Check out [how to](ansi_compat.md) and open an issue or pull request.
+
+
+
+### System Commands
+
+
+Click to show feature matrix
+
+| Terminal | Copy to Clipboard (OSC52) | Hyperlinks (OSC8) | Notifications (OSC777) |
+| ---------------- | :-----------------------: | :---------------: | :--------------------: |
+| alacritty | ✅ | ❌[^alacritty] | ❌ |
+| foot | ✅ | ✅ | ✅ |
+| kitty | ✅ | ✅ | ✅ |
+| Konsole | ❌[^konsole] | ✅ | ❌ |
+| rxvt | ❌ | ❌ | ❌ |
+| urxvt | ✅[^urxvt] | ❌ | ✅ |
+| screen | ✅ | ❌[^screen] | ❌ |
+| st | ✅ | ❌ | ❌ |
+| tmux | ✅ | ❌[^tmux] | ❌ |
+| vte-based[^vte] | ❌[^vte] | ✅ | ❌ |
+| wezterm | ✅ | ✅ | ❌ |
+| xterm | ✅ | ❌ | ❌ |
+| Linux Console | ⛔ | ⛔ | ❌ |
+| Apple Terminal | ✅[^apple] | ❌ | ❌ |
+| iTerm | ✅ | ✅ | ❌ |
+| Windows cmd | ❌ | ❌ | ❌ |
+| Windows Terminal | ✅ | ✅ | ❌ |
+
+[^vte]: This covers all vte-based terminals, including Gnome Terminal, guake, Pantheon Terminal, Terminator, Tilix, XFCE Terminal. OSC52 is not supported, see [issue#2495](https://gitlab.gnome.org/GNOME/vte/-/issues/2495).
+[^urxvt]: Workaround for urxvt not supporting OSC52. See [this](https://unix.stackexchange.com/a/629485) for more information.
+[^konsole]: OSC52 is not supported, for more info see [bug#372116](https://bugs.kde.org/show_bug.cgi?id=372116).
+[^apple]: OSC52 works with a [workaround](https://github.com/roy2220/osc52pty).
+[^tmux]: OSC8 is not supported, for more info see [issue#911](https://github.com/tmux/tmux/issues/911).
+[^screen]: OSC8 is not supported, for more info see [bug#50952](https://savannah.gnu.org/bugs/index.php?50952).
+[^alacritty]: OSC8 is not supported, for more info see [issue#922](https://github.com/alacritty/alacritty/issues/922).
+
+
+
+## Platform Support
+
+`termenv` works on Unix systems (like Linux, macOS, or BSD) and Windows. While
+terminal applications on Unix support ANSI styling out-of-the-box, on Windows
+you need to enable ANSI processing in your application first:
+
+```go
+ restoreConsole, err := termenv.EnableVirtualTerminalProcessing(termenv.DefaultOutput())
+ if err != nil {
+ panic(err)
+ }
+ defer restoreConsole()
+```
+
+The above code is safe to include on non-Windows systems or when os.Stdout does
+not refer to a terminal (e.g. in tests).
+
+## Color Chart
+
+
+
+You can find the source code used to create this chart in `termenv`'s examples.
+
+## Related Projects
+
+- [reflow](https://github.com/muesli/reflow) - ANSI-aware text operations
+- [Lip Gloss](https://github.com/charmbracelet/lipgloss) - style definitions for nice terminal layouts 👄
+- [ansi](https://github.com/muesli/ansi) - ANSI sequence helpers
+
+## termenv in the Wild
+
+Need some inspiration or just want to see how others are using `termenv`? Check
+out these projects:
+
+- [Bubble Tea](https://github.com/charmbracelet/bubbletea) - a powerful little TUI framework 🏗
+- [Glamour](https://github.com/charmbracelet/glamour) - stylesheet-based markdown rendering for your CLI apps 💇🏻♀️
+- [Glow](https://github.com/charmbracelet/glow) - a markdown renderer for the command-line 💅🏻
+- [duf](https://github.com/muesli/duf) - Disk Usage/Free Utility - a better 'df' alternative
+- [gitty](https://github.com/muesli/gitty) - contextual information about your git projects
+- [slides](https://github.com/maaslalani/slides) - terminal-based presentation tool
+
+## Feedback
+
+Got some feedback or suggestions? Please open an issue or drop me a note!
+
+- [Twitter](https://twitter.com/mueslix)
+- [The Fediverse](https://mastodon.social/@fribbledom)
+
+## License
+
+[MIT](https://github.com/muesli/termenv/raw/master/LICENSE)
diff --git a/vendor/github.com/muesli/termenv/ansi_compat.md b/vendor/github.com/muesli/termenv/ansi_compat.md
new file mode 100644
index 0000000..6b68a3a
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/ansi_compat.md
@@ -0,0 +1,65 @@
+## Change Foreground Color
+
+This command should enable a blue foreground color:
+
+```bash
+echo -ne "\033]10;#0000ff\007"
+```
+
+## Change Background Color
+
+This command should enable a green background color:
+
+```bash
+echo -ne "\033]11;#00ff00\007"
+```
+
+## Change Cursor Color
+
+This command should enable a red cursor color:
+
+```bash
+echo -ne "\033]12;#ff0000\007"
+```
+
+## Query Color Scheme
+
+These two commands should print out the currently active color scheme:
+
+```bash
+echo -ne "\033]10;?\033\\"
+echo -ne "\033]11;?\033\\"
+```
+
+## Query Cursor Position
+
+This command should print out the current cursor position:
+
+```bash
+echo -ne "\033[6n"
+```
+
+## Set Window Title
+
+This command should set the window title to "Test":
+
+```bash
+echo -ne "\033]2;Test\007" && sleep 10
+```
+
+## Bracketed paste
+
+Enter this command, then paste a word from the clipboard. The text
+displayed on the terminal should contain the codes `200~` and `201~`:
+
+```bash
+echo -ne "\033[?2004h" && sleep 10
+```
+
+## Trigger Notification
+
+This command should trigger a notification:
+
+```bash
+echo -ne "\033]777;notify;Title;Body\033\\"
+```
diff --git a/vendor/github.com/muesli/termenv/ansicolors.go b/vendor/github.com/muesli/termenv/ansicolors.go
new file mode 100644
index 0000000..ee303e2
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/ansicolors.go
@@ -0,0 +1,281 @@
+package termenv
+
+// ANSI color codes
+const (
+ ANSIBlack ANSIColor = iota
+ ANSIRed
+ ANSIGreen
+ ANSIYellow
+ ANSIBlue
+ ANSIMagenta
+ ANSICyan
+ ANSIWhite
+ ANSIBrightBlack
+ ANSIBrightRed
+ ANSIBrightGreen
+ ANSIBrightYellow
+ ANSIBrightBlue
+ ANSIBrightMagenta
+ ANSIBrightCyan
+ ANSIBrightWhite
+)
+
+// RGB values of ANSI colors (0-255).
+var ansiHex = []string{
+ "#000000",
+ "#800000",
+ "#008000",
+ "#808000",
+ "#000080",
+ "#800080",
+ "#008080",
+ "#c0c0c0",
+ "#808080",
+ "#ff0000",
+ "#00ff00",
+ "#ffff00",
+ "#0000ff",
+ "#ff00ff",
+ "#00ffff",
+ "#ffffff",
+ "#000000",
+ "#00005f",
+ "#000087",
+ "#0000af",
+ "#0000d7",
+ "#0000ff",
+ "#005f00",
+ "#005f5f",
+ "#005f87",
+ "#005faf",
+ "#005fd7",
+ "#005fff",
+ "#008700",
+ "#00875f",
+ "#008787",
+ "#0087af",
+ "#0087d7",
+ "#0087ff",
+ "#00af00",
+ "#00af5f",
+ "#00af87",
+ "#00afaf",
+ "#00afd7",
+ "#00afff",
+ "#00d700",
+ "#00d75f",
+ "#00d787",
+ "#00d7af",
+ "#00d7d7",
+ "#00d7ff",
+ "#00ff00",
+ "#00ff5f",
+ "#00ff87",
+ "#00ffaf",
+ "#00ffd7",
+ "#00ffff",
+ "#5f0000",
+ "#5f005f",
+ "#5f0087",
+ "#5f00af",
+ "#5f00d7",
+ "#5f00ff",
+ "#5f5f00",
+ "#5f5f5f",
+ "#5f5f87",
+ "#5f5faf",
+ "#5f5fd7",
+ "#5f5fff",
+ "#5f8700",
+ "#5f875f",
+ "#5f8787",
+ "#5f87af",
+ "#5f87d7",
+ "#5f87ff",
+ "#5faf00",
+ "#5faf5f",
+ "#5faf87",
+ "#5fafaf",
+ "#5fafd7",
+ "#5fafff",
+ "#5fd700",
+ "#5fd75f",
+ "#5fd787",
+ "#5fd7af",
+ "#5fd7d7",
+ "#5fd7ff",
+ "#5fff00",
+ "#5fff5f",
+ "#5fff87",
+ "#5fffaf",
+ "#5fffd7",
+ "#5fffff",
+ "#870000",
+ "#87005f",
+ "#870087",
+ "#8700af",
+ "#8700d7",
+ "#8700ff",
+ "#875f00",
+ "#875f5f",
+ "#875f87",
+ "#875faf",
+ "#875fd7",
+ "#875fff",
+ "#878700",
+ "#87875f",
+ "#878787",
+ "#8787af",
+ "#8787d7",
+ "#8787ff",
+ "#87af00",
+ "#87af5f",
+ "#87af87",
+ "#87afaf",
+ "#87afd7",
+ "#87afff",
+ "#87d700",
+ "#87d75f",
+ "#87d787",
+ "#87d7af",
+ "#87d7d7",
+ "#87d7ff",
+ "#87ff00",
+ "#87ff5f",
+ "#87ff87",
+ "#87ffaf",
+ "#87ffd7",
+ "#87ffff",
+ "#af0000",
+ "#af005f",
+ "#af0087",
+ "#af00af",
+ "#af00d7",
+ "#af00ff",
+ "#af5f00",
+ "#af5f5f",
+ "#af5f87",
+ "#af5faf",
+ "#af5fd7",
+ "#af5fff",
+ "#af8700",
+ "#af875f",
+ "#af8787",
+ "#af87af",
+ "#af87d7",
+ "#af87ff",
+ "#afaf00",
+ "#afaf5f",
+ "#afaf87",
+ "#afafaf",
+ "#afafd7",
+ "#afafff",
+ "#afd700",
+ "#afd75f",
+ "#afd787",
+ "#afd7af",
+ "#afd7d7",
+ "#afd7ff",
+ "#afff00",
+ "#afff5f",
+ "#afff87",
+ "#afffaf",
+ "#afffd7",
+ "#afffff",
+ "#d70000",
+ "#d7005f",
+ "#d70087",
+ "#d700af",
+ "#d700d7",
+ "#d700ff",
+ "#d75f00",
+ "#d75f5f",
+ "#d75f87",
+ "#d75faf",
+ "#d75fd7",
+ "#d75fff",
+ "#d78700",
+ "#d7875f",
+ "#d78787",
+ "#d787af",
+ "#d787d7",
+ "#d787ff",
+ "#d7af00",
+ "#d7af5f",
+ "#d7af87",
+ "#d7afaf",
+ "#d7afd7",
+ "#d7afff",
+ "#d7d700",
+ "#d7d75f",
+ "#d7d787",
+ "#d7d7af",
+ "#d7d7d7",
+ "#d7d7ff",
+ "#d7ff00",
+ "#d7ff5f",
+ "#d7ff87",
+ "#d7ffaf",
+ "#d7ffd7",
+ "#d7ffff",
+ "#ff0000",
+ "#ff005f",
+ "#ff0087",
+ "#ff00af",
+ "#ff00d7",
+ "#ff00ff",
+ "#ff5f00",
+ "#ff5f5f",
+ "#ff5f87",
+ "#ff5faf",
+ "#ff5fd7",
+ "#ff5fff",
+ "#ff8700",
+ "#ff875f",
+ "#ff8787",
+ "#ff87af",
+ "#ff87d7",
+ "#ff87ff",
+ "#ffaf00",
+ "#ffaf5f",
+ "#ffaf87",
+ "#ffafaf",
+ "#ffafd7",
+ "#ffafff",
+ "#ffd700",
+ "#ffd75f",
+ "#ffd787",
+ "#ffd7af",
+ "#ffd7d7",
+ "#ffd7ff",
+ "#ffff00",
+ "#ffff5f",
+ "#ffff87",
+ "#ffffaf",
+ "#ffffd7",
+ "#ffffff",
+ "#080808",
+ "#121212",
+ "#1c1c1c",
+ "#262626",
+ "#303030",
+ "#3a3a3a",
+ "#444444",
+ "#4e4e4e",
+ "#585858",
+ "#626262",
+ "#6c6c6c",
+ "#767676",
+ "#808080",
+ "#8a8a8a",
+ "#949494",
+ "#9e9e9e",
+ "#a8a8a8",
+ "#b2b2b2",
+ "#bcbcbc",
+ "#c6c6c6",
+ "#d0d0d0",
+ "#dadada",
+ "#e4e4e4",
+ "#eeeeee",
+}
diff --git a/vendor/github.com/muesli/termenv/color.go b/vendor/github.com/muesli/termenv/color.go
new file mode 100644
index 0000000..1a216e9
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/color.go
@@ -0,0 +1,204 @@
+package termenv
+
+import (
+ "errors"
+ "fmt"
+ "math"
+ "strings"
+
+ "github.com/lucasb-eyer/go-colorful"
+)
+
+var (
+ // ErrInvalidColor gets returned when a color is invalid.
+ ErrInvalidColor = errors.New("invalid color")
+)
+
+// Foreground and Background sequence codes
+const (
+ Foreground = "38"
+ Background = "48"
+)
+
+// Color is an interface implemented by all colors that can be converted to an
+// ANSI sequence.
+type Color interface {
+ // Sequence returns the ANSI Sequence for the color.
+ Sequence(bg bool) string
+}
+
+// NoColor is a nop for terminals that don't support colors.
+type NoColor struct{}
+
+func (c NoColor) String() string {
+ return ""
+}
+
+// ANSIColor is a color (0-15) as defined by the ANSI Standard.
+type ANSIColor int
+
+func (c ANSIColor) String() string {
+ return ansiHex[c]
+}
+
+// ANSI256Color is a color (16-255) as defined by the ANSI Standard.
+type ANSI256Color int
+
+func (c ANSI256Color) String() string {
+ return ansiHex[c]
+}
+
+// RGBColor is a hex-encoded color, e.g. "#abcdef".
+type RGBColor string
+
+// ConvertToRGB converts a Color to a colorful.Color.
+func ConvertToRGB(c Color) colorful.Color {
+ var hex string
+ switch v := c.(type) {
+ case RGBColor:
+ hex = string(v)
+ case ANSIColor:
+ hex = ansiHex[v]
+ case ANSI256Color:
+ hex = ansiHex[v]
+ }
+
+ ch, _ := colorful.Hex(hex)
+ return ch
+}
+
+// Sequence returns the ANSI Sequence for the color.
+func (c NoColor) Sequence(_ bool) string {
+ return ""
+}
+
+// Sequence returns the ANSI Sequence for the color.
+func (c ANSIColor) Sequence(bg bool) string {
+ col := int(c)
+ bgMod := func(c int) int {
+ if bg {
+ return c + 10
+ }
+ return c
+ }
+
+ if col < 8 {
+ return fmt.Sprintf("%d", bgMod(col)+30)
+ }
+ return fmt.Sprintf("%d", bgMod(col-8)+90)
+}
+
+// Sequence returns the ANSI Sequence for the color.
+func (c ANSI256Color) Sequence(bg bool) string {
+ prefix := Foreground
+ if bg {
+ prefix = Background
+ }
+ return fmt.Sprintf("%s;5;%d", prefix, c)
+}
+
+// Sequence returns the ANSI Sequence for the color.
+func (c RGBColor) Sequence(bg bool) string {
+ f, err := colorful.Hex(string(c))
+ if err != nil {
+ return ""
+ }
+
+ prefix := Foreground
+ if bg {
+ prefix = Background
+ }
+ return fmt.Sprintf("%s;2;%d;%d;%d", prefix, uint8(f.R*255), uint8(f.G*255), uint8(f.B*255))
+}
+
+func xTermColor(s string) (RGBColor, error) {
+ if len(s) < 24 || len(s) > 25 {
+ return RGBColor(""), ErrInvalidColor
+ }
+
+ switch {
+ case strings.HasSuffix(s, string(BEL)):
+ s = strings.TrimSuffix(s, string(BEL))
+ case strings.HasSuffix(s, string(ESC)):
+ s = strings.TrimSuffix(s, string(ESC))
+ case strings.HasSuffix(s, ST):
+ s = strings.TrimSuffix(s, ST)
+ default:
+ return RGBColor(""), ErrInvalidColor
+ }
+
+ s = s[4:]
+
+ prefix := ";rgb:"
+ if !strings.HasPrefix(s, prefix) {
+ return RGBColor(""), ErrInvalidColor
+ }
+ s = strings.TrimPrefix(s, prefix)
+
+ h := strings.Split(s, "/")
+ hex := fmt.Sprintf("#%s%s%s", h[0][:2], h[1][:2], h[2][:2])
+ return RGBColor(hex), nil
+}
+
+func ansi256ToANSIColor(c ANSI256Color) ANSIColor {
+ var r int
+ md := math.MaxFloat64
+
+ h, _ := colorful.Hex(ansiHex[c])
+ for i := 0; i <= 15; i++ {
+ hb, _ := colorful.Hex(ansiHex[i])
+ d := h.DistanceHSLuv(hb)
+
+ if d < md {
+ md = d
+ r = i
+ }
+ }
+
+ return ANSIColor(r)
+}
+
+func hexToANSI256Color(c colorful.Color) ANSI256Color {
+ v2ci := func(v float64) int {
+ if v < 48 {
+ return 0
+ }
+ if v < 115 {
+ return 1
+ }
+ return int((v - 35) / 40)
+ }
+
+ // Calculate the nearest 0-based color index at 16..231
+ r := v2ci(c.R * 255.0) // 0..5 each
+ g := v2ci(c.G * 255.0)
+ b := v2ci(c.B * 255.0)
+ ci := 36*r + 6*g + b /* 0..215 */
+
+ // Calculate the represented colors back from the index
+ i2cv := [6]int{0, 0x5f, 0x87, 0xaf, 0xd7, 0xff}
+ cr := i2cv[r] // r/g/b, 0..255 each
+ cg := i2cv[g]
+ cb := i2cv[b]
+
+ // Calculate the nearest 0-based gray index at 232..255
+ var grayIdx int
+ average := (r + g + b) / 3
+ if average > 238 {
+ grayIdx = 23
+ } else {
+ grayIdx = (average - 3) / 10 // 0..23
+ }
+ gv := 8 + 10*grayIdx // same value for r/g/b, 0..255
+
+ // Return the one which is nearer to the original input rgb value
+ c2 := colorful.Color{R: float64(cr) / 255.0, G: float64(cg) / 255.0, B: float64(cb) / 255.0}
+ g2 := colorful.Color{R: float64(gv) / 255.0, G: float64(gv) / 255.0, B: float64(gv) / 255.0}
+ colorDist := c.DistanceHSLuv(c2)
+ grayDist := c.DistanceHSLuv(g2)
+
+ if colorDist <= grayDist {
+ return ANSI256Color(16 + ci)
+ }
+ return ANSI256Color(232 + grayIdx)
+}
diff --git a/vendor/github.com/muesli/termenv/constants_linux.go b/vendor/github.com/muesli/termenv/constants_linux.go
new file mode 100644
index 0000000..4262f03
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/constants_linux.go
@@ -0,0 +1,8 @@
+package termenv
+
+import "golang.org/x/sys/unix"
+
+const (
+ tcgetattr = unix.TCGETS
+ tcsetattr = unix.TCSETS
+)
diff --git a/vendor/github.com/muesli/termenv/constants_solaris.go b/vendor/github.com/muesli/termenv/constants_solaris.go
new file mode 100644
index 0000000..4262f03
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/constants_solaris.go
@@ -0,0 +1,8 @@
+package termenv
+
+import "golang.org/x/sys/unix"
+
+const (
+ tcgetattr = unix.TCGETS
+ tcsetattr = unix.TCSETS
+)
diff --git a/vendor/github.com/muesli/termenv/constants_unix.go b/vendor/github.com/muesli/termenv/constants_unix.go
new file mode 100644
index 0000000..5d66424
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/constants_unix.go
@@ -0,0 +1,13 @@
+//go:build (darwin || dragonfly || freebsd || netbsd || openbsd) && !solaris && !illumos
+// +build darwin dragonfly freebsd netbsd openbsd
+// +build !solaris
+// +build !illumos
+
+package termenv
+
+import "golang.org/x/sys/unix"
+
+const (
+ tcgetattr = unix.TIOCGETA
+ tcsetattr = unix.TIOCSETA
+)
diff --git a/vendor/github.com/muesli/termenv/copy.go b/vendor/github.com/muesli/termenv/copy.go
new file mode 100644
index 0000000..4bf5c9f
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/copy.go
@@ -0,0 +1,37 @@
+package termenv
+
+import (
+ "strings"
+
+ "github.com/aymanbagabas/go-osc52/v2"
+)
+
+// Copy copies text to clipboard using OSC 52 escape sequence.
+func (o Output) Copy(str string) {
+ s := osc52.New(str)
+ if strings.HasPrefix(o.environ.Getenv("TERM"), "screen") {
+ s = s.Screen()
+ }
+ _, _ = s.WriteTo(o)
+}
+
+// CopyPrimary copies text to primary clipboard (X11) using OSC 52 escape
+// sequence.
+func (o Output) CopyPrimary(str string) {
+ s := osc52.New(str).Primary()
+ if strings.HasPrefix(o.environ.Getenv("TERM"), "screen") {
+ s = s.Screen()
+ }
+ _, _ = s.WriteTo(o)
+}
+
+// Copy copies text to clipboard using OSC 52 escape sequence.
+func Copy(str string) {
+ output.Copy(str)
+}
+
+// CopyPrimary copies text to primary clipboard (X11) using OSC 52 escape
+// sequence.
+func CopyPrimary(str string) {
+ output.CopyPrimary(str)
+}
diff --git a/vendor/github.com/muesli/termenv/hyperlink.go b/vendor/github.com/muesli/termenv/hyperlink.go
new file mode 100644
index 0000000..97e760a
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/hyperlink.go
@@ -0,0 +1,11 @@
+package termenv
+
+// Hyperlink creates a hyperlink using OSC8.
+func Hyperlink(link, name string) string {
+ return output.Hyperlink(link, name)
+}
+
+// Hyperlink creates a hyperlink using OSC8.
+func (o *Output) Hyperlink(link, name string) string {
+ return OSC + "8;;" + link + ST + name + OSC + "8;;" + ST
+}
diff --git a/vendor/github.com/muesli/termenv/notification.go b/vendor/github.com/muesli/termenv/notification.go
new file mode 100644
index 0000000..2a8cf06
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/notification.go
@@ -0,0 +1,11 @@
+package termenv
+
+// Notify triggers a notification using OSC777.
+func Notify(title, body string) {
+ output.Notify(title, body)
+}
+
+// Notify triggers a notification using OSC777.
+func (o *Output) Notify(title, body string) {
+ _, _ = o.WriteString(OSC + "777;notify;" + title + ";" + body + ST)
+}
diff --git a/vendor/github.com/muesli/termenv/output.go b/vendor/github.com/muesli/termenv/output.go
new file mode 100644
index 0000000..e22d369
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/output.go
@@ -0,0 +1,197 @@
+package termenv
+
+import (
+ "io"
+ "os"
+ "sync"
+)
+
+var (
+ // output is the default global output.
+ output = NewOutput(os.Stdout)
+)
+
+// File represents a file descriptor.
+type File interface {
+ io.ReadWriter
+ Fd() uintptr
+}
+
+// OutputOption sets an option on Output.
+type OutputOption = func(*Output)
+
+// Output is a terminal output.
+type Output struct {
+ Profile
+ tty io.Writer
+ environ Environ
+
+ assumeTTY bool
+ unsafe bool
+ cache bool
+ fgSync *sync.Once
+ fgColor Color
+ bgSync *sync.Once
+ bgColor Color
+}
+
+// Environ is an interface for getting environment variables.
+type Environ interface {
+ Environ() []string
+ Getenv(string) string
+}
+
+type osEnviron struct{}
+
+func (oe *osEnviron) Environ() []string {
+ return os.Environ()
+}
+
+func (oe *osEnviron) Getenv(key string) string {
+ return os.Getenv(key)
+}
+
+// DefaultOutput returns the default global output.
+func DefaultOutput() *Output {
+ return output
+}
+
+// SetDefaultOutput sets the default global output.
+func SetDefaultOutput(o *Output) {
+ output = o
+}
+
+// NewOutput returns a new Output for the given file descriptor.
+func NewOutput(tty io.Writer, opts ...OutputOption) *Output {
+ o := &Output{
+ tty: tty,
+ environ: &osEnviron{},
+ Profile: -1,
+ fgSync: &sync.Once{},
+ fgColor: NoColor{},
+ bgSync: &sync.Once{},
+ bgColor: NoColor{},
+ }
+
+ if o.tty == nil {
+ o.tty = os.Stdout
+ }
+ for _, opt := range opts {
+ opt(o)
+ }
+ if o.Profile < 0 {
+ o.Profile = o.EnvColorProfile()
+ }
+
+ return o
+}
+
+// WithEnvironment returns a new OutputOption for the given environment.
+func WithEnvironment(environ Environ) OutputOption {
+ return func(o *Output) {
+ o.environ = environ
+ }
+}
+
+// WithProfile returns a new OutputOption for the given profile.
+func WithProfile(profile Profile) OutputOption {
+ return func(o *Output) {
+ o.Profile = profile
+ }
+}
+
+// WithColorCache returns a new OutputOption with fore- and background color values
+// pre-fetched and cached.
+func WithColorCache(v bool) OutputOption {
+ return func(o *Output) {
+ o.cache = v
+
+ // cache the values now
+ _ = o.ForegroundColor()
+ _ = o.BackgroundColor()
+ }
+}
+
+// WithTTY returns a new OutputOption to assume whether or not the output is a TTY.
+// This is useful when mocking console output.
+func WithTTY(v bool) OutputOption {
+ return func(o *Output) {
+ o.assumeTTY = v
+ }
+}
+
+// WithUnsafe returns a new OutputOption with unsafe mode enabled. Unsafe mode doesn't
+// check whether or not the terminal is a TTY.
+//
+// This option supersedes WithTTY.
+//
+// This is useful when mocking console output and enforcing ANSI escape output
+// e.g. on SSH sessions.
+func WithUnsafe() OutputOption {
+ return func(o *Output) {
+ o.unsafe = true
+ }
+}
+
+// ForegroundColor returns the terminal's default foreground color.
+func (o *Output) ForegroundColor() Color {
+ f := func() {
+ if !o.isTTY() {
+ return
+ }
+
+ o.fgColor = o.foregroundColor()
+ }
+
+ if o.cache {
+ o.fgSync.Do(f)
+ } else {
+ f()
+ }
+
+ return o.fgColor
+}
+
+// BackgroundColor returns the terminal's default background color.
+func (o *Output) BackgroundColor() Color {
+ f := func() {
+ if !o.isTTY() {
+ return
+ }
+
+ o.bgColor = o.backgroundColor()
+ }
+
+ if o.cache {
+ o.bgSync.Do(f)
+ } else {
+ f()
+ }
+
+ return o.bgColor
+}
+
+// HasDarkBackground returns whether terminal uses a dark-ish background.
+func (o *Output) HasDarkBackground() bool {
+ c := ConvertToRGB(o.BackgroundColor())
+ _, _, l := c.Hsl()
+ return l < 0.5
+}
+
+// TTY returns the terminal's file descriptor. This may be nil if the output is
+// not a terminal.
+func (o Output) TTY() File {
+ if f, ok := o.tty.(File); ok {
+ return f
+ }
+ return nil
+}
+
+func (o Output) Write(p []byte) (int, error) {
+ return o.tty.Write(p)
+}
+
+// WriteString writes the given string to the output.
+func (o Output) WriteString(s string) (int, error) {
+ return o.Write([]byte(s))
+}
diff --git a/vendor/github.com/muesli/termenv/profile.go b/vendor/github.com/muesli/termenv/profile.go
new file mode 100644
index 0000000..fa128e2
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/profile.go
@@ -0,0 +1,97 @@
+package termenv
+
+import (
+ "image/color"
+ "strconv"
+ "strings"
+
+ "github.com/lucasb-eyer/go-colorful"
+)
+
+// Profile is a color profile: Ascii, ANSI, ANSI256, or TrueColor.
+type Profile int
+
+const (
+ // TrueColor, 24-bit color profile
+ TrueColor = Profile(iota)
+ // ANSI256, 8-bit color profile
+ ANSI256
+ // ANSI, 4-bit color profile
+ ANSI
+ // Ascii, uncolored profile
+ Ascii //nolint:revive
+)
+
+// String returns a new Style.
+func (p Profile) String(s ...string) Style {
+ return Style{
+ profile: p,
+ string: strings.Join(s, " "),
+ }
+}
+
+// Convert transforms a given Color to a Color supported within the Profile.
+func (p Profile) Convert(c Color) Color {
+ if p == Ascii {
+ return NoColor{}
+ }
+
+ switch v := c.(type) {
+ case ANSIColor:
+ return v
+
+ case ANSI256Color:
+ if p == ANSI {
+ return ansi256ToANSIColor(v)
+ }
+ return v
+
+ case RGBColor:
+ h, err := colorful.Hex(string(v))
+ if err != nil {
+ return nil
+ }
+ if p != TrueColor {
+ ac := hexToANSI256Color(h)
+ if p == ANSI {
+ return ansi256ToANSIColor(ac)
+ }
+ return ac
+ }
+ return v
+ }
+
+ return c
+}
+
+// Color creates a Color from a string. Valid inputs are hex colors, as well as
+// ANSI color codes (0-15, 16-255).
+func (p Profile) Color(s string) Color {
+ if len(s) == 0 {
+ return nil
+ }
+
+ var c Color
+ if strings.HasPrefix(s, "#") {
+ c = RGBColor(s)
+ } else {
+ i, err := strconv.Atoi(s)
+ if err != nil {
+ return nil
+ }
+
+ if i < 16 {
+ c = ANSIColor(i)
+ } else {
+ c = ANSI256Color(i)
+ }
+ }
+
+ return p.Convert(c)
+}
+
+// FromColor creates a Color from a color.Color.
+func (p Profile) FromColor(c color.Color) Color {
+ col, _ := colorful.MakeColor(c)
+ return p.Color(col.Hex())
+}
diff --git a/vendor/github.com/muesli/termenv/screen.go b/vendor/github.com/muesli/termenv/screen.go
new file mode 100644
index 0000000..a71181b
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/screen.go
@@ -0,0 +1,590 @@
+package termenv
+
+import (
+ "fmt"
+ "strings"
+)
+
+// Sequence definitions.
+const (
+ // Cursor positioning.
+ CursorUpSeq = "%dA"
+ CursorDownSeq = "%dB"
+ CursorForwardSeq = "%dC"
+ CursorBackSeq = "%dD"
+ CursorNextLineSeq = "%dE"
+ CursorPreviousLineSeq = "%dF"
+ CursorHorizontalSeq = "%dG"
+ CursorPositionSeq = "%d;%dH"
+ EraseDisplaySeq = "%dJ"
+ EraseLineSeq = "%dK"
+ ScrollUpSeq = "%dS"
+ ScrollDownSeq = "%dT"
+ SaveCursorPositionSeq = "s"
+ RestoreCursorPositionSeq = "u"
+ ChangeScrollingRegionSeq = "%d;%dr"
+ InsertLineSeq = "%dL"
+ DeleteLineSeq = "%dM"
+
+ // Explicit values for EraseLineSeq.
+ EraseLineRightSeq = "0K"
+ EraseLineLeftSeq = "1K"
+ EraseEntireLineSeq = "2K"
+
+ // Mouse.
+ EnableMousePressSeq = "?9h" // press only (X10)
+ DisableMousePressSeq = "?9l"
+ EnableMouseSeq = "?1000h" // press, release, wheel
+ DisableMouseSeq = "?1000l"
+ EnableMouseHiliteSeq = "?1001h" // highlight
+ DisableMouseHiliteSeq = "?1001l"
+ EnableMouseCellMotionSeq = "?1002h" // press, release, move on pressed, wheel
+ DisableMouseCellMotionSeq = "?1002l"
+ EnableMouseAllMotionSeq = "?1003h" // press, release, move, wheel
+ DisableMouseAllMotionSeq = "?1003l"
+ EnableMouseExtendedModeSeq = "?1006h" // press, release, move, wheel, extended coordinates
+ DisableMouseExtendedModeSeq = "?1006l"
+ EnableMousePixelsModeSeq = "?1016h" // press, release, move, wheel, extended pixel coordinates
+ DisableMousePixelsModeSeq = "?1016l"
+
+ // Screen.
+ RestoreScreenSeq = "?47l"
+ SaveScreenSeq = "?47h"
+ AltScreenSeq = "?1049h"
+ ExitAltScreenSeq = "?1049l"
+
+ // Bracketed paste.
+ // https://en.wikipedia.org/wiki/Bracketed-paste
+ EnableBracketedPasteSeq = "?2004h"
+ DisableBracketedPasteSeq = "?2004l"
+ StartBracketedPasteSeq = "200~"
+ EndBracketedPasteSeq = "201~"
+
+ // Session.
+ SetWindowTitleSeq = "2;%s" + string(BEL)
+ SetForegroundColorSeq = "10;%s" + string(BEL)
+ SetBackgroundColorSeq = "11;%s" + string(BEL)
+ SetCursorColorSeq = "12;%s" + string(BEL)
+ ShowCursorSeq = "?25h"
+ HideCursorSeq = "?25l"
+)
+
+// Reset the terminal to its default style, removing any active styles.
+func (o Output) Reset() {
+ fmt.Fprint(o.tty, CSI+ResetSeq+"m")
+}
+
+// SetForegroundColor sets the default foreground color.
+func (o Output) SetForegroundColor(color Color) {
+ fmt.Fprintf(o.tty, OSC+SetForegroundColorSeq, color)
+}
+
+// SetBackgroundColor sets the default background color.
+func (o Output) SetBackgroundColor(color Color) {
+ fmt.Fprintf(o.tty, OSC+SetBackgroundColorSeq, color)
+}
+
+// SetCursorColor sets the cursor color.
+func (o Output) SetCursorColor(color Color) {
+ fmt.Fprintf(o.tty, OSC+SetCursorColorSeq, color)
+}
+
+// RestoreScreen restores a previously saved screen state.
+func (o Output) RestoreScreen() {
+ fmt.Fprint(o.tty, CSI+RestoreScreenSeq)
+}
+
+// SaveScreen saves the screen state.
+func (o Output) SaveScreen() {
+ fmt.Fprint(o.tty, CSI+SaveScreenSeq)
+}
+
+// AltScreen switches to the alternate screen buffer. The former view can be
+// restored with ExitAltScreen().
+func (o Output) AltScreen() {
+ fmt.Fprint(o.tty, CSI+AltScreenSeq)
+}
+
+// ExitAltScreen exits the alternate screen buffer and returns to the former
+// terminal view.
+func (o Output) ExitAltScreen() {
+ fmt.Fprint(o.tty, CSI+ExitAltScreenSeq)
+}
+
+// ClearScreen clears the visible portion of the terminal.
+func (o Output) ClearScreen() {
+ fmt.Fprintf(o.tty, CSI+EraseDisplaySeq, 2)
+ o.MoveCursor(1, 1)
+}
+
+// MoveCursor moves the cursor to a given position.
+func (o Output) MoveCursor(row int, column int) {
+ fmt.Fprintf(o.tty, CSI+CursorPositionSeq, row, column)
+}
+
+// HideCursor hides the cursor.
+func (o Output) HideCursor() {
+ fmt.Fprint(o.tty, CSI+HideCursorSeq)
+}
+
+// ShowCursor shows the cursor.
+func (o Output) ShowCursor() {
+ fmt.Fprint(o.tty, CSI+ShowCursorSeq)
+}
+
+// SaveCursorPosition saves the cursor position.
+func (o Output) SaveCursorPosition() {
+ fmt.Fprint(o.tty, CSI+SaveCursorPositionSeq)
+}
+
+// RestoreCursorPosition restores a saved cursor position.
+func (o Output) RestoreCursorPosition() {
+ fmt.Fprint(o.tty, CSI+RestoreCursorPositionSeq)
+}
+
+// CursorUp moves the cursor up a given number of lines.
+func (o Output) CursorUp(n int) {
+ fmt.Fprintf(o.tty, CSI+CursorUpSeq, n)
+}
+
+// CursorDown moves the cursor down a given number of lines.
+func (o Output) CursorDown(n int) {
+ fmt.Fprintf(o.tty, CSI+CursorDownSeq, n)
+}
+
+// CursorForward moves the cursor up a given number of lines.
+func (o Output) CursorForward(n int) {
+ fmt.Fprintf(o.tty, CSI+CursorForwardSeq, n)
+}
+
+// CursorBack moves the cursor backwards a given number of cells.
+func (o Output) CursorBack(n int) {
+ fmt.Fprintf(o.tty, CSI+CursorBackSeq, n)
+}
+
+// CursorNextLine moves the cursor down a given number of lines and places it at
+// the beginning of the line.
+func (o Output) CursorNextLine(n int) {
+ fmt.Fprintf(o.tty, CSI+CursorNextLineSeq, n)
+}
+
+// CursorPrevLine moves the cursor up a given number of lines and places it at
+// the beginning of the line.
+func (o Output) CursorPrevLine(n int) {
+ fmt.Fprintf(o.tty, CSI+CursorPreviousLineSeq, n)
+}
+
+// ClearLine clears the current line.
+func (o Output) ClearLine() {
+ fmt.Fprint(o.tty, CSI+EraseEntireLineSeq)
+}
+
+// ClearLineLeft clears the line to the left of the cursor.
+func (o Output) ClearLineLeft() {
+ fmt.Fprint(o.tty, CSI+EraseLineLeftSeq)
+}
+
+// ClearLineRight clears the line to the right of the cursor.
+func (o Output) ClearLineRight() {
+ fmt.Fprint(o.tty, CSI+EraseLineRightSeq)
+}
+
+// ClearLines clears a given number of lines.
+func (o Output) ClearLines(n int) {
+ clearLine := fmt.Sprintf(CSI+EraseLineSeq, 2)
+ cursorUp := fmt.Sprintf(CSI+CursorUpSeq, 1)
+ fmt.Fprint(o.tty, clearLine+strings.Repeat(cursorUp+clearLine, n))
+}
+
+// ChangeScrollingRegion sets the scrolling region of the terminal.
+func (o Output) ChangeScrollingRegion(top, bottom int) {
+ fmt.Fprintf(o.tty, CSI+ChangeScrollingRegionSeq, top, bottom)
+}
+
+// InsertLines inserts the given number of lines at the top of the scrollable
+// region, pushing lines below down.
+func (o Output) InsertLines(n int) {
+ fmt.Fprintf(o.tty, CSI+InsertLineSeq, n)
+}
+
+// DeleteLines deletes the given number of lines, pulling any lines in
+// the scrollable region below up.
+func (o Output) DeleteLines(n int) {
+ fmt.Fprintf(o.tty, CSI+DeleteLineSeq, n)
+}
+
+// EnableMousePress enables X10 mouse mode. Button press events are sent only.
+func (o Output) EnableMousePress() {
+ fmt.Fprint(o.tty, CSI+EnableMousePressSeq)
+}
+
+// DisableMousePress disables X10 mouse mode.
+func (o Output) DisableMousePress() {
+ fmt.Fprint(o.tty, CSI+DisableMousePressSeq)
+}
+
+// EnableMouse enables Mouse Tracking mode.
+func (o Output) EnableMouse() {
+ fmt.Fprint(o.tty, CSI+EnableMouseSeq)
+}
+
+// DisableMouse disables Mouse Tracking mode.
+func (o Output) DisableMouse() {
+ fmt.Fprint(o.tty, CSI+DisableMouseSeq)
+}
+
+// EnableMouseHilite enables Hilite Mouse Tracking mode.
+func (o Output) EnableMouseHilite() {
+ fmt.Fprint(o.tty, CSI+EnableMouseHiliteSeq)
+}
+
+// DisableMouseHilite disables Hilite Mouse Tracking mode.
+func (o Output) DisableMouseHilite() {
+ fmt.Fprint(o.tty, CSI+DisableMouseHiliteSeq)
+}
+
+// EnableMouseCellMotion enables Cell Motion Mouse Tracking mode.
+func (o Output) EnableMouseCellMotion() {
+ fmt.Fprint(o.tty, CSI+EnableMouseCellMotionSeq)
+}
+
+// DisableMouseCellMotion disables Cell Motion Mouse Tracking mode.
+func (o Output) DisableMouseCellMotion() {
+ fmt.Fprint(o.tty, CSI+DisableMouseCellMotionSeq)
+}
+
+// EnableMouseAllMotion enables All Motion Mouse mode.
+func (o Output) EnableMouseAllMotion() {
+ fmt.Fprint(o.tty, CSI+EnableMouseAllMotionSeq)
+}
+
+// DisableMouseAllMotion disables All Motion Mouse mode.
+func (o Output) DisableMouseAllMotion() {
+ fmt.Fprint(o.tty, CSI+DisableMouseAllMotionSeq)
+}
+
+// EnableMouseExtendedMotion enables Extended Mouse mode (SGR). This should be
+// enabled in conjunction with EnableMouseCellMotion, and EnableMouseAllMotion.
+func (o Output) EnableMouseExtendedMode() {
+ fmt.Fprint(o.tty, CSI+EnableMouseExtendedModeSeq)
+}
+
+// DisableMouseExtendedMotion disables Extended Mouse mode (SGR).
+func (o Output) DisableMouseExtendedMode() {
+ fmt.Fprint(o.tty, CSI+DisableMouseExtendedModeSeq)
+}
+
+// EnableMousePixelsMotion enables Pixel Motion Mouse mode (SGR-Pixels). This
+// should be enabled in conjunction with EnableMouseCellMotion, and
+// EnableMouseAllMotion.
+func (o Output) EnableMousePixelsMode() {
+ fmt.Fprint(o.tty, CSI+EnableMousePixelsModeSeq)
+}
+
+// DisableMousePixelsMotion disables Pixel Motion Mouse mode (SGR-Pixels).
+func (o Output) DisableMousePixelsMode() {
+ fmt.Fprint(o.tty, CSI+DisableMousePixelsModeSeq)
+}
+
+// SetWindowTitle sets the terminal window title.
+func (o Output) SetWindowTitle(title string) {
+ fmt.Fprintf(o.tty, OSC+SetWindowTitleSeq, title)
+}
+
+// EnableBracketedPaste enables bracketed paste.
+func (o Output) EnableBracketedPaste() {
+ fmt.Fprintf(o.tty, CSI+EnableBracketedPasteSeq)
+}
+
+// DisableBracketedPaste disables bracketed paste.
+func (o Output) DisableBracketedPaste() {
+ fmt.Fprintf(o.tty, CSI+DisableBracketedPasteSeq)
+}
+
+// Legacy functions.
+
+// Reset the terminal to its default style, removing any active styles.
+//
+// Deprecated: please use termenv.Output instead.
+func Reset() {
+ output.Reset()
+}
+
+// SetForegroundColor sets the default foreground color.
+//
+// Deprecated: please use termenv.Output instead.
+func SetForegroundColor(color Color) {
+ output.SetForegroundColor(color)
+}
+
+// SetBackgroundColor sets the default background color.
+//
+// Deprecated: please use termenv.Output instead.
+func SetBackgroundColor(color Color) {
+ output.SetBackgroundColor(color)
+}
+
+// SetCursorColor sets the cursor color.
+//
+// Deprecated: please use termenv.Output instead.
+func SetCursorColor(color Color) {
+ output.SetCursorColor(color)
+}
+
+// RestoreScreen restores a previously saved screen state.
+//
+// Deprecated: please use termenv.Output instead.
+func RestoreScreen() {
+ output.RestoreScreen()
+}
+
+// SaveScreen saves the screen state.
+//
+// Deprecated: please use termenv.Output instead.
+func SaveScreen() {
+ output.SaveScreen()
+}
+
+// AltScreen switches to the alternate screen buffer. The former view can be
+// restored with ExitAltScreen().
+//
+// Deprecated: please use termenv.Output instead.
+func AltScreen() {
+ output.AltScreen()
+}
+
+// ExitAltScreen exits the alternate screen buffer and returns to the former
+// terminal view.
+//
+// Deprecated: please use termenv.Output instead.
+func ExitAltScreen() {
+ output.ExitAltScreen()
+}
+
+// ClearScreen clears the visible portion of the terminal.
+//
+// Deprecated: please use termenv.Output instead.
+func ClearScreen() {
+ output.ClearScreen()
+}
+
+// MoveCursor moves the cursor to a given position.
+//
+// Deprecated: please use termenv.Output instead.
+func MoveCursor(row int, column int) {
+ output.MoveCursor(row, column)
+}
+
+// HideCursor hides the cursor.
+//
+// Deprecated: please use termenv.Output instead.
+func HideCursor() {
+ output.HideCursor()
+}
+
+// ShowCursor shows the cursor.
+//
+// Deprecated: please use termenv.Output instead.
+func ShowCursor() {
+ output.ShowCursor()
+}
+
+// SaveCursorPosition saves the cursor position.
+//
+// Deprecated: please use termenv.Output instead.
+func SaveCursorPosition() {
+ output.SaveCursorPosition()
+}
+
+// RestoreCursorPosition restores a saved cursor position.
+//
+// Deprecated: please use termenv.Output instead.
+func RestoreCursorPosition() {
+ output.RestoreCursorPosition()
+}
+
+// CursorUp moves the cursor up a given number of lines.
+//
+// Deprecated: please use termenv.Output instead.
+func CursorUp(n int) {
+ output.CursorUp(n)
+}
+
+// CursorDown moves the cursor down a given number of lines.
+//
+// Deprecated: please use termenv.Output instead.
+func CursorDown(n int) {
+ output.CursorDown(n)
+}
+
+// CursorForward moves the cursor up a given number of lines.
+//
+// Deprecated: please use termenv.Output instead.
+func CursorForward(n int) {
+ output.CursorForward(n)
+}
+
+// CursorBack moves the cursor backwards a given number of cells.
+//
+// Deprecated: please use termenv.Output instead.
+func CursorBack(n int) {
+ output.CursorBack(n)
+}
+
+// CursorNextLine moves the cursor down a given number of lines and places it at
+// the beginning of the line.
+//
+// Deprecated: please use termenv.Output instead.
+func CursorNextLine(n int) {
+ output.CursorNextLine(n)
+}
+
+// CursorPrevLine moves the cursor up a given number of lines and places it at
+// the beginning of the line.
+//
+// Deprecated: please use termenv.Output instead.
+func CursorPrevLine(n int) {
+ output.CursorPrevLine(n)
+}
+
+// ClearLine clears the current line.
+//
+// Deprecated: please use termenv.Output instead.
+func ClearLine() {
+ output.ClearLine()
+}
+
+// ClearLineLeft clears the line to the left of the cursor.
+//
+// Deprecated: please use termenv.Output instead.
+func ClearLineLeft() {
+ output.ClearLineLeft()
+}
+
+// ClearLineRight clears the line to the right of the cursor.
+//
+// Deprecated: please use termenv.Output instead.
+func ClearLineRight() {
+ output.ClearLineRight()
+}
+
+// ClearLines clears a given number of lines.
+//
+// Deprecated: please use termenv.Output instead.
+func ClearLines(n int) {
+ output.ClearLines(n)
+}
+
+// ChangeScrollingRegion sets the scrolling region of the terminal.
+//
+// Deprecated: please use termenv.Output instead.
+func ChangeScrollingRegion(top, bottom int) {
+ output.ChangeScrollingRegion(top, bottom)
+}
+
+// InsertLines inserts the given number of lines at the top of the scrollable
+// region, pushing lines below down.
+//
+// Deprecated: please use termenv.Output instead.
+func InsertLines(n int) {
+ output.InsertLines(n)
+}
+
+// DeleteLines deletes the given number of lines, pulling any lines in
+// the scrollable region below up.
+//
+// Deprecated: please use termenv.Output instead.
+func DeleteLines(n int) {
+ output.DeleteLines(n)
+}
+
+// EnableMousePress enables X10 mouse mode. Button press events are sent only.
+//
+// Deprecated: please use termenv.Output instead.
+func EnableMousePress() {
+ output.EnableMousePress()
+}
+
+// DisableMousePress disables X10 mouse mode.
+//
+// Deprecated: please use termenv.Output instead.
+func DisableMousePress() {
+ output.DisableMousePress()
+}
+
+// EnableMouse enables Mouse Tracking mode.
+//
+// Deprecated: please use termenv.Output instead.
+func EnableMouse() {
+ output.EnableMouse()
+}
+
+// DisableMouse disables Mouse Tracking mode.
+//
+// Deprecated: please use termenv.Output instead.
+func DisableMouse() {
+ output.DisableMouse()
+}
+
+// EnableMouseHilite enables Hilite Mouse Tracking mode.
+//
+// Deprecated: please use termenv.Output instead.
+func EnableMouseHilite() {
+ output.EnableMouseHilite()
+}
+
+// DisableMouseHilite disables Hilite Mouse Tracking mode.
+//
+// Deprecated: please use termenv.Output instead.
+func DisableMouseHilite() {
+ output.DisableMouseHilite()
+}
+
+// EnableMouseCellMotion enables Cell Motion Mouse Tracking mode.
+//
+// Deprecated: please use termenv.Output instead.
+func EnableMouseCellMotion() {
+ output.EnableMouseCellMotion()
+}
+
+// DisableMouseCellMotion disables Cell Motion Mouse Tracking mode.
+//
+// Deprecated: please use termenv.Output instead.
+func DisableMouseCellMotion() {
+ output.DisableMouseCellMotion()
+}
+
+// EnableMouseAllMotion enables All Motion Mouse mode.
+//
+// Deprecated: please use termenv.Output instead.
+func EnableMouseAllMotion() {
+ output.EnableMouseAllMotion()
+}
+
+// DisableMouseAllMotion disables All Motion Mouse mode.
+//
+// Deprecated: please use termenv.Output instead.
+func DisableMouseAllMotion() {
+ output.DisableMouseAllMotion()
+}
+
+// SetWindowTitle sets the terminal window title.
+//
+// Deprecated: please use termenv.Output instead.
+func SetWindowTitle(title string) {
+ output.SetWindowTitle(title)
+}
+
+// EnableBracketedPaste enables bracketed paste.
+//
+// Deprecated: please use termenv.Output instead.
+func EnableBracketedPaste() {
+ output.EnableBracketedPaste()
+}
+
+// DisableBracketedPaste disables bracketed paste.
+//
+// Deprecated: please use termenv.Output instead.
+func DisableBracketedPaste() {
+ output.DisableBracketedPaste()
+}
diff --git a/vendor/github.com/muesli/termenv/style.go b/vendor/github.com/muesli/termenv/style.go
new file mode 100644
index 0000000..83b0b4d
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/style.go
@@ -0,0 +1,126 @@
+package termenv
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/mattn/go-runewidth"
+)
+
+// Sequence definitions.
+const (
+ ResetSeq = "0"
+ BoldSeq = "1"
+ FaintSeq = "2"
+ ItalicSeq = "3"
+ UnderlineSeq = "4"
+ BlinkSeq = "5"
+ ReverseSeq = "7"
+ CrossOutSeq = "9"
+ OverlineSeq = "53"
+)
+
+// Style is a string that various rendering styles can be applied to.
+type Style struct {
+ profile Profile
+ string
+ styles []string
+}
+
+// String returns a new Style.
+func String(s ...string) Style {
+ return Style{
+ profile: ANSI,
+ string: strings.Join(s, " "),
+ }
+}
+
+func (t Style) String() string {
+ return t.Styled(t.string)
+}
+
+// Styled renders s with all applied styles.
+func (t Style) Styled(s string) string {
+ if t.profile == Ascii {
+ return s
+ }
+ if len(t.styles) == 0 {
+ return s
+ }
+
+ seq := strings.Join(t.styles, ";")
+ if seq == "" {
+ return s
+ }
+
+ return fmt.Sprintf("%s%sm%s%sm", CSI, seq, s, CSI+ResetSeq)
+}
+
+// Foreground sets a foreground color.
+func (t Style) Foreground(c Color) Style {
+ if c != nil {
+ t.styles = append(t.styles, c.Sequence(false))
+ }
+ return t
+}
+
+// Background sets a background color.
+func (t Style) Background(c Color) Style {
+ if c != nil {
+ t.styles = append(t.styles, c.Sequence(true))
+ }
+ return t
+}
+
+// Bold enables bold rendering.
+func (t Style) Bold() Style {
+ t.styles = append(t.styles, BoldSeq)
+ return t
+}
+
+// Faint enables faint rendering.
+func (t Style) Faint() Style {
+ t.styles = append(t.styles, FaintSeq)
+ return t
+}
+
+// Italic enables italic rendering.
+func (t Style) Italic() Style {
+ t.styles = append(t.styles, ItalicSeq)
+ return t
+}
+
+// Underline enables underline rendering.
+func (t Style) Underline() Style {
+ t.styles = append(t.styles, UnderlineSeq)
+ return t
+}
+
+// Overline enables overline rendering.
+func (t Style) Overline() Style {
+ t.styles = append(t.styles, OverlineSeq)
+ return t
+}
+
+// Blink enables blink mode.
+func (t Style) Blink() Style {
+ t.styles = append(t.styles, BlinkSeq)
+ return t
+}
+
+// Reverse enables reverse color mode.
+func (t Style) Reverse() Style {
+ t.styles = append(t.styles, ReverseSeq)
+ return t
+}
+
+// CrossOut enables crossed-out rendering.
+func (t Style) CrossOut() Style {
+ t.styles = append(t.styles, CrossOutSeq)
+ return t
+}
+
+// Width returns the width required to print all runes in Style.
+func (t Style) Width() int {
+ return runewidth.StringWidth(t.string)
+}
diff --git a/vendor/github.com/muesli/termenv/termenv.go b/vendor/github.com/muesli/termenv/termenv.go
new file mode 100644
index 0000000..4ceb271
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/termenv.go
@@ -0,0 +1,114 @@
+package termenv
+
+import (
+ "errors"
+
+ "github.com/mattn/go-isatty"
+)
+
+var (
+ // ErrStatusReport gets returned when the terminal can't be queried.
+ ErrStatusReport = errors.New("unable to retrieve status report")
+)
+
+const (
+ // Escape character
+ ESC = '\x1b'
+ // Bell
+ BEL = '\a'
+ // Control Sequence Introducer
+ CSI = string(ESC) + "["
+ // Operating System Command
+ OSC = string(ESC) + "]"
+ // String Terminator
+ ST = string(ESC) + `\`
+)
+
+func (o *Output) isTTY() bool {
+ if o.assumeTTY || o.unsafe {
+ return true
+ }
+ if len(o.environ.Getenv("CI")) > 0 {
+ return false
+ }
+ if o.TTY() == nil {
+ return false
+ }
+
+ return isatty.IsTerminal(o.TTY().Fd())
+}
+
+// ColorProfile returns the supported color profile:
+// Ascii, ANSI, ANSI256, or TrueColor.
+func ColorProfile() Profile {
+ return output.ColorProfile()
+}
+
+// ForegroundColor returns the terminal's default foreground color.
+func ForegroundColor() Color {
+ return output.ForegroundColor()
+}
+
+// BackgroundColor returns the terminal's default background color.
+func BackgroundColor() Color {
+ return output.BackgroundColor()
+}
+
+// HasDarkBackground returns whether terminal uses a dark-ish background.
+func HasDarkBackground() bool {
+ return output.HasDarkBackground()
+}
+
+// EnvNoColor returns true if the environment variables explicitly disable color output
+// by setting NO_COLOR (https://no-color.org/)
+// or CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
+// If NO_COLOR is set, this will return true, ignoring CLICOLOR/CLICOLOR_FORCE
+// If CLICOLOR=="0", it will be true only if CLICOLOR_FORCE is also "0" or is unset.
+func (o *Output) EnvNoColor() bool {
+ return o.environ.Getenv("NO_COLOR") != "" || (o.environ.Getenv("CLICOLOR") == "0" && !o.cliColorForced())
+}
+
+// EnvNoColor returns true if the environment variables explicitly disable color output
+// by setting NO_COLOR (https://no-color.org/)
+// or CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
+// If NO_COLOR is set, this will return true, ignoring CLICOLOR/CLICOLOR_FORCE
+// If CLICOLOR=="0", it will be true only if CLICOLOR_FORCE is also "0" or is unset.
+func EnvNoColor() bool {
+ return output.EnvNoColor()
+}
+
+// EnvColorProfile returns the color profile based on environment variables set
+// Supports NO_COLOR (https://no-color.org/)
+// and CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
+// If none of these environment variables are set, this behaves the same as ColorProfile()
+// It will return the Ascii color profile if EnvNoColor() returns true
+// If the terminal does not support any colors, but CLICOLOR_FORCE is set and not "0"
+// then the ANSI color profile will be returned.
+func EnvColorProfile() Profile {
+ return output.EnvColorProfile()
+}
+
+// EnvColorProfile returns the color profile based on environment variables set
+// Supports NO_COLOR (https://no-color.org/)
+// and CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
+// If none of these environment variables are set, this behaves the same as ColorProfile()
+// It will return the Ascii color profile if EnvNoColor() returns true
+// If the terminal does not support any colors, but CLICOLOR_FORCE is set and not "0"
+// then the ANSI color profile will be returned.
+func (o *Output) EnvColorProfile() Profile {
+ if o.EnvNoColor() {
+ return Ascii
+ }
+ p := o.ColorProfile()
+ if o.cliColorForced() && p == Ascii {
+ return ANSI
+ }
+ return p
+}
+
+func (o *Output) cliColorForced() bool {
+ if forced := o.environ.Getenv("CLICOLOR_FORCE"); forced != "" {
+ return forced != "0"
+ }
+ return false
+}
diff --git a/vendor/github.com/muesli/termenv/termenv_other.go b/vendor/github.com/muesli/termenv/termenv_other.go
new file mode 100644
index 0000000..93a43b6
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/termenv_other.go
@@ -0,0 +1,30 @@
+//go:build js || plan9 || aix
+// +build js plan9 aix
+
+package termenv
+
+import "io"
+
+// ColorProfile returns the supported color profile:
+// ANSI256
+func (o Output) ColorProfile() Profile {
+ return ANSI256
+}
+
+func (o Output) foregroundColor() Color {
+ // default gray
+ return ANSIColor(7)
+}
+
+func (o Output) backgroundColor() Color {
+ // default black
+ return ANSIColor(0)
+}
+
+// EnableVirtualTerminalProcessing enables virtual terminal processing on
+// Windows for w and returns a function that restores w to its previous state.
+// On non-Windows platforms, or if w does not refer to a terminal, then it
+// returns a non-nil no-op function and no error.
+func EnableVirtualTerminalProcessing(w io.Writer) (func() error, error) {
+ return func() error { return nil }, nil
+}
diff --git a/vendor/github.com/muesli/termenv/termenv_posix.go b/vendor/github.com/muesli/termenv/termenv_posix.go
new file mode 100644
index 0000000..b2109b7
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/termenv_posix.go
@@ -0,0 +1,17 @@
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd
+
+package termenv
+
+import (
+ "golang.org/x/sys/unix"
+)
+
+func isForeground(fd int) bool {
+ pgrp, err := unix.IoctlGetInt(fd, unix.TIOCGPGRP)
+ if err != nil {
+ return false
+ }
+
+ return pgrp == unix.Getpgrp()
+}
diff --git a/vendor/github.com/muesli/termenv/termenv_solaris.go b/vendor/github.com/muesli/termenv/termenv_solaris.go
new file mode 100644
index 0000000..27a95a9
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/termenv_solaris.go
@@ -0,0 +1,22 @@
+//go:build solaris || illumos
+// +build solaris illumos
+
+package termenv
+
+import (
+ "golang.org/x/sys/unix"
+)
+
+func isForeground(fd int) bool {
+ pgrp, err := unix.IoctlGetInt(fd, unix.TIOCGPGRP)
+ if err != nil {
+ return false
+ }
+
+ g, err := unix.Getpgrp()
+ if err != nil {
+ return false
+ }
+
+ return pgrp == g
+}
diff --git a/vendor/github.com/muesli/termenv/termenv_unix.go b/vendor/github.com/muesli/termenv/termenv_unix.go
new file mode 100644
index 0000000..24d519a
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/termenv_unix.go
@@ -0,0 +1,293 @@
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package termenv
+
+import (
+ "fmt"
+ "io"
+ "strconv"
+ "strings"
+ "time"
+
+ "golang.org/x/sys/unix"
+)
+
+const (
+ // timeout for OSC queries
+ OSCTimeout = 5 * time.Second
+)
+
+// ColorProfile returns the supported color profile:
+// Ascii, ANSI, ANSI256, or TrueColor.
+func (o *Output) ColorProfile() Profile {
+ if !o.isTTY() {
+ return Ascii
+ }
+
+ if o.environ.Getenv("GOOGLE_CLOUD_SHELL") == "true" {
+ return TrueColor
+ }
+
+ term := o.environ.Getenv("TERM")
+ colorTerm := o.environ.Getenv("COLORTERM")
+
+ switch strings.ToLower(colorTerm) {
+ case "24bit":
+ fallthrough
+ case "truecolor":
+ if strings.HasPrefix(term, "screen") {
+ // tmux supports TrueColor, screen only ANSI256
+ if o.environ.Getenv("TERM_PROGRAM") != "tmux" {
+ return ANSI256
+ }
+ }
+ return TrueColor
+ case "yes":
+ fallthrough
+ case "true":
+ return ANSI256
+ }
+
+ switch term {
+ case "xterm-kitty", "wezterm":
+ return TrueColor
+ case "linux":
+ return ANSI
+ }
+
+ if strings.Contains(term, "256color") {
+ return ANSI256
+ }
+ if strings.Contains(term, "color") {
+ return ANSI
+ }
+ if strings.Contains(term, "ansi") {
+ return ANSI
+ }
+
+ return Ascii
+}
+
+func (o Output) foregroundColor() Color {
+ s, err := o.termStatusReport(10)
+ if err == nil {
+ c, err := xTermColor(s)
+ if err == nil {
+ return c
+ }
+ }
+
+ colorFGBG := o.environ.Getenv("COLORFGBG")
+ if strings.Contains(colorFGBG, ";") {
+ c := strings.Split(colorFGBG, ";")
+ i, err := strconv.Atoi(c[0])
+ if err == nil {
+ return ANSIColor(i)
+ }
+ }
+
+ // default gray
+ return ANSIColor(7)
+}
+
+func (o Output) backgroundColor() Color {
+ s, err := o.termStatusReport(11)
+ if err == nil {
+ c, err := xTermColor(s)
+ if err == nil {
+ return c
+ }
+ }
+
+ colorFGBG := o.environ.Getenv("COLORFGBG")
+ if strings.Contains(colorFGBG, ";") {
+ c := strings.Split(colorFGBG, ";")
+ i, err := strconv.Atoi(c[len(c)-1])
+ if err == nil {
+ return ANSIColor(i)
+ }
+ }
+
+ // default black
+ return ANSIColor(0)
+}
+
+func (o *Output) waitForData(timeout time.Duration) error {
+ fd := o.TTY().Fd()
+ tv := unix.NsecToTimeval(int64(timeout))
+ var readfds unix.FdSet
+ readfds.Set(int(fd))
+
+ for {
+ n, err := unix.Select(int(fd)+1, &readfds, nil, nil, &tv)
+ if err == unix.EINTR {
+ continue
+ }
+ if err != nil {
+ return err
+ }
+ if n == 0 {
+ return fmt.Errorf("timeout")
+ }
+
+ break
+ }
+
+ return nil
+}
+
+func (o *Output) readNextByte() (byte, error) {
+ if !o.unsafe {
+ if err := o.waitForData(OSCTimeout); err != nil {
+ return 0, err
+ }
+ }
+
+ var b [1]byte
+ n, err := o.TTY().Read(b[:])
+ if err != nil {
+ return 0, err
+ }
+
+ if n == 0 {
+ panic("read returned no data")
+ }
+
+ return b[0], nil
+}
+
+// readNextResponse reads either an OSC response or a cursor position response:
+// - OSC response: "\x1b]11;rgb:1111/1111/1111\x1b\\"
+// - cursor position response: "\x1b[42;1R"
+func (o *Output) readNextResponse() (response string, isOSC bool, err error) {
+ start, err := o.readNextByte()
+ if err != nil {
+ return "", false, err
+ }
+
+ // first byte must be ESC
+ for start != ESC {
+ start, err = o.readNextByte()
+ if err != nil {
+ return "", false, err
+ }
+ }
+
+ response += string(start)
+
+ // next byte is either '[' (cursor position response) or ']' (OSC response)
+ tpe, err := o.readNextByte()
+ if err != nil {
+ return "", false, err
+ }
+
+ response += string(tpe)
+
+ var oscResponse bool
+ switch tpe {
+ case '[':
+ oscResponse = false
+ case ']':
+ oscResponse = true
+ default:
+ return "", false, ErrStatusReport
+ }
+
+ for {
+ b, err := o.readNextByte()
+ if err != nil {
+ return "", false, err
+ }
+
+ response += string(b)
+
+ if oscResponse {
+ // OSC can be terminated by BEL (\a) or ST (ESC)
+ if b == BEL || strings.HasSuffix(response, string(ESC)) {
+ return response, true, nil
+ }
+ } else {
+ // cursor position response is terminated by 'R'
+ if b == 'R' {
+ return response, false, nil
+ }
+ }
+
+ // both responses have less than 25 bytes, so if we read more, that's an error
+ if len(response) > 25 {
+ break
+ }
+ }
+
+ return "", false, ErrStatusReport
+}
+
+func (o Output) termStatusReport(sequence int) (string, error) {
+ // screen/tmux can't support OSC, because they can be connected to multiple
+ // terminals concurrently.
+ term := o.environ.Getenv("TERM")
+ if strings.HasPrefix(term, "screen") || strings.HasPrefix(term, "tmux") {
+ return "", ErrStatusReport
+ }
+
+ tty := o.TTY()
+ if tty == nil {
+ return "", ErrStatusReport
+ }
+
+ if !o.unsafe {
+ fd := int(tty.Fd())
+ // if in background, we can't control the terminal
+ if !isForeground(fd) {
+ return "", ErrStatusReport
+ }
+
+ t, err := unix.IoctlGetTermios(fd, tcgetattr)
+ if err != nil {
+ return "", fmt.Errorf("%s: %s", ErrStatusReport, err)
+ }
+ defer unix.IoctlSetTermios(fd, tcsetattr, t) //nolint:errcheck
+
+ noecho := *t
+ noecho.Lflag = noecho.Lflag &^ unix.ECHO
+ noecho.Lflag = noecho.Lflag &^ unix.ICANON
+ if err := unix.IoctlSetTermios(fd, tcsetattr, &noecho); err != nil {
+ return "", fmt.Errorf("%s: %s", ErrStatusReport, err)
+ }
+ }
+
+ // first, send OSC query, which is ignored by terminal which do not support it
+ fmt.Fprintf(tty, OSC+"%d;?"+ST, sequence)
+
+ // then, query cursor position, should be supported by all terminals
+ fmt.Fprintf(tty, CSI+"6n")
+
+ // read the next response
+ res, isOSC, err := o.readNextResponse()
+ if err != nil {
+ return "", fmt.Errorf("%s: %s", ErrStatusReport, err)
+ }
+
+ // if this is not OSC response, then the terminal does not support it
+ if !isOSC {
+ return "", ErrStatusReport
+ }
+
+ // read the cursor query response next and discard the result
+ _, _, err = o.readNextResponse()
+ if err != nil {
+ return "", err
+ }
+
+ // fmt.Println("Rcvd", res[1:])
+ return res, nil
+}
+
+// EnableVirtualTerminalProcessing enables virtual terminal processing on
+// Windows for w and returns a function that restores w to its previous state.
+// On non-Windows platforms, or if w does not refer to a terminal, then it
+// returns a non-nil no-op function and no error.
+func EnableVirtualTerminalProcessing(_ io.Writer) (func() error, error) {
+ return func() error { return nil }, nil
+}
diff --git a/vendor/github.com/muesli/termenv/termenv_windows.go b/vendor/github.com/muesli/termenv/termenv_windows.go
new file mode 100644
index 0000000..1d9c618
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/termenv_windows.go
@@ -0,0 +1,139 @@
+//go:build windows
+// +build windows
+
+package termenv
+
+import (
+ "fmt"
+ "strconv"
+
+ "golang.org/x/sys/windows"
+)
+
+func (o *Output) ColorProfile() Profile {
+ if !o.isTTY() {
+ return Ascii
+ }
+
+ if o.environ.Getenv("ConEmuANSI") == "ON" {
+ return TrueColor
+ }
+
+ winVersion, _, buildNumber := windows.RtlGetNtVersionNumbers()
+ if buildNumber < 10586 || winVersion < 10 {
+ // No ANSI support before Windows 10 build 10586.
+ if o.environ.Getenv("ANSICON") != "" {
+ conVersion := o.environ.Getenv("ANSICON_VER")
+ cv, err := strconv.ParseInt(conVersion, 10, 64)
+ if err != nil || cv < 181 {
+ // No 8 bit color support before v1.81 release.
+ return ANSI
+ }
+
+ return ANSI256
+ }
+
+ return Ascii
+ }
+ if buildNumber < 14931 {
+ // No true color support before build 14931.
+ return ANSI256
+ }
+
+ return TrueColor
+}
+
+func (o Output) foregroundColor() Color {
+ // default gray
+ return ANSIColor(7)
+}
+
+func (o Output) backgroundColor() Color {
+ // default black
+ return ANSIColor(0)
+}
+
+// EnableWindowsANSIConsole enables virtual terminal processing on Windows
+// platforms. This allows the use of ANSI escape sequences in Windows console
+// applications. Ensure this gets called before anything gets rendered with
+// termenv.
+//
+// Returns the original console mode and an error if one occurred.
+func EnableWindowsANSIConsole() (uint32, error) {
+ handle, err := windows.GetStdHandle(windows.STD_OUTPUT_HANDLE)
+ if err != nil {
+ return 0, err
+ }
+
+ var mode uint32
+ err = windows.GetConsoleMode(handle, &mode)
+ if err != nil {
+ return 0, err
+ }
+
+ // See https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
+ if mode&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING {
+ vtpmode := mode | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
+ if err := windows.SetConsoleMode(handle, vtpmode); err != nil {
+ return 0, err
+ }
+ }
+
+ return mode, nil
+}
+
+// RestoreWindowsConsole restores the console mode to a previous state.
+func RestoreWindowsConsole(mode uint32) error {
+ handle, err := windows.GetStdHandle(windows.STD_OUTPUT_HANDLE)
+ if err != nil {
+ return err
+ }
+
+ return windows.SetConsoleMode(handle, mode)
+}
+
+// EnableVirtualTerminalProcessing enables virtual terminal processing on
+// Windows for o and returns a function that restores o to its previous state.
+// On non-Windows platforms, or if o does not refer to a terminal, then it
+// returns a non-nil no-op function and no error.
+func EnableVirtualTerminalProcessing(o *Output) (restoreFunc func() error, err error) {
+ // There is nothing to restore until we set the console mode.
+ restoreFunc = func() error {
+ return nil
+ }
+
+ // If o is not a tty, then there is nothing to do.
+ tty := o.TTY()
+ if tty == nil {
+ return
+ }
+
+ // Get the current console mode. If there is an error, assume that o is not
+ // a terminal, discard the error, and return.
+ var mode uint32
+ if err2 := windows.GetConsoleMode(windows.Handle(tty.Fd()), &mode); err2 != nil {
+ return
+ }
+
+ // If virtual terminal processing is already set, then there is nothing to
+ // do and nothing to restore.
+ if mode&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING == windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING {
+ return
+ }
+
+ // Enable virtual terminal processing. See
+ // https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
+ if err2 := windows.SetConsoleMode(windows.Handle(tty.Fd()), mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err2 != nil {
+ err = fmt.Errorf("windows.SetConsoleMode: %w", err2)
+ return
+ }
+
+ // Set the restore function. We maintain a reference to the tty in the
+ // closure (rather than just its handle) to ensure that the tty is not
+ // closed by a finalizer.
+ restoreFunc = func() error {
+ return windows.SetConsoleMode(windows.Handle(tty.Fd()), mode)
+ }
+
+ return
+}
diff --git a/vendor/github.com/nfnt/resize/.travis.yml b/vendor/github.com/nfnt/resize/.travis.yml
new file mode 100644
index 0000000..5ff08e7
--- /dev/null
+++ b/vendor/github.com/nfnt/resize/.travis.yml
@@ -0,0 +1,7 @@
+language: go
+
+go:
+ - "1.x"
+ - "1.1"
+ - "1.4"
+ - "1.10"
diff --git a/vendor/github.com/nfnt/resize/LICENSE b/vendor/github.com/nfnt/resize/LICENSE
new file mode 100644
index 0000000..7836cad
--- /dev/null
+++ b/vendor/github.com/nfnt/resize/LICENSE
@@ -0,0 +1,13 @@
+Copyright (c) 2012, Jan Schlicht
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/vendor/github.com/nfnt/resize/README.md b/vendor/github.com/nfnt/resize/README.md
new file mode 100644
index 0000000..372777d
--- /dev/null
+++ b/vendor/github.com/nfnt/resize/README.md
@@ -0,0 +1,151 @@
+# This package is no longer being updated! Please look for alternatives if that bothers you.
+
+Resize
+======
+
+Image resizing for the [Go programming language](http://golang.org) with common interpolation methods.
+
+[](https://travis-ci.org/nfnt/resize)
+
+Installation
+------------
+
+```bash
+$ go get github.com/nfnt/resize
+```
+
+It's that easy!
+
+Usage
+-----
+
+This package needs at least Go 1.1. Import package with
+
+```go
+import "github.com/nfnt/resize"
+```
+
+The resize package provides 2 functions:
+
+* `resize.Resize` creates a scaled image with new dimensions (`width`, `height`) using the interpolation function `interp`.
+ If either `width` or `height` is set to 0, it will be set to an aspect ratio preserving value.
+* `resize.Thumbnail` downscales an image preserving its aspect ratio to the maximum dimensions (`maxWidth`, `maxHeight`).
+ It will return the original image if original sizes are smaller than the provided dimensions.
+
+```go
+resize.Resize(width, height uint, img image.Image, interp resize.InterpolationFunction) image.Image
+resize.Thumbnail(maxWidth, maxHeight uint, img image.Image, interp resize.InterpolationFunction) image.Image
+```
+
+The provided interpolation functions are (from fast to slow execution time)
+
+- `NearestNeighbor`: [Nearest-neighbor interpolation](http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation)
+- `Bilinear`: [Bilinear interpolation](http://en.wikipedia.org/wiki/Bilinear_interpolation)
+- `Bicubic`: [Bicubic interpolation](http://en.wikipedia.org/wiki/Bicubic_interpolation)
+- `MitchellNetravali`: [Mitchell-Netravali interpolation](http://dl.acm.org/citation.cfm?id=378514)
+- `Lanczos2`: [Lanczos resampling](http://en.wikipedia.org/wiki/Lanczos_resampling) with a=2
+- `Lanczos3`: [Lanczos resampling](http://en.wikipedia.org/wiki/Lanczos_resampling) with a=3
+
+Which of these methods gives the best results depends on your use case.
+
+Sample usage:
+
+```go
+package main
+
+import (
+ "github.com/nfnt/resize"
+ "image/jpeg"
+ "log"
+ "os"
+)
+
+func main() {
+ // open "test.jpg"
+ file, err := os.Open("test.jpg")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // decode jpeg into image.Image
+ img, err := jpeg.Decode(file)
+ if err != nil {
+ log.Fatal(err)
+ }
+ file.Close()
+
+ // resize to width 1000 using Lanczos resampling
+ // and preserve aspect ratio
+ m := resize.Resize(1000, 0, img, resize.Lanczos3)
+
+ out, err := os.Create("test_resized.jpg")
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer out.Close()
+
+ // write new image to file
+ jpeg.Encode(out, m, nil)
+}
+```
+
+Caveats
+-------
+
+* Optimized access routines are used for `image.RGBA`, `image.NRGBA`, `image.RGBA64`, `image.NRGBA64`, `image.YCbCr`, `image.Gray`, and `image.Gray16` types. All other image types are accessed in a generic way that will result in slow processing speed.
+* JPEG images are stored in `image.YCbCr`. This image format stores data in a way that will decrease processing speed. A resize may be up to 2 times slower than with `image.RGBA`.
+
+
+Downsizing Samples
+-------
+
+Downsizing is not as simple as it might look like. Images have to be filtered before they are scaled down, otherwise aliasing might occur.
+Filtering is highly subjective: Applying too much will blur the whole image, too little will make aliasing become apparent.
+Resize tries to provide sane defaults that should suffice in most cases.
+
+### Artificial sample
+
+Original image
+
+
+
+
+
Nearest-Neighbor
+
Bilinear
+
+
+
Bicubic
+
Mitchell-Netravali
+
+
+
Lanczos2
+
Lanczos3
+
+
+
+### Real-Life sample
+
+Original image
+
+
+
+
+
Nearest-Neighbor
+
Bilinear
+
+
+
Bicubic
+
Mitchell-Netravali
+
+
+
Lanczos2
+
Lanczos3
+
+
+
+
+License
+-------
+
+Copyright (c) 2012 Jan Schlicht
+Resize is released under a MIT style license.
diff --git a/vendor/github.com/nfnt/resize/converter.go b/vendor/github.com/nfnt/resize/converter.go
new file mode 100644
index 0000000..f9c520d
--- /dev/null
+++ b/vendor/github.com/nfnt/resize/converter.go
@@ -0,0 +1,438 @@
+/*
+Copyright (c) 2012, Jan Schlicht
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+*/
+
+package resize
+
+import "image"
+
+// Keep value in [0,255] range.
+func clampUint8(in int32) uint8 {
+ // casting a negative int to an uint will result in an overflown
+ // large uint. this behavior will be exploited here and in other functions
+ // to achieve a higher performance.
+ if uint32(in) < 256 {
+ return uint8(in)
+ }
+ if in > 255 {
+ return 255
+ }
+ return 0
+}
+
+// Keep value in [0,65535] range.
+func clampUint16(in int64) uint16 {
+ if uint64(in) < 65536 {
+ return uint16(in)
+ }
+ if in > 65535 {
+ return 65535
+ }
+ return 0
+}
+
+func resizeGeneric(in image.Image, out *image.RGBA64, scale float64, coeffs []int32, offset []int, filterLength int) {
+ newBounds := out.Bounds()
+ maxX := in.Bounds().Dx() - 1
+
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
+ var rgba [4]int64
+ var sum int64
+ start := offset[y]
+ ci := y * filterLength
+ for i := 0; i < filterLength; i++ {
+ coeff := coeffs[ci+i]
+ if coeff != 0 {
+ xi := start + i
+ switch {
+ case xi < 0:
+ xi = 0
+ case xi >= maxX:
+ xi = maxX
+ }
+
+ r, g, b, a := in.At(xi+in.Bounds().Min.X, x+in.Bounds().Min.Y).RGBA()
+
+ rgba[0] += int64(coeff) * int64(r)
+ rgba[1] += int64(coeff) * int64(g)
+ rgba[2] += int64(coeff) * int64(b)
+ rgba[3] += int64(coeff) * int64(a)
+ sum += int64(coeff)
+ }
+ }
+
+ offset := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*8
+
+ value := clampUint16(rgba[0] / sum)
+ out.Pix[offset+0] = uint8(value >> 8)
+ out.Pix[offset+1] = uint8(value)
+ value = clampUint16(rgba[1] / sum)
+ out.Pix[offset+2] = uint8(value >> 8)
+ out.Pix[offset+3] = uint8(value)
+ value = clampUint16(rgba[2] / sum)
+ out.Pix[offset+4] = uint8(value >> 8)
+ out.Pix[offset+5] = uint8(value)
+ value = clampUint16(rgba[3] / sum)
+ out.Pix[offset+6] = uint8(value >> 8)
+ out.Pix[offset+7] = uint8(value)
+ }
+ }
+}
+
+func resizeRGBA(in *image.RGBA, out *image.RGBA, scale float64, coeffs []int16, offset []int, filterLength int) {
+ newBounds := out.Bounds()
+ maxX := in.Bounds().Dx() - 1
+
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
+ row := in.Pix[x*in.Stride:]
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
+ var rgba [4]int32
+ var sum int32
+ start := offset[y]
+ ci := y * filterLength
+ for i := 0; i < filterLength; i++ {
+ coeff := coeffs[ci+i]
+ if coeff != 0 {
+ xi := start + i
+ switch {
+ case uint(xi) < uint(maxX):
+ xi *= 4
+ case xi >= maxX:
+ xi = 4 * maxX
+ default:
+ xi = 0
+ }
+
+ rgba[0] += int32(coeff) * int32(row[xi+0])
+ rgba[1] += int32(coeff) * int32(row[xi+1])
+ rgba[2] += int32(coeff) * int32(row[xi+2])
+ rgba[3] += int32(coeff) * int32(row[xi+3])
+ sum += int32(coeff)
+ }
+ }
+
+ xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*4
+
+ out.Pix[xo+0] = clampUint8(rgba[0] / sum)
+ out.Pix[xo+1] = clampUint8(rgba[1] / sum)
+ out.Pix[xo+2] = clampUint8(rgba[2] / sum)
+ out.Pix[xo+3] = clampUint8(rgba[3] / sum)
+ }
+ }
+}
+
+func resizeNRGBA(in *image.NRGBA, out *image.RGBA, scale float64, coeffs []int16, offset []int, filterLength int) {
+ newBounds := out.Bounds()
+ maxX := in.Bounds().Dx() - 1
+
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
+ row := in.Pix[x*in.Stride:]
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
+ var rgba [4]int32
+ var sum int32
+ start := offset[y]
+ ci := y * filterLength
+ for i := 0; i < filterLength; i++ {
+ coeff := coeffs[ci+i]
+ if coeff != 0 {
+ xi := start + i
+ switch {
+ case uint(xi) < uint(maxX):
+ xi *= 4
+ case xi >= maxX:
+ xi = 4 * maxX
+ default:
+ xi = 0
+ }
+
+ // Forward alpha-premultiplication
+ a := int32(row[xi+3])
+ r := int32(row[xi+0]) * a
+ r /= 0xff
+ g := int32(row[xi+1]) * a
+ g /= 0xff
+ b := int32(row[xi+2]) * a
+ b /= 0xff
+
+ rgba[0] += int32(coeff) * r
+ rgba[1] += int32(coeff) * g
+ rgba[2] += int32(coeff) * b
+ rgba[3] += int32(coeff) * a
+ sum += int32(coeff)
+ }
+ }
+
+ xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*4
+
+ out.Pix[xo+0] = clampUint8(rgba[0] / sum)
+ out.Pix[xo+1] = clampUint8(rgba[1] / sum)
+ out.Pix[xo+2] = clampUint8(rgba[2] / sum)
+ out.Pix[xo+3] = clampUint8(rgba[3] / sum)
+ }
+ }
+}
+
+func resizeRGBA64(in *image.RGBA64, out *image.RGBA64, scale float64, coeffs []int32, offset []int, filterLength int) {
+ newBounds := out.Bounds()
+ maxX := in.Bounds().Dx() - 1
+
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
+ row := in.Pix[x*in.Stride:]
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
+ var rgba [4]int64
+ var sum int64
+ start := offset[y]
+ ci := y * filterLength
+ for i := 0; i < filterLength; i++ {
+ coeff := coeffs[ci+i]
+ if coeff != 0 {
+ xi := start + i
+ switch {
+ case uint(xi) < uint(maxX):
+ xi *= 8
+ case xi >= maxX:
+ xi = 8 * maxX
+ default:
+ xi = 0
+ }
+
+ rgba[0] += int64(coeff) * (int64(row[xi+0])<<8 | int64(row[xi+1]))
+ rgba[1] += int64(coeff) * (int64(row[xi+2])<<8 | int64(row[xi+3]))
+ rgba[2] += int64(coeff) * (int64(row[xi+4])<<8 | int64(row[xi+5]))
+ rgba[3] += int64(coeff) * (int64(row[xi+6])<<8 | int64(row[xi+7]))
+ sum += int64(coeff)
+ }
+ }
+
+ xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*8
+
+ value := clampUint16(rgba[0] / sum)
+ out.Pix[xo+0] = uint8(value >> 8)
+ out.Pix[xo+1] = uint8(value)
+ value = clampUint16(rgba[1] / sum)
+ out.Pix[xo+2] = uint8(value >> 8)
+ out.Pix[xo+3] = uint8(value)
+ value = clampUint16(rgba[2] / sum)
+ out.Pix[xo+4] = uint8(value >> 8)
+ out.Pix[xo+5] = uint8(value)
+ value = clampUint16(rgba[3] / sum)
+ out.Pix[xo+6] = uint8(value >> 8)
+ out.Pix[xo+7] = uint8(value)
+ }
+ }
+}
+
+func resizeNRGBA64(in *image.NRGBA64, out *image.RGBA64, scale float64, coeffs []int32, offset []int, filterLength int) {
+ newBounds := out.Bounds()
+ maxX := in.Bounds().Dx() - 1
+
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
+ row := in.Pix[x*in.Stride:]
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
+ var rgba [4]int64
+ var sum int64
+ start := offset[y]
+ ci := y * filterLength
+ for i := 0; i < filterLength; i++ {
+ coeff := coeffs[ci+i]
+ if coeff != 0 {
+ xi := start + i
+ switch {
+ case uint(xi) < uint(maxX):
+ xi *= 8
+ case xi >= maxX:
+ xi = 8 * maxX
+ default:
+ xi = 0
+ }
+
+ // Forward alpha-premultiplication
+ a := int64(uint16(row[xi+6])<<8 | uint16(row[xi+7]))
+ r := int64(uint16(row[xi+0])<<8|uint16(row[xi+1])) * a
+ r /= 0xffff
+ g := int64(uint16(row[xi+2])<<8|uint16(row[xi+3])) * a
+ g /= 0xffff
+ b := int64(uint16(row[xi+4])<<8|uint16(row[xi+5])) * a
+ b /= 0xffff
+
+ rgba[0] += int64(coeff) * r
+ rgba[1] += int64(coeff) * g
+ rgba[2] += int64(coeff) * b
+ rgba[3] += int64(coeff) * a
+ sum += int64(coeff)
+ }
+ }
+
+ xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*8
+
+ value := clampUint16(rgba[0] / sum)
+ out.Pix[xo+0] = uint8(value >> 8)
+ out.Pix[xo+1] = uint8(value)
+ value = clampUint16(rgba[1] / sum)
+ out.Pix[xo+2] = uint8(value >> 8)
+ out.Pix[xo+3] = uint8(value)
+ value = clampUint16(rgba[2] / sum)
+ out.Pix[xo+4] = uint8(value >> 8)
+ out.Pix[xo+5] = uint8(value)
+ value = clampUint16(rgba[3] / sum)
+ out.Pix[xo+6] = uint8(value >> 8)
+ out.Pix[xo+7] = uint8(value)
+ }
+ }
+}
+
+func resizeGray(in *image.Gray, out *image.Gray, scale float64, coeffs []int16, offset []int, filterLength int) {
+ newBounds := out.Bounds()
+ maxX := in.Bounds().Dx() - 1
+
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
+ row := in.Pix[(x-newBounds.Min.X)*in.Stride:]
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
+ var gray int32
+ var sum int32
+ start := offset[y]
+ ci := y * filterLength
+ for i := 0; i < filterLength; i++ {
+ coeff := coeffs[ci+i]
+ if coeff != 0 {
+ xi := start + i
+ switch {
+ case xi < 0:
+ xi = 0
+ case xi >= maxX:
+ xi = maxX
+ }
+ gray += int32(coeff) * int32(row[xi])
+ sum += int32(coeff)
+ }
+ }
+
+ offset := (y-newBounds.Min.Y)*out.Stride + (x - newBounds.Min.X)
+ out.Pix[offset] = clampUint8(gray / sum)
+ }
+ }
+}
+
+func resizeGray16(in *image.Gray16, out *image.Gray16, scale float64, coeffs []int32, offset []int, filterLength int) {
+ newBounds := out.Bounds()
+ maxX := in.Bounds().Dx() - 1
+
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
+ row := in.Pix[x*in.Stride:]
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
+ var gray int64
+ var sum int64
+ start := offset[y]
+ ci := y * filterLength
+ for i := 0; i < filterLength; i++ {
+ coeff := coeffs[ci+i]
+ if coeff != 0 {
+ xi := start + i
+ switch {
+ case uint(xi) < uint(maxX):
+ xi *= 2
+ case xi >= maxX:
+ xi = 2 * maxX
+ default:
+ xi = 0
+ }
+ gray += int64(coeff) * int64(uint16(row[xi+0])<<8|uint16(row[xi+1]))
+ sum += int64(coeff)
+ }
+ }
+
+ offset := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*2
+ value := clampUint16(gray / sum)
+ out.Pix[offset+0] = uint8(value >> 8)
+ out.Pix[offset+1] = uint8(value)
+ }
+ }
+}
+
+func resizeYCbCr(in *ycc, out *ycc, scale float64, coeffs []int16, offset []int, filterLength int) {
+ newBounds := out.Bounds()
+ maxX := in.Bounds().Dx() - 1
+
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
+ row := in.Pix[x*in.Stride:]
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
+ var p [3]int32
+ var sum int32
+ start := offset[y]
+ ci := y * filterLength
+ for i := 0; i < filterLength; i++ {
+ coeff := coeffs[ci+i]
+ if coeff != 0 {
+ xi := start + i
+ switch {
+ case uint(xi) < uint(maxX):
+ xi *= 3
+ case xi >= maxX:
+ xi = 3 * maxX
+ default:
+ xi = 0
+ }
+ p[0] += int32(coeff) * int32(row[xi+0])
+ p[1] += int32(coeff) * int32(row[xi+1])
+ p[2] += int32(coeff) * int32(row[xi+2])
+ sum += int32(coeff)
+ }
+ }
+
+ xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*3
+ out.Pix[xo+0] = clampUint8(p[0] / sum)
+ out.Pix[xo+1] = clampUint8(p[1] / sum)
+ out.Pix[xo+2] = clampUint8(p[2] / sum)
+ }
+ }
+}
+
+func nearestYCbCr(in *ycc, out *ycc, scale float64, coeffs []bool, offset []int, filterLength int) {
+ newBounds := out.Bounds()
+ maxX := in.Bounds().Dx() - 1
+
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
+ row := in.Pix[x*in.Stride:]
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
+ var p [3]float32
+ var sum float32
+ start := offset[y]
+ ci := y * filterLength
+ for i := 0; i < filterLength; i++ {
+ if coeffs[ci+i] {
+ xi := start + i
+ switch {
+ case uint(xi) < uint(maxX):
+ xi *= 3
+ case xi >= maxX:
+ xi = 3 * maxX
+ default:
+ xi = 0
+ }
+ p[0] += float32(row[xi+0])
+ p[1] += float32(row[xi+1])
+ p[2] += float32(row[xi+2])
+ sum++
+ }
+ }
+
+ xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*3
+ out.Pix[xo+0] = floatToUint8(p[0] / sum)
+ out.Pix[xo+1] = floatToUint8(p[1] / sum)
+ out.Pix[xo+2] = floatToUint8(p[2] / sum)
+ }
+ }
+}
diff --git a/vendor/github.com/nfnt/resize/filters.go b/vendor/github.com/nfnt/resize/filters.go
new file mode 100644
index 0000000..4ce04e3
--- /dev/null
+++ b/vendor/github.com/nfnt/resize/filters.go
@@ -0,0 +1,143 @@
+/*
+Copyright (c) 2012, Jan Schlicht
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+*/
+
+package resize
+
+import (
+ "math"
+)
+
+func nearest(in float64) float64 {
+ if in >= -0.5 && in < 0.5 {
+ return 1
+ }
+ return 0
+}
+
+func linear(in float64) float64 {
+ in = math.Abs(in)
+ if in <= 1 {
+ return 1 - in
+ }
+ return 0
+}
+
+func cubic(in float64) float64 {
+ in = math.Abs(in)
+ if in <= 1 {
+ return in*in*(1.5*in-2.5) + 1.0
+ }
+ if in <= 2 {
+ return in*(in*(2.5-0.5*in)-4.0) + 2.0
+ }
+ return 0
+}
+
+func mitchellnetravali(in float64) float64 {
+ in = math.Abs(in)
+ if in <= 1 {
+ return (7.0*in*in*in - 12.0*in*in + 5.33333333333) * 0.16666666666
+ }
+ if in <= 2 {
+ return (-2.33333333333*in*in*in + 12.0*in*in - 20.0*in + 10.6666666667) * 0.16666666666
+ }
+ return 0
+}
+
+func sinc(x float64) float64 {
+ x = math.Abs(x) * math.Pi
+ if x >= 1.220703e-4 {
+ return math.Sin(x) / x
+ }
+ return 1
+}
+
+func lanczos2(in float64) float64 {
+ if in > -2 && in < 2 {
+ return sinc(in) * sinc(in*0.5)
+ }
+ return 0
+}
+
+func lanczos3(in float64) float64 {
+ if in > -3 && in < 3 {
+ return sinc(in) * sinc(in*0.3333333333333333)
+ }
+ return 0
+}
+
+// range [-256,256]
+func createWeights8(dy, filterLength int, blur, scale float64, kernel func(float64) float64) ([]int16, []int, int) {
+ filterLength = filterLength * int(math.Max(math.Ceil(blur*scale), 1))
+ filterFactor := math.Min(1./(blur*scale), 1)
+
+ coeffs := make([]int16, dy*filterLength)
+ start := make([]int, dy)
+ for y := 0; y < dy; y++ {
+ interpX := scale*(float64(y)+0.5) - 0.5
+ start[y] = int(interpX) - filterLength/2 + 1
+ interpX -= float64(start[y])
+ for i := 0; i < filterLength; i++ {
+ in := (interpX - float64(i)) * filterFactor
+ coeffs[y*filterLength+i] = int16(kernel(in) * 256)
+ }
+ }
+
+ return coeffs, start, filterLength
+}
+
+// range [-65536,65536]
+func createWeights16(dy, filterLength int, blur, scale float64, kernel func(float64) float64) ([]int32, []int, int) {
+ filterLength = filterLength * int(math.Max(math.Ceil(blur*scale), 1))
+ filterFactor := math.Min(1./(blur*scale), 1)
+
+ coeffs := make([]int32, dy*filterLength)
+ start := make([]int, dy)
+ for y := 0; y < dy; y++ {
+ interpX := scale*(float64(y)+0.5) - 0.5
+ start[y] = int(interpX) - filterLength/2 + 1
+ interpX -= float64(start[y])
+ for i := 0; i < filterLength; i++ {
+ in := (interpX - float64(i)) * filterFactor
+ coeffs[y*filterLength+i] = int32(kernel(in) * 65536)
+ }
+ }
+
+ return coeffs, start, filterLength
+}
+
+func createWeightsNearest(dy, filterLength int, blur, scale float64) ([]bool, []int, int) {
+ filterLength = filterLength * int(math.Max(math.Ceil(blur*scale), 1))
+ filterFactor := math.Min(1./(blur*scale), 1)
+
+ coeffs := make([]bool, dy*filterLength)
+ start := make([]int, dy)
+ for y := 0; y < dy; y++ {
+ interpX := scale*(float64(y)+0.5) - 0.5
+ start[y] = int(interpX) - filterLength/2 + 1
+ interpX -= float64(start[y])
+ for i := 0; i < filterLength; i++ {
+ in := (interpX - float64(i)) * filterFactor
+ if in >= -0.5 && in < 0.5 {
+ coeffs[y*filterLength+i] = true
+ } else {
+ coeffs[y*filterLength+i] = false
+ }
+ }
+ }
+
+ return coeffs, start, filterLength
+}
diff --git a/vendor/github.com/nfnt/resize/nearest.go b/vendor/github.com/nfnt/resize/nearest.go
new file mode 100644
index 0000000..888039d
--- /dev/null
+++ b/vendor/github.com/nfnt/resize/nearest.go
@@ -0,0 +1,318 @@
+/*
+Copyright (c) 2014, Charlie Vieth
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+*/
+
+package resize
+
+import "image"
+
+func floatToUint8(x float32) uint8 {
+ // Nearest-neighbor values are always
+ // positive no need to check lower-bound.
+ if x > 0xfe {
+ return 0xff
+ }
+ return uint8(x)
+}
+
+func floatToUint16(x float32) uint16 {
+ if x > 0xfffe {
+ return 0xffff
+ }
+ return uint16(x)
+}
+
+func nearestGeneric(in image.Image, out *image.RGBA64, scale float64, coeffs []bool, offset []int, filterLength int) {
+ newBounds := out.Bounds()
+ maxX := in.Bounds().Dx() - 1
+
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
+ var rgba [4]float32
+ var sum float32
+ start := offset[y]
+ ci := y * filterLength
+ for i := 0; i < filterLength; i++ {
+ if coeffs[ci+i] {
+ xi := start + i
+ switch {
+ case xi < 0:
+ xi = 0
+ case xi >= maxX:
+ xi = maxX
+ }
+ r, g, b, a := in.At(xi+in.Bounds().Min.X, x+in.Bounds().Min.Y).RGBA()
+ rgba[0] += float32(r)
+ rgba[1] += float32(g)
+ rgba[2] += float32(b)
+ rgba[3] += float32(a)
+ sum++
+ }
+ }
+
+ offset := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*8
+ value := floatToUint16(rgba[0] / sum)
+ out.Pix[offset+0] = uint8(value >> 8)
+ out.Pix[offset+1] = uint8(value)
+ value = floatToUint16(rgba[1] / sum)
+ out.Pix[offset+2] = uint8(value >> 8)
+ out.Pix[offset+3] = uint8(value)
+ value = floatToUint16(rgba[2] / sum)
+ out.Pix[offset+4] = uint8(value >> 8)
+ out.Pix[offset+5] = uint8(value)
+ value = floatToUint16(rgba[3] / sum)
+ out.Pix[offset+6] = uint8(value >> 8)
+ out.Pix[offset+7] = uint8(value)
+ }
+ }
+}
+
+func nearestRGBA(in *image.RGBA, out *image.RGBA, scale float64, coeffs []bool, offset []int, filterLength int) {
+ newBounds := out.Bounds()
+ maxX := in.Bounds().Dx() - 1
+
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
+ row := in.Pix[x*in.Stride:]
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
+ var rgba [4]float32
+ var sum float32
+ start := offset[y]
+ ci := y * filterLength
+ for i := 0; i < filterLength; i++ {
+ if coeffs[ci+i] {
+ xi := start + i
+ switch {
+ case uint(xi) < uint(maxX):
+ xi *= 4
+ case xi >= maxX:
+ xi = 4 * maxX
+ default:
+ xi = 0
+ }
+ rgba[0] += float32(row[xi+0])
+ rgba[1] += float32(row[xi+1])
+ rgba[2] += float32(row[xi+2])
+ rgba[3] += float32(row[xi+3])
+ sum++
+ }
+ }
+
+ xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*4
+ out.Pix[xo+0] = floatToUint8(rgba[0] / sum)
+ out.Pix[xo+1] = floatToUint8(rgba[1] / sum)
+ out.Pix[xo+2] = floatToUint8(rgba[2] / sum)
+ out.Pix[xo+3] = floatToUint8(rgba[3] / sum)
+ }
+ }
+}
+
+func nearestNRGBA(in *image.NRGBA, out *image.NRGBA, scale float64, coeffs []bool, offset []int, filterLength int) {
+ newBounds := out.Bounds()
+ maxX := in.Bounds().Dx() - 1
+
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
+ row := in.Pix[x*in.Stride:]
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
+ var rgba [4]float32
+ var sum float32
+ start := offset[y]
+ ci := y * filterLength
+ for i := 0; i < filterLength; i++ {
+ if coeffs[ci+i] {
+ xi := start + i
+ switch {
+ case uint(xi) < uint(maxX):
+ xi *= 4
+ case xi >= maxX:
+ xi = 4 * maxX
+ default:
+ xi = 0
+ }
+ rgba[0] += float32(row[xi+0])
+ rgba[1] += float32(row[xi+1])
+ rgba[2] += float32(row[xi+2])
+ rgba[3] += float32(row[xi+3])
+ sum++
+ }
+ }
+
+ xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*4
+ out.Pix[xo+0] = floatToUint8(rgba[0] / sum)
+ out.Pix[xo+1] = floatToUint8(rgba[1] / sum)
+ out.Pix[xo+2] = floatToUint8(rgba[2] / sum)
+ out.Pix[xo+3] = floatToUint8(rgba[3] / sum)
+ }
+ }
+}
+
+func nearestRGBA64(in *image.RGBA64, out *image.RGBA64, scale float64, coeffs []bool, offset []int, filterLength int) {
+ newBounds := out.Bounds()
+ maxX := in.Bounds().Dx() - 1
+
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
+ row := in.Pix[x*in.Stride:]
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
+ var rgba [4]float32
+ var sum float32
+ start := offset[y]
+ ci := y * filterLength
+ for i := 0; i < filterLength; i++ {
+ if coeffs[ci+i] {
+ xi := start + i
+ switch {
+ case uint(xi) < uint(maxX):
+ xi *= 8
+ case xi >= maxX:
+ xi = 8 * maxX
+ default:
+ xi = 0
+ }
+ rgba[0] += float32(uint16(row[xi+0])<<8 | uint16(row[xi+1]))
+ rgba[1] += float32(uint16(row[xi+2])<<8 | uint16(row[xi+3]))
+ rgba[2] += float32(uint16(row[xi+4])<<8 | uint16(row[xi+5]))
+ rgba[3] += float32(uint16(row[xi+6])<<8 | uint16(row[xi+7]))
+ sum++
+ }
+ }
+
+ xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*8
+ value := floatToUint16(rgba[0] / sum)
+ out.Pix[xo+0] = uint8(value >> 8)
+ out.Pix[xo+1] = uint8(value)
+ value = floatToUint16(rgba[1] / sum)
+ out.Pix[xo+2] = uint8(value >> 8)
+ out.Pix[xo+3] = uint8(value)
+ value = floatToUint16(rgba[2] / sum)
+ out.Pix[xo+4] = uint8(value >> 8)
+ out.Pix[xo+5] = uint8(value)
+ value = floatToUint16(rgba[3] / sum)
+ out.Pix[xo+6] = uint8(value >> 8)
+ out.Pix[xo+7] = uint8(value)
+ }
+ }
+}
+
+func nearestNRGBA64(in *image.NRGBA64, out *image.NRGBA64, scale float64, coeffs []bool, offset []int, filterLength int) {
+ newBounds := out.Bounds()
+ maxX := in.Bounds().Dx() - 1
+
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
+ row := in.Pix[x*in.Stride:]
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
+ var rgba [4]float32
+ var sum float32
+ start := offset[y]
+ ci := y * filterLength
+ for i := 0; i < filterLength; i++ {
+ if coeffs[ci+i] {
+ xi := start + i
+ switch {
+ case uint(xi) < uint(maxX):
+ xi *= 8
+ case xi >= maxX:
+ xi = 8 * maxX
+ default:
+ xi = 0
+ }
+ rgba[0] += float32(uint16(row[xi+0])<<8 | uint16(row[xi+1]))
+ rgba[1] += float32(uint16(row[xi+2])<<8 | uint16(row[xi+3]))
+ rgba[2] += float32(uint16(row[xi+4])<<8 | uint16(row[xi+5]))
+ rgba[3] += float32(uint16(row[xi+6])<<8 | uint16(row[xi+7]))
+ sum++
+ }
+ }
+
+ xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*8
+ value := floatToUint16(rgba[0] / sum)
+ out.Pix[xo+0] = uint8(value >> 8)
+ out.Pix[xo+1] = uint8(value)
+ value = floatToUint16(rgba[1] / sum)
+ out.Pix[xo+2] = uint8(value >> 8)
+ out.Pix[xo+3] = uint8(value)
+ value = floatToUint16(rgba[2] / sum)
+ out.Pix[xo+4] = uint8(value >> 8)
+ out.Pix[xo+5] = uint8(value)
+ value = floatToUint16(rgba[3] / sum)
+ out.Pix[xo+6] = uint8(value >> 8)
+ out.Pix[xo+7] = uint8(value)
+ }
+ }
+}
+
+func nearestGray(in *image.Gray, out *image.Gray, scale float64, coeffs []bool, offset []int, filterLength int) {
+ newBounds := out.Bounds()
+ maxX := in.Bounds().Dx() - 1
+
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
+ row := in.Pix[x*in.Stride:]
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
+ var gray float32
+ var sum float32
+ start := offset[y]
+ ci := y * filterLength
+ for i := 0; i < filterLength; i++ {
+ if coeffs[ci+i] {
+ xi := start + i
+ switch {
+ case xi < 0:
+ xi = 0
+ case xi >= maxX:
+ xi = maxX
+ }
+ gray += float32(row[xi])
+ sum++
+ }
+ }
+
+ offset := (y-newBounds.Min.Y)*out.Stride + (x - newBounds.Min.X)
+ out.Pix[offset] = floatToUint8(gray / sum)
+ }
+ }
+}
+
+func nearestGray16(in *image.Gray16, out *image.Gray16, scale float64, coeffs []bool, offset []int, filterLength int) {
+ newBounds := out.Bounds()
+ maxX := in.Bounds().Dx() - 1
+
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
+ row := in.Pix[x*in.Stride:]
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
+ var gray float32
+ var sum float32
+ start := offset[y]
+ ci := y * filterLength
+ for i := 0; i < filterLength; i++ {
+ if coeffs[ci+i] {
+ xi := start + i
+ switch {
+ case uint(xi) < uint(maxX):
+ xi *= 2
+ case xi >= maxX:
+ xi = 2 * maxX
+ default:
+ xi = 0
+ }
+ gray += float32(uint16(row[xi+0])<<8 | uint16(row[xi+1]))
+ sum++
+ }
+ }
+
+ offset := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*2
+ value := floatToUint16(gray / sum)
+ out.Pix[offset+0] = uint8(value >> 8)
+ out.Pix[offset+1] = uint8(value)
+ }
+ }
+}
diff --git a/vendor/github.com/nfnt/resize/resize.go b/vendor/github.com/nfnt/resize/resize.go
new file mode 100644
index 0000000..0d7fbf6
--- /dev/null
+++ b/vendor/github.com/nfnt/resize/resize.go
@@ -0,0 +1,620 @@
+/*
+Copyright (c) 2012, Jan Schlicht
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+*/
+
+// Package resize implements various image resizing methods.
+//
+// The package works with the Image interface described in the image package.
+// Various interpolation methods are provided and multiple processors may be
+// utilized in the computations.
+//
+// Example:
+// imgResized := resize.Resize(1000, 0, imgOld, resize.MitchellNetravali)
+package resize
+
+import (
+ "image"
+ "runtime"
+ "sync"
+)
+
+// An InterpolationFunction provides the parameters that describe an
+// interpolation kernel. It returns the number of samples to take
+// and the kernel function to use for sampling.
+type InterpolationFunction int
+
+// InterpolationFunction constants
+const (
+ // Nearest-neighbor interpolation
+ NearestNeighbor InterpolationFunction = iota
+ // Bilinear interpolation
+ Bilinear
+ // Bicubic interpolation (with cubic hermite spline)
+ Bicubic
+ // Mitchell-Netravali interpolation
+ MitchellNetravali
+ // Lanczos interpolation (a=2)
+ Lanczos2
+ // Lanczos interpolation (a=3)
+ Lanczos3
+)
+
+// kernal, returns an InterpolationFunctions taps and kernel.
+func (i InterpolationFunction) kernel() (int, func(float64) float64) {
+ switch i {
+ case Bilinear:
+ return 2, linear
+ case Bicubic:
+ return 4, cubic
+ case MitchellNetravali:
+ return 4, mitchellnetravali
+ case Lanczos2:
+ return 4, lanczos2
+ case Lanczos3:
+ return 6, lanczos3
+ default:
+ // Default to NearestNeighbor.
+ return 2, nearest
+ }
+}
+
+// values <1 will sharpen the image
+var blur = 1.0
+
+// Resize scales an image to new width and height using the interpolation function interp.
+// A new image with the given dimensions will be returned.
+// If one of the parameters width or height is set to 0, its size will be calculated so that
+// the aspect ratio is that of the originating image.
+// The resizing algorithm uses channels for parallel computation.
+// If the input image has width or height of 0, it is returned unchanged.
+func Resize(width, height uint, img image.Image, interp InterpolationFunction) image.Image {
+ scaleX, scaleY := calcFactors(width, height, float64(img.Bounds().Dx()), float64(img.Bounds().Dy()))
+ if width == 0 {
+ width = uint(0.7 + float64(img.Bounds().Dx())/scaleX)
+ }
+ if height == 0 {
+ height = uint(0.7 + float64(img.Bounds().Dy())/scaleY)
+ }
+
+ // Trivial case: return input image
+ if int(width) == img.Bounds().Dx() && int(height) == img.Bounds().Dy() {
+ return img
+ }
+
+ // Input image has no pixels
+ if img.Bounds().Dx() <= 0 || img.Bounds().Dy() <= 0 {
+ return img
+ }
+
+ if interp == NearestNeighbor {
+ return resizeNearest(width, height, scaleX, scaleY, img, interp)
+ }
+
+ taps, kernel := interp.kernel()
+ cpus := runtime.GOMAXPROCS(0)
+ wg := sync.WaitGroup{}
+
+ // Generic access to image.Image is slow in tight loops.
+ // The optimal access has to be determined from the concrete image type.
+ switch input := img.(type) {
+ case *image.RGBA:
+ // 8-bit precision
+ temp := image.NewRGBA(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
+ result := image.NewRGBA(image.Rect(0, 0, int(width), int(height)))
+
+ // horizontal filter, results in transposed temporary image
+ coeffs, offset, filterLength := createWeights8(temp.Bounds().Dy(), taps, blur, scaleX, kernel)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(temp, i, cpus).(*image.RGBA)
+ go func() {
+ defer wg.Done()
+ resizeRGBA(input, slice, scaleX, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+
+ // horizontal filter on transposed image, result is not transposed
+ coeffs, offset, filterLength = createWeights8(result.Bounds().Dy(), taps, blur, scaleY, kernel)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(result, i, cpus).(*image.RGBA)
+ go func() {
+ defer wg.Done()
+ resizeRGBA(temp, slice, scaleY, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+ return result
+ case *image.NRGBA:
+ // 8-bit precision
+ temp := image.NewRGBA(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
+ result := image.NewRGBA(image.Rect(0, 0, int(width), int(height)))
+
+ // horizontal filter, results in transposed temporary image
+ coeffs, offset, filterLength := createWeights8(temp.Bounds().Dy(), taps, blur, scaleX, kernel)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(temp, i, cpus).(*image.RGBA)
+ go func() {
+ defer wg.Done()
+ resizeNRGBA(input, slice, scaleX, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+
+ // horizontal filter on transposed image, result is not transposed
+ coeffs, offset, filterLength = createWeights8(result.Bounds().Dy(), taps, blur, scaleY, kernel)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(result, i, cpus).(*image.RGBA)
+ go func() {
+ defer wg.Done()
+ resizeRGBA(temp, slice, scaleY, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+ return result
+
+ case *image.YCbCr:
+ // 8-bit precision
+ // accessing the YCbCr arrays in a tight loop is slow.
+ // converting the image to ycc increases performance by 2x.
+ temp := newYCC(image.Rect(0, 0, input.Bounds().Dy(), int(width)), input.SubsampleRatio)
+ result := newYCC(image.Rect(0, 0, int(width), int(height)), image.YCbCrSubsampleRatio444)
+
+ coeffs, offset, filterLength := createWeights8(temp.Bounds().Dy(), taps, blur, scaleX, kernel)
+ in := imageYCbCrToYCC(input)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(temp, i, cpus).(*ycc)
+ go func() {
+ defer wg.Done()
+ resizeYCbCr(in, slice, scaleX, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+
+ coeffs, offset, filterLength = createWeights8(result.Bounds().Dy(), taps, blur, scaleY, kernel)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(result, i, cpus).(*ycc)
+ go func() {
+ defer wg.Done()
+ resizeYCbCr(temp, slice, scaleY, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+ return result.YCbCr()
+ case *image.RGBA64:
+ // 16-bit precision
+ temp := image.NewRGBA64(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
+ result := image.NewRGBA64(image.Rect(0, 0, int(width), int(height)))
+
+ // horizontal filter, results in transposed temporary image
+ coeffs, offset, filterLength := createWeights16(temp.Bounds().Dy(), taps, blur, scaleX, kernel)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(temp, i, cpus).(*image.RGBA64)
+ go func() {
+ defer wg.Done()
+ resizeRGBA64(input, slice, scaleX, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+
+ // horizontal filter on transposed image, result is not transposed
+ coeffs, offset, filterLength = createWeights16(result.Bounds().Dy(), taps, blur, scaleY, kernel)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(result, i, cpus).(*image.RGBA64)
+ go func() {
+ defer wg.Done()
+ resizeRGBA64(temp, slice, scaleY, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+ return result
+ case *image.NRGBA64:
+ // 16-bit precision
+ temp := image.NewRGBA64(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
+ result := image.NewRGBA64(image.Rect(0, 0, int(width), int(height)))
+
+ // horizontal filter, results in transposed temporary image
+ coeffs, offset, filterLength := createWeights16(temp.Bounds().Dy(), taps, blur, scaleX, kernel)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(temp, i, cpus).(*image.RGBA64)
+ go func() {
+ defer wg.Done()
+ resizeNRGBA64(input, slice, scaleX, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+
+ // horizontal filter on transposed image, result is not transposed
+ coeffs, offset, filterLength = createWeights16(result.Bounds().Dy(), taps, blur, scaleY, kernel)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(result, i, cpus).(*image.RGBA64)
+ go func() {
+ defer wg.Done()
+ resizeRGBA64(temp, slice, scaleY, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+ return result
+ case *image.Gray:
+ // 8-bit precision
+ temp := image.NewGray(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
+ result := image.NewGray(image.Rect(0, 0, int(width), int(height)))
+
+ // horizontal filter, results in transposed temporary image
+ coeffs, offset, filterLength := createWeights8(temp.Bounds().Dy(), taps, blur, scaleX, kernel)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(temp, i, cpus).(*image.Gray)
+ go func() {
+ defer wg.Done()
+ resizeGray(input, slice, scaleX, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+
+ // horizontal filter on transposed image, result is not transposed
+ coeffs, offset, filterLength = createWeights8(result.Bounds().Dy(), taps, blur, scaleY, kernel)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(result, i, cpus).(*image.Gray)
+ go func() {
+ defer wg.Done()
+ resizeGray(temp, slice, scaleY, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+ return result
+ case *image.Gray16:
+ // 16-bit precision
+ temp := image.NewGray16(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
+ result := image.NewGray16(image.Rect(0, 0, int(width), int(height)))
+
+ // horizontal filter, results in transposed temporary image
+ coeffs, offset, filterLength := createWeights16(temp.Bounds().Dy(), taps, blur, scaleX, kernel)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(temp, i, cpus).(*image.Gray16)
+ go func() {
+ defer wg.Done()
+ resizeGray16(input, slice, scaleX, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+
+ // horizontal filter on transposed image, result is not transposed
+ coeffs, offset, filterLength = createWeights16(result.Bounds().Dy(), taps, blur, scaleY, kernel)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(result, i, cpus).(*image.Gray16)
+ go func() {
+ defer wg.Done()
+ resizeGray16(temp, slice, scaleY, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+ return result
+ default:
+ // 16-bit precision
+ temp := image.NewRGBA64(image.Rect(0, 0, img.Bounds().Dy(), int(width)))
+ result := image.NewRGBA64(image.Rect(0, 0, int(width), int(height)))
+
+ // horizontal filter, results in transposed temporary image
+ coeffs, offset, filterLength := createWeights16(temp.Bounds().Dy(), taps, blur, scaleX, kernel)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(temp, i, cpus).(*image.RGBA64)
+ go func() {
+ defer wg.Done()
+ resizeGeneric(img, slice, scaleX, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+
+ // horizontal filter on transposed image, result is not transposed
+ coeffs, offset, filterLength = createWeights16(result.Bounds().Dy(), taps, blur, scaleY, kernel)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(result, i, cpus).(*image.RGBA64)
+ go func() {
+ defer wg.Done()
+ resizeRGBA64(temp, slice, scaleY, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+ return result
+ }
+}
+
+func resizeNearest(width, height uint, scaleX, scaleY float64, img image.Image, interp InterpolationFunction) image.Image {
+ taps, _ := interp.kernel()
+ cpus := runtime.GOMAXPROCS(0)
+ wg := sync.WaitGroup{}
+
+ switch input := img.(type) {
+ case *image.RGBA:
+ // 8-bit precision
+ temp := image.NewRGBA(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
+ result := image.NewRGBA(image.Rect(0, 0, int(width), int(height)))
+
+ // horizontal filter, results in transposed temporary image
+ coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(temp, i, cpus).(*image.RGBA)
+ go func() {
+ defer wg.Done()
+ nearestRGBA(input, slice, scaleX, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+
+ // horizontal filter on transposed image, result is not transposed
+ coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(result, i, cpus).(*image.RGBA)
+ go func() {
+ defer wg.Done()
+ nearestRGBA(temp, slice, scaleY, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+ return result
+ case *image.NRGBA:
+ // 8-bit precision
+ temp := image.NewNRGBA(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
+ result := image.NewNRGBA(image.Rect(0, 0, int(width), int(height)))
+
+ // horizontal filter, results in transposed temporary image
+ coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(temp, i, cpus).(*image.NRGBA)
+ go func() {
+ defer wg.Done()
+ nearestNRGBA(input, slice, scaleX, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+
+ // horizontal filter on transposed image, result is not transposed
+ coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(result, i, cpus).(*image.NRGBA)
+ go func() {
+ defer wg.Done()
+ nearestNRGBA(temp, slice, scaleY, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+ return result
+ case *image.YCbCr:
+ // 8-bit precision
+ // accessing the YCbCr arrays in a tight loop is slow.
+ // converting the image to ycc increases performance by 2x.
+ temp := newYCC(image.Rect(0, 0, input.Bounds().Dy(), int(width)), input.SubsampleRatio)
+ result := newYCC(image.Rect(0, 0, int(width), int(height)), image.YCbCrSubsampleRatio444)
+
+ coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX)
+ in := imageYCbCrToYCC(input)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(temp, i, cpus).(*ycc)
+ go func() {
+ defer wg.Done()
+ nearestYCbCr(in, slice, scaleX, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+
+ coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(result, i, cpus).(*ycc)
+ go func() {
+ defer wg.Done()
+ nearestYCbCr(temp, slice, scaleY, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+ return result.YCbCr()
+ case *image.RGBA64:
+ // 16-bit precision
+ temp := image.NewRGBA64(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
+ result := image.NewRGBA64(image.Rect(0, 0, int(width), int(height)))
+
+ // horizontal filter, results in transposed temporary image
+ coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(temp, i, cpus).(*image.RGBA64)
+ go func() {
+ defer wg.Done()
+ nearestRGBA64(input, slice, scaleX, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+
+ // horizontal filter on transposed image, result is not transposed
+ coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(result, i, cpus).(*image.RGBA64)
+ go func() {
+ defer wg.Done()
+ nearestRGBA64(temp, slice, scaleY, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+ return result
+ case *image.NRGBA64:
+ // 16-bit precision
+ temp := image.NewNRGBA64(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
+ result := image.NewNRGBA64(image.Rect(0, 0, int(width), int(height)))
+
+ // horizontal filter, results in transposed temporary image
+ coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(temp, i, cpus).(*image.NRGBA64)
+ go func() {
+ defer wg.Done()
+ nearestNRGBA64(input, slice, scaleX, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+
+ // horizontal filter on transposed image, result is not transposed
+ coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(result, i, cpus).(*image.NRGBA64)
+ go func() {
+ defer wg.Done()
+ nearestNRGBA64(temp, slice, scaleY, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+ return result
+ case *image.Gray:
+ // 8-bit precision
+ temp := image.NewGray(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
+ result := image.NewGray(image.Rect(0, 0, int(width), int(height)))
+
+ // horizontal filter, results in transposed temporary image
+ coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(temp, i, cpus).(*image.Gray)
+ go func() {
+ defer wg.Done()
+ nearestGray(input, slice, scaleX, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+
+ // horizontal filter on transposed image, result is not transposed
+ coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(result, i, cpus).(*image.Gray)
+ go func() {
+ defer wg.Done()
+ nearestGray(temp, slice, scaleY, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+ return result
+ case *image.Gray16:
+ // 16-bit precision
+ temp := image.NewGray16(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
+ result := image.NewGray16(image.Rect(0, 0, int(width), int(height)))
+
+ // horizontal filter, results in transposed temporary image
+ coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(temp, i, cpus).(*image.Gray16)
+ go func() {
+ defer wg.Done()
+ nearestGray16(input, slice, scaleX, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+
+ // horizontal filter on transposed image, result is not transposed
+ coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(result, i, cpus).(*image.Gray16)
+ go func() {
+ defer wg.Done()
+ nearestGray16(temp, slice, scaleY, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+ return result
+ default:
+ // 16-bit precision
+ temp := image.NewRGBA64(image.Rect(0, 0, img.Bounds().Dy(), int(width)))
+ result := image.NewRGBA64(image.Rect(0, 0, int(width), int(height)))
+
+ // horizontal filter, results in transposed temporary image
+ coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(temp, i, cpus).(*image.RGBA64)
+ go func() {
+ defer wg.Done()
+ nearestGeneric(img, slice, scaleX, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+
+ // horizontal filter on transposed image, result is not transposed
+ coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY)
+ wg.Add(cpus)
+ for i := 0; i < cpus; i++ {
+ slice := makeSlice(result, i, cpus).(*image.RGBA64)
+ go func() {
+ defer wg.Done()
+ nearestRGBA64(temp, slice, scaleY, coeffs, offset, filterLength)
+ }()
+ }
+ wg.Wait()
+ return result
+ }
+
+}
+
+// Calculates scaling factors using old and new image dimensions.
+func calcFactors(width, height uint, oldWidth, oldHeight float64) (scaleX, scaleY float64) {
+ if width == 0 {
+ if height == 0 {
+ scaleX = 1.0
+ scaleY = 1.0
+ } else {
+ scaleY = oldHeight / float64(height)
+ scaleX = scaleY
+ }
+ } else {
+ scaleX = oldWidth / float64(width)
+ if height == 0 {
+ scaleY = scaleX
+ } else {
+ scaleY = oldHeight / float64(height)
+ }
+ }
+ return
+}
+
+type imageWithSubImage interface {
+ image.Image
+ SubImage(image.Rectangle) image.Image
+}
+
+func makeSlice(img imageWithSubImage, i, n int) image.Image {
+ return img.SubImage(image.Rect(img.Bounds().Min.X, img.Bounds().Min.Y+i*img.Bounds().Dy()/n, img.Bounds().Max.X, img.Bounds().Min.Y+(i+1)*img.Bounds().Dy()/n))
+}
diff --git a/vendor/github.com/nfnt/resize/thumbnail.go b/vendor/github.com/nfnt/resize/thumbnail.go
new file mode 100644
index 0000000..9efc246
--- /dev/null
+++ b/vendor/github.com/nfnt/resize/thumbnail.go
@@ -0,0 +1,55 @@
+/*
+Copyright (c) 2012, Jan Schlicht
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+*/
+
+package resize
+
+import (
+ "image"
+)
+
+// Thumbnail will downscale provided image to max width and height preserving
+// original aspect ratio and using the interpolation function interp.
+// It will return original image, without processing it, if original sizes
+// are already smaller than provided constraints.
+func Thumbnail(maxWidth, maxHeight uint, img image.Image, interp InterpolationFunction) image.Image {
+ origBounds := img.Bounds()
+ origWidth := uint(origBounds.Dx())
+ origHeight := uint(origBounds.Dy())
+ newWidth, newHeight := origWidth, origHeight
+
+ // Return original image if it have same or smaller size as constraints
+ if maxWidth >= origWidth && maxHeight >= origHeight {
+ return img
+ }
+
+ // Preserve aspect ratio
+ if origWidth > maxWidth {
+ newHeight = uint(origHeight * maxWidth / origWidth)
+ if newHeight < 1 {
+ newHeight = 1
+ }
+ newWidth = maxWidth
+ }
+
+ if newHeight > maxHeight {
+ newWidth = uint(newWidth * maxHeight / newHeight)
+ if newWidth < 1 {
+ newWidth = 1
+ }
+ newHeight = maxHeight
+ }
+ return Resize(newWidth, newHeight, img, interp)
+}
diff --git a/vendor/github.com/nfnt/resize/ycc.go b/vendor/github.com/nfnt/resize/ycc.go
new file mode 100644
index 0000000..143e4d0
--- /dev/null
+++ b/vendor/github.com/nfnt/resize/ycc.go
@@ -0,0 +1,387 @@
+/*
+Copyright (c) 2014, Charlie Vieth
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+*/
+
+package resize
+
+import (
+ "image"
+ "image/color"
+)
+
+// ycc is an in memory YCbCr image. The Y, Cb and Cr samples are held in a
+// single slice to increase resizing performance.
+type ycc struct {
+ // Pix holds the image's pixels, in Y, Cb, Cr order. The pixel at
+ // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*3].
+ Pix []uint8
+ // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
+ Stride int
+ // Rect is the image's bounds.
+ Rect image.Rectangle
+ // SubsampleRatio is the subsample ratio of the original YCbCr image.
+ SubsampleRatio image.YCbCrSubsampleRatio
+}
+
+// PixOffset returns the index of the first element of Pix that corresponds to
+// the pixel at (x, y).
+func (p *ycc) PixOffset(x, y int) int {
+ return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*3
+}
+
+func (p *ycc) Bounds() image.Rectangle {
+ return p.Rect
+}
+
+func (p *ycc) ColorModel() color.Model {
+ return color.YCbCrModel
+}
+
+func (p *ycc) At(x, y int) color.Color {
+ if !(image.Point{x, y}.In(p.Rect)) {
+ return color.YCbCr{}
+ }
+ i := p.PixOffset(x, y)
+ return color.YCbCr{
+ p.Pix[i+0],
+ p.Pix[i+1],
+ p.Pix[i+2],
+ }
+}
+
+func (p *ycc) Opaque() bool {
+ return true
+}
+
+// SubImage returns an image representing the portion of the image p visible
+// through r. The returned value shares pixels with the original image.
+func (p *ycc) SubImage(r image.Rectangle) image.Image {
+ r = r.Intersect(p.Rect)
+ if r.Empty() {
+ return &ycc{SubsampleRatio: p.SubsampleRatio}
+ }
+ i := p.PixOffset(r.Min.X, r.Min.Y)
+ return &ycc{
+ Pix: p.Pix[i:],
+ Stride: p.Stride,
+ Rect: r,
+ SubsampleRatio: p.SubsampleRatio,
+ }
+}
+
+// newYCC returns a new ycc with the given bounds and subsample ratio.
+func newYCC(r image.Rectangle, s image.YCbCrSubsampleRatio) *ycc {
+ w, h := r.Dx(), r.Dy()
+ buf := make([]uint8, 3*w*h)
+ return &ycc{Pix: buf, Stride: 3 * w, Rect: r, SubsampleRatio: s}
+}
+
+// Copy of image.YCbCrSubsampleRatio constants - this allows us to support
+// older versions of Go where these constants are not defined (i.e. Go 1.4)
+const (
+ ycbcrSubsampleRatio444 image.YCbCrSubsampleRatio = iota
+ ycbcrSubsampleRatio422
+ ycbcrSubsampleRatio420
+ ycbcrSubsampleRatio440
+ ycbcrSubsampleRatio411
+ ycbcrSubsampleRatio410
+)
+
+// YCbCr converts ycc to a YCbCr image with the same subsample ratio
+// as the YCbCr image that ycc was generated from.
+func (p *ycc) YCbCr() *image.YCbCr {
+ ycbcr := image.NewYCbCr(p.Rect, p.SubsampleRatio)
+ switch ycbcr.SubsampleRatio {
+ case ycbcrSubsampleRatio422:
+ return p.ycbcr422(ycbcr)
+ case ycbcrSubsampleRatio420:
+ return p.ycbcr420(ycbcr)
+ case ycbcrSubsampleRatio440:
+ return p.ycbcr440(ycbcr)
+ case ycbcrSubsampleRatio444:
+ return p.ycbcr444(ycbcr)
+ case ycbcrSubsampleRatio411:
+ return p.ycbcr411(ycbcr)
+ case ycbcrSubsampleRatio410:
+ return p.ycbcr410(ycbcr)
+ }
+ return ycbcr
+}
+
+// imageYCbCrToYCC converts a YCbCr image to a ycc image for resizing.
+func imageYCbCrToYCC(in *image.YCbCr) *ycc {
+ w, h := in.Rect.Dx(), in.Rect.Dy()
+ p := ycc{
+ Pix: make([]uint8, 3*w*h),
+ Stride: 3 * w,
+ Rect: image.Rect(0, 0, w, h),
+ SubsampleRatio: in.SubsampleRatio,
+ }
+ switch in.SubsampleRatio {
+ case ycbcrSubsampleRatio422:
+ return convertToYCC422(in, &p)
+ case ycbcrSubsampleRatio420:
+ return convertToYCC420(in, &p)
+ case ycbcrSubsampleRatio440:
+ return convertToYCC440(in, &p)
+ case ycbcrSubsampleRatio444:
+ return convertToYCC444(in, &p)
+ case ycbcrSubsampleRatio411:
+ return convertToYCC411(in, &p)
+ case ycbcrSubsampleRatio410:
+ return convertToYCC410(in, &p)
+ }
+ return &p
+}
+
+func (p *ycc) ycbcr422(ycbcr *image.YCbCr) *image.YCbCr {
+ var off int
+ Pix := p.Pix
+ Y := ycbcr.Y
+ Cb := ycbcr.Cb
+ Cr := ycbcr.Cr
+ for y := 0; y < ycbcr.Rect.Max.Y-ycbcr.Rect.Min.Y; y++ {
+ yy := y * ycbcr.YStride
+ cy := y * ycbcr.CStride
+ for x := 0; x < ycbcr.Rect.Max.X-ycbcr.Rect.Min.X; x++ {
+ ci := cy + x/2
+ Y[yy+x] = Pix[off+0]
+ Cb[ci] = Pix[off+1]
+ Cr[ci] = Pix[off+2]
+ off += 3
+ }
+ }
+ return ycbcr
+}
+
+func (p *ycc) ycbcr420(ycbcr *image.YCbCr) *image.YCbCr {
+ var off int
+ Pix := p.Pix
+ Y := ycbcr.Y
+ Cb := ycbcr.Cb
+ Cr := ycbcr.Cr
+ for y := 0; y < ycbcr.Rect.Max.Y-ycbcr.Rect.Min.Y; y++ {
+ yy := y * ycbcr.YStride
+ cy := (y / 2) * ycbcr.CStride
+ for x := 0; x < ycbcr.Rect.Max.X-ycbcr.Rect.Min.X; x++ {
+ ci := cy + x/2
+ Y[yy+x] = Pix[off+0]
+ Cb[ci] = Pix[off+1]
+ Cr[ci] = Pix[off+2]
+ off += 3
+ }
+ }
+ return ycbcr
+}
+
+func (p *ycc) ycbcr440(ycbcr *image.YCbCr) *image.YCbCr {
+ var off int
+ Pix := p.Pix
+ Y := ycbcr.Y
+ Cb := ycbcr.Cb
+ Cr := ycbcr.Cr
+ for y := 0; y < ycbcr.Rect.Max.Y-ycbcr.Rect.Min.Y; y++ {
+ yy := y * ycbcr.YStride
+ cy := (y / 2) * ycbcr.CStride
+ for x := 0; x < ycbcr.Rect.Max.X-ycbcr.Rect.Min.X; x++ {
+ ci := cy + x
+ Y[yy+x] = Pix[off+0]
+ Cb[ci] = Pix[off+1]
+ Cr[ci] = Pix[off+2]
+ off += 3
+ }
+ }
+ return ycbcr
+}
+
+func (p *ycc) ycbcr444(ycbcr *image.YCbCr) *image.YCbCr {
+ var off int
+ Pix := p.Pix
+ Y := ycbcr.Y
+ Cb := ycbcr.Cb
+ Cr := ycbcr.Cr
+ for y := 0; y < ycbcr.Rect.Max.Y-ycbcr.Rect.Min.Y; y++ {
+ yy := y * ycbcr.YStride
+ cy := y * ycbcr.CStride
+ for x := 0; x < ycbcr.Rect.Max.X-ycbcr.Rect.Min.X; x++ {
+ ci := cy + x
+ Y[yy+x] = Pix[off+0]
+ Cb[ci] = Pix[off+1]
+ Cr[ci] = Pix[off+2]
+ off += 3
+ }
+ }
+ return ycbcr
+}
+
+func (p *ycc) ycbcr411(ycbcr *image.YCbCr) *image.YCbCr {
+ var off int
+ Pix := p.Pix
+ Y := ycbcr.Y
+ Cb := ycbcr.Cb
+ Cr := ycbcr.Cr
+ for y := 0; y < ycbcr.Rect.Max.Y-ycbcr.Rect.Min.Y; y++ {
+ yy := y * ycbcr.YStride
+ cy := y * ycbcr.CStride
+ for x := 0; x < ycbcr.Rect.Max.X-ycbcr.Rect.Min.X; x++ {
+ ci := cy + x/4
+ Y[yy+x] = Pix[off+0]
+ Cb[ci] = Pix[off+1]
+ Cr[ci] = Pix[off+2]
+ off += 3
+ }
+ }
+ return ycbcr
+}
+
+func (p *ycc) ycbcr410(ycbcr *image.YCbCr) *image.YCbCr {
+ var off int
+ Pix := p.Pix
+ Y := ycbcr.Y
+ Cb := ycbcr.Cb
+ Cr := ycbcr.Cr
+ for y := 0; y < ycbcr.Rect.Max.Y-ycbcr.Rect.Min.Y; y++ {
+ yy := y * ycbcr.YStride
+ cy := (y / 2) * ycbcr.CStride
+ for x := 0; x < ycbcr.Rect.Max.X-ycbcr.Rect.Min.X; x++ {
+ ci := cy + x/4
+ Y[yy+x] = Pix[off+0]
+ Cb[ci] = Pix[off+1]
+ Cr[ci] = Pix[off+2]
+ off += 3
+ }
+ }
+ return ycbcr
+}
+
+func convertToYCC422(in *image.YCbCr, p *ycc) *ycc {
+ var off int
+ Pix := p.Pix
+ Y := in.Y
+ Cb := in.Cb
+ Cr := in.Cr
+ for y := 0; y < in.Rect.Max.Y-in.Rect.Min.Y; y++ {
+ yy := y * in.YStride
+ cy := y * in.CStride
+ for x := 0; x < in.Rect.Max.X-in.Rect.Min.X; x++ {
+ ci := cy + x/2
+ Pix[off+0] = Y[yy+x]
+ Pix[off+1] = Cb[ci]
+ Pix[off+2] = Cr[ci]
+ off += 3
+ }
+ }
+ return p
+}
+
+func convertToYCC420(in *image.YCbCr, p *ycc) *ycc {
+ var off int
+ Pix := p.Pix
+ Y := in.Y
+ Cb := in.Cb
+ Cr := in.Cr
+ for y := 0; y < in.Rect.Max.Y-in.Rect.Min.Y; y++ {
+ yy := y * in.YStride
+ cy := (y / 2) * in.CStride
+ for x := 0; x < in.Rect.Max.X-in.Rect.Min.X; x++ {
+ ci := cy + x/2
+ Pix[off+0] = Y[yy+x]
+ Pix[off+1] = Cb[ci]
+ Pix[off+2] = Cr[ci]
+ off += 3
+ }
+ }
+ return p
+}
+
+func convertToYCC440(in *image.YCbCr, p *ycc) *ycc {
+ var off int
+ Pix := p.Pix
+ Y := in.Y
+ Cb := in.Cb
+ Cr := in.Cr
+ for y := 0; y < in.Rect.Max.Y-in.Rect.Min.Y; y++ {
+ yy := y * in.YStride
+ cy := (y / 2) * in.CStride
+ for x := 0; x < in.Rect.Max.X-in.Rect.Min.X; x++ {
+ ci := cy + x
+ Pix[off+0] = Y[yy+x]
+ Pix[off+1] = Cb[ci]
+ Pix[off+2] = Cr[ci]
+ off += 3
+ }
+ }
+ return p
+}
+
+func convertToYCC444(in *image.YCbCr, p *ycc) *ycc {
+ var off int
+ Pix := p.Pix
+ Y := in.Y
+ Cb := in.Cb
+ Cr := in.Cr
+ for y := 0; y < in.Rect.Max.Y-in.Rect.Min.Y; y++ {
+ yy := y * in.YStride
+ cy := y * in.CStride
+ for x := 0; x < in.Rect.Max.X-in.Rect.Min.X; x++ {
+ ci := cy + x
+ Pix[off+0] = Y[yy+x]
+ Pix[off+1] = Cb[ci]
+ Pix[off+2] = Cr[ci]
+ off += 3
+ }
+ }
+ return p
+}
+
+func convertToYCC411(in *image.YCbCr, p *ycc) *ycc {
+ var off int
+ Pix := p.Pix
+ Y := in.Y
+ Cb := in.Cb
+ Cr := in.Cr
+ for y := 0; y < in.Rect.Max.Y-in.Rect.Min.Y; y++ {
+ yy := y * in.YStride
+ cy := y * in.CStride
+ for x := 0; x < in.Rect.Max.X-in.Rect.Min.X; x++ {
+ ci := cy + x/4
+ Pix[off+0] = Y[yy+x]
+ Pix[off+1] = Cb[ci]
+ Pix[off+2] = Cr[ci]
+ off += 3
+ }
+ }
+ return p
+}
+
+func convertToYCC410(in *image.YCbCr, p *ycc) *ycc {
+ var off int
+ Pix := p.Pix
+ Y := in.Y
+ Cb := in.Cb
+ Cr := in.Cr
+ for y := 0; y < in.Rect.Max.Y-in.Rect.Min.Y; y++ {
+ yy := y * in.YStride
+ cy := (y / 2) * in.CStride
+ for x := 0; x < in.Rect.Max.X-in.Rect.Min.X; x++ {
+ ci := cy + x/4
+ Pix[off+0] = Y[yy+x]
+ Pix[off+1] = Cb[ci]
+ Pix[off+2] = Cr[ci]
+ off += 3
+ }
+ }
+ return p
+}
diff --git a/vendor/github.com/rivo/uniseg/LICENSE.txt b/vendor/github.com/rivo/uniseg/LICENSE.txt
new file mode 100644
index 0000000..5040f1e
--- /dev/null
+++ b/vendor/github.com/rivo/uniseg/LICENSE.txt
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Oliver Kuederle
+
+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/vendor/github.com/rivo/uniseg/README.md b/vendor/github.com/rivo/uniseg/README.md
new file mode 100644
index 0000000..a8191b8
--- /dev/null
+++ b/vendor/github.com/rivo/uniseg/README.md
@@ -0,0 +1,137 @@
+# Unicode Text Segmentation for Go
+
+[](https://pkg.go.dev/github.com/rivo/uniseg)
+[](https://goreportcard.com/report/github.com/rivo/uniseg)
+
+This Go package implements Unicode Text Segmentation according to [Unicode Standard Annex #29](https://unicode.org/reports/tr29/), Unicode Line Breaking according to [Unicode Standard Annex #14](https://unicode.org/reports/tr14/) (Unicode version 15.0.0), and monospace font string width calculation similar to [wcwidth](https://man7.org/linux/man-pages/man3/wcwidth.3.html).
+
+## Background
+
+### Grapheme Clusters
+
+In Go, [strings are read-only slices of bytes](https://go.dev/blog/strings). They can be turned into Unicode code points using the `for` loop or by casting: `[]rune(str)`. However, multiple code points may be combined into one user-perceived character or what the Unicode specification calls "grapheme cluster". Here are some examples:
+
+|String|Bytes (UTF-8)|Code points (runes)|Grapheme clusters|
+|-|-|-|-|
+|Käse|6 bytes: `4b 61 cc 88 73 65`|5 code points: `4b 61 308 73 65`|4 clusters: `[4b],[61 308],[73],[65]`|
+|🏳️🌈|14 bytes: `f0 9f 8f b3 ef b8 8f e2 80 8d f0 9f 8c 88`|4 code points: `1f3f3 fe0f 200d 1f308`|1 cluster: `[1f3f3 fe0f 200d 1f308]`|
+|🇩🇪|8 bytes: `f0 9f 87 a9 f0 9f 87 aa`|2 code points: `1f1e9 1f1ea`|1 cluster: `[1f1e9 1f1ea]`|
+
+This package provides tools to iterate over these grapheme clusters. This may be used to determine the number of user-perceived characters, to split strings in their intended places, or to extract individual characters which form a unit.
+
+### Word Boundaries
+
+Word boundaries are used in a number of different contexts. The most familiar ones are selection (double-click mouse selection), cursor movement ("move to next word" control-arrow keys), and the dialog option "Whole Word Search" for search and replace. They are also used in database queries, to determine whether elements are within a certain number of words of one another. Searching may also use word boundaries in determining matching items. This package provides tools to determine word boundaries within strings.
+
+### Sentence Boundaries
+
+Sentence boundaries are often used for triple-click or some other method of selecting or iterating through blocks of text that are larger than single words. They are also used to determine whether words occur within the same sentence in database queries. This package provides tools to determine sentence boundaries within strings.
+
+### Line Breaking
+
+Line breaking, also known as word wrapping, is the process of breaking a section of text into lines such that it will fit in the available width of a page, window or other display area. This package provides tools to determine where a string may or may not be broken and where it must be broken (for example after newline characters).
+
+### Monospace Width
+
+Most terminals or text displays / text editors using a monospace font (for example source code editors) use a fixed width for each character. Some characters such as emojis or characters found in Asian and other languages may take up more than one character cell. This package provides tools to determine the number of cells a string will take up when displayed in a monospace font. See [here](https://pkg.go.dev/github.com/rivo/uniseg#hdr-Monospace_Width) for more information.
+
+## Installation
+
+```bash
+go get github.com/rivo/uniseg
+```
+
+## Examples
+
+### Counting Characters in a String
+
+```go
+n := uniseg.GraphemeClusterCount("🇩🇪🏳️🌈")
+fmt.Println(n)
+// 2
+```
+
+### Calculating the Monospace String Width
+
+```go
+width := uniseg.StringWidth("🇩🇪🏳️🌈!")
+fmt.Println(width)
+// 5
+```
+
+### Using the [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) Class
+
+This is the most convenient method of iterating over grapheme clusters:
+
+```go
+gr := uniseg.NewGraphemes("👍🏼!")
+for gr.Next() {
+ fmt.Printf("%x ", gr.Runes())
+}
+// [1f44d 1f3fc] [21]
+```
+
+### Using the [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step) or [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString) Function
+
+This avoids allocating a new `Graphemes` object but it requires the handling of states and boundaries:
+
+```go
+str := "🇩🇪🏳️🌈"
+state := -1
+var c string
+for len(str) > 0 {
+ c, str, _, state = uniseg.StepString(str, state)
+ fmt.Printf("%x ", []rune(c))
+}
+// [1f1e9 1f1ea] [1f3f3 fe0f 200d 1f308]
+```
+
+### Advanced Examples
+
+The [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) class offers the most convenient way to access all functionality of this package. But in some cases, it may be better to use the specialized functions directly. For example, if you're only interested in word segmentation, use [`FirstWord`](https://pkg.go.dev/github.com/rivo/uniseg#FirstWord) or [`FirstWordInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstWordInString):
+
+```go
+str := "Hello, world!"
+state := -1
+var c string
+for len(str) > 0 {
+ c, str, state = uniseg.FirstWordInString(str, state)
+ fmt.Printf("(%s)\n", c)
+}
+// (Hello)
+// (,)
+// ( )
+// (world)
+// (!)
+```
+
+Similarly, use
+
+- [`FirstGraphemeCluster`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeCluster) or [`FirstGraphemeClusterInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeClusterInString) for grapheme cluster determination only,
+- [`FirstSentence`](https://pkg.go.dev/github.com/rivo/uniseg#FirstSentence) or [`FirstSentenceInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstSentenceInString) for sentence segmentation only, and
+- [`FirstLineSegment`](https://pkg.go.dev/github.com/rivo/uniseg#FirstLineSegment) or [`FirstLineSegmentInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstLineSegmentInString) for line breaking / word wrapping (although using [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step) or [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString) is preferred as it will observe grapheme cluster boundaries).
+
+If you're only interested in the width of characters, use [`FirstGraphemeCluster`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeCluster) or [`FirstGraphemeClusterInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeClusterInString). It is much faster than using [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step), [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString), or the [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) class because it does not include the logic for word / sentence / line boundaries.
+
+Finally, if you need to reverse a string while preserving grapheme clusters, use [`ReverseString`](https://pkg.go.dev/github.com/rivo/uniseg#ReverseString):
+
+```go
+fmt.Println(uniseg.ReverseString("🇩🇪🏳️🌈"))
+// 🏳️🌈🇩🇪
+```
+
+## Documentation
+
+Refer to https://pkg.go.dev/github.com/rivo/uniseg for the package's documentation.
+
+## Dependencies
+
+This package does not depend on any packages outside the standard library.
+
+## Sponsor this Project
+
+[Become a Sponsor on GitHub](https://github.com/sponsors/rivo?metadata_source=uniseg_readme) to support this project!
+
+## Your Feedback
+
+Add your issue here on GitHub, preferably before submitting any PR's. Feel free to get in touch if you have any questions.
\ No newline at end of file
diff --git a/vendor/github.com/rivo/uniseg/doc.go b/vendor/github.com/rivo/uniseg/doc.go
new file mode 100644
index 0000000..11224ae
--- /dev/null
+++ b/vendor/github.com/rivo/uniseg/doc.go
@@ -0,0 +1,108 @@
+/*
+Package uniseg implements Unicode Text Segmentation, Unicode Line Breaking, and
+string width calculation for monospace fonts. Unicode Text Segmentation conforms
+to Unicode Standard Annex #29 (https://unicode.org/reports/tr29/) and Unicode
+Line Breaking conforms to Unicode Standard Annex #14
+(https://unicode.org/reports/tr14/).
+
+In short, using this package, you can split a string into grapheme clusters
+(what people would usually refer to as a "character"), into words, and into
+sentences. Or, in its simplest case, this package allows you to count the number
+of characters in a string, especially when it contains complex characters such
+as emojis, combining characters, or characters from Asian, Arabic, Hebrew, or
+other languages. Additionally, you can use it to implement line breaking (or
+"word wrapping"), that is, to determine where text can be broken over to the
+next line when the width of the line is not big enough to fit the entire text.
+Finally, you can use it to calculate the display width of a string for monospace
+fonts.
+
+# Getting Started
+
+If you just want to count the number of characters in a string, you can use
+[GraphemeClusterCount]. If you want to determine the display width of a string,
+you can use [StringWidth]. If you want to iterate over a string, you can use
+[Step], [StepString], or the [Graphemes] class (more convenient but less
+performant). This will provide you with all information: grapheme clusters,
+word boundaries, sentence boundaries, line breaks, and monospace character
+widths. The specialized functions [FirstGraphemeCluster],
+[FirstGraphemeClusterInString], [FirstWord], [FirstWordInString],
+[FirstSentence], and [FirstSentenceInString] can be used if only one type of
+information is needed.
+
+# Grapheme Clusters
+
+Consider the rainbow flag emoji: 🏳️🌈. On most modern systems, it appears as one
+character. But its string representation actually has 14 bytes, so counting
+bytes (or using len("🏳️🌈")) will not work as expected. Counting runes won't,
+either: The flag has 4 Unicode code points, thus 4 runes. The stdlib function
+utf8.RuneCountInString("🏳️🌈") and len([]rune("🏳️🌈")) will both return 4.
+
+The [GraphemeClusterCount] function will return 1 for the rainbow flag emoji.
+The Graphemes class and a variety of functions in this package will allow you to
+split strings into its grapheme clusters.
+
+# Word Boundaries
+
+Word boundaries are used in a number of different contexts. The most familiar
+ones are selection (double-click mouse selection), cursor movement ("move to
+next word" control-arrow keys), and the dialog option "Whole Word Search" for
+search and replace. This package provides methods for determining word
+boundaries.
+
+# Sentence Boundaries
+
+Sentence boundaries are often used for triple-click or some other method of
+selecting or iterating through blocks of text that are larger than single words.
+They are also used to determine whether words occur within the same sentence in
+database queries. This package provides methods for determining sentence
+boundaries.
+
+# Line Breaking
+
+Line breaking, also known as word wrapping, is the process of breaking a section
+of text into lines such that it will fit in the available width of a page,
+window or other display area. This package provides methods to determine the
+positions in a string where a line must be broken, may be broken, or must not be
+broken.
+
+# Monospace Width
+
+Monospace width, as referred to in this package, is the width of a string in a
+monospace font. This is commonly used in terminal user interfaces or text
+displays or editors that don't support proportional fonts. A width of 1
+corresponds to a single character cell. The C function [wcswidth()] and its
+implementation in other programming languages is in widespread use for the same
+purpose. However, there is no standard for the calculation of such widths, and
+this package differs from wcswidth() in a number of ways, presumably to generate
+more visually pleasing results.
+
+To start, we assume that every code point has a width of 1, with the following
+exceptions:
+
+ - Code points with grapheme cluster break properties Control, CR, LF, Extend,
+ and ZWJ have a width of 0.
+ - U+2E3A, Two-Em Dash, has a width of 3.
+ - U+2E3B, Three-Em Dash, has a width of 4.
+ - Characters with the East-Asian Width properties "Fullwidth" (F) and "Wide"
+ (W) have a width of 2. (Properties "Ambiguous" (A) and "Neutral" (N) both
+ have a width of 1.)
+ - Code points with grapheme cluster break property Regional Indicator have a
+ width of 2.
+ - Code points with grapheme cluster break property Extended Pictographic have
+ a width of 2, unless their Emoji Presentation flag is "No", in which case
+ the width is 1.
+
+For Hangul grapheme clusters composed of conjoining Jamo and for Regional
+Indicators (flags), all code points except the first one have a width of 0. For
+grapheme clusters starting with an Extended Pictographic, any additional code
+point will force a total width of 2, except if the Variation Selector-15
+(U+FE0E) is included, in which case the total width is always 1. Grapheme
+clusters ending with Variation Selector-16 (U+FE0F) have a width of 2.
+
+Note that whether these widths appear correct depends on your application's
+render engine, to which extent it conforms to the Unicode Standard, and its
+choice of font.
+
+[wcswidth()]: https://man7.org/linux/man-pages/man3/wcswidth.3.html
+*/
+package uniseg
diff --git a/vendor/github.com/rivo/uniseg/eastasianwidth.go b/vendor/github.com/rivo/uniseg/eastasianwidth.go
new file mode 100644
index 0000000..5fc54d9
--- /dev/null
+++ b/vendor/github.com/rivo/uniseg/eastasianwidth.go
@@ -0,0 +1,2588 @@
+// Code generated via go generate from gen_properties.go. DO NOT EDIT.
+
+package uniseg
+
+// eastAsianWidth are taken from
+// https://www.unicode.org/Public/15.0.0/ucd/EastAsianWidth.txt
+// and
+// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt
+// ("Extended_Pictographic" only)
+// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode
+// license agreement.
+var eastAsianWidth = [][3]int{
+ {0x0000, 0x001F, prN}, // Cc [32] ..
+ {0x0020, 0x0020, prNa}, // Zs SPACE
+ {0x0021, 0x0023, prNa}, // Po [3] EXCLAMATION MARK..NUMBER SIGN
+ {0x0024, 0x0024, prNa}, // Sc DOLLAR SIGN
+ {0x0025, 0x0027, prNa}, // Po [3] PERCENT SIGN..APOSTROPHE
+ {0x0028, 0x0028, prNa}, // Ps LEFT PARENTHESIS
+ {0x0029, 0x0029, prNa}, // Pe RIGHT PARENTHESIS
+ {0x002A, 0x002A, prNa}, // Po ASTERISK
+ {0x002B, 0x002B, prNa}, // Sm PLUS SIGN
+ {0x002C, 0x002C, prNa}, // Po COMMA
+ {0x002D, 0x002D, prNa}, // Pd HYPHEN-MINUS
+ {0x002E, 0x002F, prNa}, // Po [2] FULL STOP..SOLIDUS
+ {0x0030, 0x0039, prNa}, // Nd [10] DIGIT ZERO..DIGIT NINE
+ {0x003A, 0x003B, prNa}, // Po [2] COLON..SEMICOLON
+ {0x003C, 0x003E, prNa}, // Sm [3] LESS-THAN SIGN..GREATER-THAN SIGN
+ {0x003F, 0x0040, prNa}, // Po [2] QUESTION MARK..COMMERCIAL AT
+ {0x0041, 0x005A, prNa}, // Lu [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z
+ {0x005B, 0x005B, prNa}, // Ps LEFT SQUARE BRACKET
+ {0x005C, 0x005C, prNa}, // Po REVERSE SOLIDUS
+ {0x005D, 0x005D, prNa}, // Pe RIGHT SQUARE BRACKET
+ {0x005E, 0x005E, prNa}, // Sk CIRCUMFLEX ACCENT
+ {0x005F, 0x005F, prNa}, // Pc LOW LINE
+ {0x0060, 0x0060, prNa}, // Sk GRAVE ACCENT
+ {0x0061, 0x007A, prNa}, // Ll [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z
+ {0x007B, 0x007B, prNa}, // Ps LEFT CURLY BRACKET
+ {0x007C, 0x007C, prNa}, // Sm VERTICAL LINE
+ {0x007D, 0x007D, prNa}, // Pe RIGHT CURLY BRACKET
+ {0x007E, 0x007E, prNa}, // Sm TILDE
+ {0x007F, 0x007F, prN}, // Cc
+ {0x0080, 0x009F, prN}, // Cc [32] ..
+ {0x00A0, 0x00A0, prN}, // Zs NO-BREAK SPACE
+ {0x00A1, 0x00A1, prA}, // Po INVERTED EXCLAMATION MARK
+ {0x00A2, 0x00A3, prNa}, // Sc [2] CENT SIGN..POUND SIGN
+ {0x00A4, 0x00A4, prA}, // Sc CURRENCY SIGN
+ {0x00A5, 0x00A5, prNa}, // Sc YEN SIGN
+ {0x00A6, 0x00A6, prNa}, // So BROKEN BAR
+ {0x00A7, 0x00A7, prA}, // Po SECTION SIGN
+ {0x00A8, 0x00A8, prA}, // Sk DIAERESIS
+ {0x00A9, 0x00A9, prN}, // So COPYRIGHT SIGN
+ {0x00AA, 0x00AA, prA}, // Lo FEMININE ORDINAL INDICATOR
+ {0x00AB, 0x00AB, prN}, // Pi LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+ {0x00AC, 0x00AC, prNa}, // Sm NOT SIGN
+ {0x00AD, 0x00AD, prA}, // Cf SOFT HYPHEN
+ {0x00AE, 0x00AE, prA}, // So REGISTERED SIGN
+ {0x00AF, 0x00AF, prNa}, // Sk MACRON
+ {0x00B0, 0x00B0, prA}, // So DEGREE SIGN
+ {0x00B1, 0x00B1, prA}, // Sm PLUS-MINUS SIGN
+ {0x00B2, 0x00B3, prA}, // No [2] SUPERSCRIPT TWO..SUPERSCRIPT THREE
+ {0x00B4, 0x00B4, prA}, // Sk ACUTE ACCENT
+ {0x00B5, 0x00B5, prN}, // Ll MICRO SIGN
+ {0x00B6, 0x00B7, prA}, // Po [2] PILCROW SIGN..MIDDLE DOT
+ {0x00B8, 0x00B8, prA}, // Sk CEDILLA
+ {0x00B9, 0x00B9, prA}, // No SUPERSCRIPT ONE
+ {0x00BA, 0x00BA, prA}, // Lo MASCULINE ORDINAL INDICATOR
+ {0x00BB, 0x00BB, prN}, // Pf RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+ {0x00BC, 0x00BE, prA}, // No [3] VULGAR FRACTION ONE QUARTER..VULGAR FRACTION THREE QUARTERS
+ {0x00BF, 0x00BF, prA}, // Po INVERTED QUESTION MARK
+ {0x00C0, 0x00C5, prN}, // Lu [6] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER A WITH RING ABOVE
+ {0x00C6, 0x00C6, prA}, // Lu LATIN CAPITAL LETTER AE
+ {0x00C7, 0x00CF, prN}, // Lu [9] LATIN CAPITAL LETTER C WITH CEDILLA..LATIN CAPITAL LETTER I WITH DIAERESIS
+ {0x00D0, 0x00D0, prA}, // Lu LATIN CAPITAL LETTER ETH
+ {0x00D1, 0x00D6, prN}, // Lu [6] LATIN CAPITAL LETTER N WITH TILDE..LATIN CAPITAL LETTER O WITH DIAERESIS
+ {0x00D7, 0x00D7, prA}, // Sm MULTIPLICATION SIGN
+ {0x00D8, 0x00D8, prA}, // Lu LATIN CAPITAL LETTER O WITH STROKE
+ {0x00D9, 0x00DD, prN}, // Lu [5] LATIN CAPITAL LETTER U WITH GRAVE..LATIN CAPITAL LETTER Y WITH ACUTE
+ {0x00DE, 0x00E1, prA}, // L& [4] LATIN CAPITAL LETTER THORN..LATIN SMALL LETTER A WITH ACUTE
+ {0x00E2, 0x00E5, prN}, // Ll [4] LATIN SMALL LETTER A WITH CIRCUMFLEX..LATIN SMALL LETTER A WITH RING ABOVE
+ {0x00E6, 0x00E6, prA}, // Ll LATIN SMALL LETTER AE
+ {0x00E7, 0x00E7, prN}, // Ll LATIN SMALL LETTER C WITH CEDILLA
+ {0x00E8, 0x00EA, prA}, // Ll [3] LATIN SMALL LETTER E WITH GRAVE..LATIN SMALL LETTER E WITH CIRCUMFLEX
+ {0x00EB, 0x00EB, prN}, // Ll LATIN SMALL LETTER E WITH DIAERESIS
+ {0x00EC, 0x00ED, prA}, // Ll [2] LATIN SMALL LETTER I WITH GRAVE..LATIN SMALL LETTER I WITH ACUTE
+ {0x00EE, 0x00EF, prN}, // Ll [2] LATIN SMALL LETTER I WITH CIRCUMFLEX..LATIN SMALL LETTER I WITH DIAERESIS
+ {0x00F0, 0x00F0, prA}, // Ll LATIN SMALL LETTER ETH
+ {0x00F1, 0x00F1, prN}, // Ll LATIN SMALL LETTER N WITH TILDE
+ {0x00F2, 0x00F3, prA}, // Ll [2] LATIN SMALL LETTER O WITH GRAVE..LATIN SMALL LETTER O WITH ACUTE
+ {0x00F4, 0x00F6, prN}, // Ll [3] LATIN SMALL LETTER O WITH CIRCUMFLEX..LATIN SMALL LETTER O WITH DIAERESIS
+ {0x00F7, 0x00F7, prA}, // Sm DIVISION SIGN
+ {0x00F8, 0x00FA, prA}, // Ll [3] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER U WITH ACUTE
+ {0x00FB, 0x00FB, prN}, // Ll LATIN SMALL LETTER U WITH CIRCUMFLEX
+ {0x00FC, 0x00FC, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS
+ {0x00FD, 0x00FD, prN}, // Ll LATIN SMALL LETTER Y WITH ACUTE
+ {0x00FE, 0x00FE, prA}, // Ll LATIN SMALL LETTER THORN
+ {0x00FF, 0x00FF, prN}, // Ll LATIN SMALL LETTER Y WITH DIAERESIS
+ {0x0100, 0x0100, prN}, // Lu LATIN CAPITAL LETTER A WITH MACRON
+ {0x0101, 0x0101, prA}, // Ll LATIN SMALL LETTER A WITH MACRON
+ {0x0102, 0x0110, prN}, // L& [15] LATIN CAPITAL LETTER A WITH BREVE..LATIN CAPITAL LETTER D WITH STROKE
+ {0x0111, 0x0111, prA}, // Ll LATIN SMALL LETTER D WITH STROKE
+ {0x0112, 0x0112, prN}, // Lu LATIN CAPITAL LETTER E WITH MACRON
+ {0x0113, 0x0113, prA}, // Ll LATIN SMALL LETTER E WITH MACRON
+ {0x0114, 0x011A, prN}, // L& [7] LATIN CAPITAL LETTER E WITH BREVE..LATIN CAPITAL LETTER E WITH CARON
+ {0x011B, 0x011B, prA}, // Ll LATIN SMALL LETTER E WITH CARON
+ {0x011C, 0x0125, prN}, // L& [10] LATIN CAPITAL LETTER G WITH CIRCUMFLEX..LATIN SMALL LETTER H WITH CIRCUMFLEX
+ {0x0126, 0x0127, prA}, // L& [2] LATIN CAPITAL LETTER H WITH STROKE..LATIN SMALL LETTER H WITH STROKE
+ {0x0128, 0x012A, prN}, // L& [3] LATIN CAPITAL LETTER I WITH TILDE..LATIN CAPITAL LETTER I WITH MACRON
+ {0x012B, 0x012B, prA}, // Ll LATIN SMALL LETTER I WITH MACRON
+ {0x012C, 0x0130, prN}, // L& [5] LATIN CAPITAL LETTER I WITH BREVE..LATIN CAPITAL LETTER I WITH DOT ABOVE
+ {0x0131, 0x0133, prA}, // L& [3] LATIN SMALL LETTER DOTLESS I..LATIN SMALL LIGATURE IJ
+ {0x0134, 0x0137, prN}, // L& [4] LATIN CAPITAL LETTER J WITH CIRCUMFLEX..LATIN SMALL LETTER K WITH CEDILLA
+ {0x0138, 0x0138, prA}, // Ll LATIN SMALL LETTER KRA
+ {0x0139, 0x013E, prN}, // L& [6] LATIN CAPITAL LETTER L WITH ACUTE..LATIN SMALL LETTER L WITH CARON
+ {0x013F, 0x0142, prA}, // L& [4] LATIN CAPITAL LETTER L WITH MIDDLE DOT..LATIN SMALL LETTER L WITH STROKE
+ {0x0143, 0x0143, prN}, // Lu LATIN CAPITAL LETTER N WITH ACUTE
+ {0x0144, 0x0144, prA}, // Ll LATIN SMALL LETTER N WITH ACUTE
+ {0x0145, 0x0147, prN}, // L& [3] LATIN CAPITAL LETTER N WITH CEDILLA..LATIN CAPITAL LETTER N WITH CARON
+ {0x0148, 0x014B, prA}, // L& [4] LATIN SMALL LETTER N WITH CARON..LATIN SMALL LETTER ENG
+ {0x014C, 0x014C, prN}, // Lu LATIN CAPITAL LETTER O WITH MACRON
+ {0x014D, 0x014D, prA}, // Ll LATIN SMALL LETTER O WITH MACRON
+ {0x014E, 0x0151, prN}, // L& [4] LATIN CAPITAL LETTER O WITH BREVE..LATIN SMALL LETTER O WITH DOUBLE ACUTE
+ {0x0152, 0x0153, prA}, // L& [2] LATIN CAPITAL LIGATURE OE..LATIN SMALL LIGATURE OE
+ {0x0154, 0x0165, prN}, // L& [18] LATIN CAPITAL LETTER R WITH ACUTE..LATIN SMALL LETTER T WITH CARON
+ {0x0166, 0x0167, prA}, // L& [2] LATIN CAPITAL LETTER T WITH STROKE..LATIN SMALL LETTER T WITH STROKE
+ {0x0168, 0x016A, prN}, // L& [3] LATIN CAPITAL LETTER U WITH TILDE..LATIN CAPITAL LETTER U WITH MACRON
+ {0x016B, 0x016B, prA}, // Ll LATIN SMALL LETTER U WITH MACRON
+ {0x016C, 0x017F, prN}, // L& [20] LATIN CAPITAL LETTER U WITH BREVE..LATIN SMALL LETTER LONG S
+ {0x0180, 0x01BA, prN}, // L& [59] LATIN SMALL LETTER B WITH STROKE..LATIN SMALL LETTER EZH WITH TAIL
+ {0x01BB, 0x01BB, prN}, // Lo LATIN LETTER TWO WITH STROKE
+ {0x01BC, 0x01BF, prN}, // L& [4] LATIN CAPITAL LETTER TONE FIVE..LATIN LETTER WYNN
+ {0x01C0, 0x01C3, prN}, // Lo [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK
+ {0x01C4, 0x01CD, prN}, // L& [10] LATIN CAPITAL LETTER DZ WITH CARON..LATIN CAPITAL LETTER A WITH CARON
+ {0x01CE, 0x01CE, prA}, // Ll LATIN SMALL LETTER A WITH CARON
+ {0x01CF, 0x01CF, prN}, // Lu LATIN CAPITAL LETTER I WITH CARON
+ {0x01D0, 0x01D0, prA}, // Ll LATIN SMALL LETTER I WITH CARON
+ {0x01D1, 0x01D1, prN}, // Lu LATIN CAPITAL LETTER O WITH CARON
+ {0x01D2, 0x01D2, prA}, // Ll LATIN SMALL LETTER O WITH CARON
+ {0x01D3, 0x01D3, prN}, // Lu LATIN CAPITAL LETTER U WITH CARON
+ {0x01D4, 0x01D4, prA}, // Ll LATIN SMALL LETTER U WITH CARON
+ {0x01D5, 0x01D5, prN}, // Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
+ {0x01D6, 0x01D6, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
+ {0x01D7, 0x01D7, prN}, // Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
+ {0x01D8, 0x01D8, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
+ {0x01D9, 0x01D9, prN}, // Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
+ {0x01DA, 0x01DA, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS AND CARON
+ {0x01DB, 0x01DB, prN}, // Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
+ {0x01DC, 0x01DC, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
+ {0x01DD, 0x024F, prN}, // L& [115] LATIN SMALL LETTER TURNED E..LATIN SMALL LETTER Y WITH STROKE
+ {0x0250, 0x0250, prN}, // Ll LATIN SMALL LETTER TURNED A
+ {0x0251, 0x0251, prA}, // Ll LATIN SMALL LETTER ALPHA
+ {0x0252, 0x0260, prN}, // Ll [15] LATIN SMALL LETTER TURNED ALPHA..LATIN SMALL LETTER G WITH HOOK
+ {0x0261, 0x0261, prA}, // Ll LATIN SMALL LETTER SCRIPT G
+ {0x0262, 0x0293, prN}, // Ll [50] LATIN LETTER SMALL CAPITAL G..LATIN SMALL LETTER EZH WITH CURL
+ {0x0294, 0x0294, prN}, // Lo LATIN LETTER GLOTTAL STOP
+ {0x0295, 0x02AF, prN}, // Ll [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL
+ {0x02B0, 0x02C1, prN}, // Lm [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP
+ {0x02C2, 0x02C3, prN}, // Sk [2] MODIFIER LETTER LEFT ARROWHEAD..MODIFIER LETTER RIGHT ARROWHEAD
+ {0x02C4, 0x02C4, prA}, // Sk MODIFIER LETTER UP ARROWHEAD
+ {0x02C5, 0x02C5, prN}, // Sk MODIFIER LETTER DOWN ARROWHEAD
+ {0x02C6, 0x02C6, prN}, // Lm MODIFIER LETTER CIRCUMFLEX ACCENT
+ {0x02C7, 0x02C7, prA}, // Lm CARON
+ {0x02C8, 0x02C8, prN}, // Lm MODIFIER LETTER VERTICAL LINE
+ {0x02C9, 0x02CB, prA}, // Lm [3] MODIFIER LETTER MACRON..MODIFIER LETTER GRAVE ACCENT
+ {0x02CC, 0x02CC, prN}, // Lm MODIFIER LETTER LOW VERTICAL LINE
+ {0x02CD, 0x02CD, prA}, // Lm MODIFIER LETTER LOW MACRON
+ {0x02CE, 0x02CF, prN}, // Lm [2] MODIFIER LETTER LOW GRAVE ACCENT..MODIFIER LETTER LOW ACUTE ACCENT
+ {0x02D0, 0x02D0, prA}, // Lm MODIFIER LETTER TRIANGULAR COLON
+ {0x02D1, 0x02D1, prN}, // Lm MODIFIER LETTER HALF TRIANGULAR COLON
+ {0x02D2, 0x02D7, prN}, // Sk [6] MODIFIER LETTER CENTRED RIGHT HALF RING..MODIFIER LETTER MINUS SIGN
+ {0x02D8, 0x02DB, prA}, // Sk [4] BREVE..OGONEK
+ {0x02DC, 0x02DC, prN}, // Sk SMALL TILDE
+ {0x02DD, 0x02DD, prA}, // Sk DOUBLE ACUTE ACCENT
+ {0x02DE, 0x02DE, prN}, // Sk MODIFIER LETTER RHOTIC HOOK
+ {0x02DF, 0x02DF, prA}, // Sk MODIFIER LETTER CROSS ACCENT
+ {0x02E0, 0x02E4, prN}, // Lm [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP
+ {0x02E5, 0x02EB, prN}, // Sk [7] MODIFIER LETTER EXTRA-HIGH TONE BAR..MODIFIER LETTER YANG DEPARTING TONE MARK
+ {0x02EC, 0x02EC, prN}, // Lm MODIFIER LETTER VOICING
+ {0x02ED, 0x02ED, prN}, // Sk MODIFIER LETTER UNASPIRATED
+ {0x02EE, 0x02EE, prN}, // Lm MODIFIER LETTER DOUBLE APOSTROPHE
+ {0x02EF, 0x02FF, prN}, // Sk [17] MODIFIER LETTER LOW DOWN ARROWHEAD..MODIFIER LETTER LOW LEFT ARROW
+ {0x0300, 0x036F, prA}, // Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X
+ {0x0370, 0x0373, prN}, // L& [4] GREEK CAPITAL LETTER HETA..GREEK SMALL LETTER ARCHAIC SAMPI
+ {0x0374, 0x0374, prN}, // Lm GREEK NUMERAL SIGN
+ {0x0375, 0x0375, prN}, // Sk GREEK LOWER NUMERAL SIGN
+ {0x0376, 0x0377, prN}, // L& [2] GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA..GREEK SMALL LETTER PAMPHYLIAN DIGAMMA
+ {0x037A, 0x037A, prN}, // Lm GREEK YPOGEGRAMMENI
+ {0x037B, 0x037D, prN}, // Ll [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL
+ {0x037E, 0x037E, prN}, // Po GREEK QUESTION MARK
+ {0x037F, 0x037F, prN}, // Lu GREEK CAPITAL LETTER YOT
+ {0x0384, 0x0385, prN}, // Sk [2] GREEK TONOS..GREEK DIALYTIKA TONOS
+ {0x0386, 0x0386, prN}, // Lu GREEK CAPITAL LETTER ALPHA WITH TONOS
+ {0x0387, 0x0387, prN}, // Po GREEK ANO TELEIA
+ {0x0388, 0x038A, prN}, // Lu [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS
+ {0x038C, 0x038C, prN}, // Lu GREEK CAPITAL LETTER OMICRON WITH TONOS
+ {0x038E, 0x0390, prN}, // L& [3] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+ {0x0391, 0x03A1, prA}, // Lu [17] GREEK CAPITAL LETTER ALPHA..GREEK CAPITAL LETTER RHO
+ {0x03A3, 0x03A9, prA}, // Lu [7] GREEK CAPITAL LETTER SIGMA..GREEK CAPITAL LETTER OMEGA
+ {0x03AA, 0x03B0, prN}, // L& [7] GREEK CAPITAL LETTER IOTA WITH DIALYTIKA..GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+ {0x03B1, 0x03C1, prA}, // Ll [17] GREEK SMALL LETTER ALPHA..GREEK SMALL LETTER RHO
+ {0x03C2, 0x03C2, prN}, // Ll GREEK SMALL LETTER FINAL SIGMA
+ {0x03C3, 0x03C9, prA}, // Ll [7] GREEK SMALL LETTER SIGMA..GREEK SMALL LETTER OMEGA
+ {0x03CA, 0x03F5, prN}, // L& [44] GREEK SMALL LETTER IOTA WITH DIALYTIKA..GREEK LUNATE EPSILON SYMBOL
+ {0x03F6, 0x03F6, prN}, // Sm GREEK REVERSED LUNATE EPSILON SYMBOL
+ {0x03F7, 0x03FF, prN}, // L& [9] GREEK CAPITAL LETTER SHO..GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL
+ {0x0400, 0x0400, prN}, // Lu CYRILLIC CAPITAL LETTER IE WITH GRAVE
+ {0x0401, 0x0401, prA}, // Lu CYRILLIC CAPITAL LETTER IO
+ {0x0402, 0x040F, prN}, // Lu [14] CYRILLIC CAPITAL LETTER DJE..CYRILLIC CAPITAL LETTER DZHE
+ {0x0410, 0x044F, prA}, // L& [64] CYRILLIC CAPITAL LETTER A..CYRILLIC SMALL LETTER YA
+ {0x0450, 0x0450, prN}, // Ll CYRILLIC SMALL LETTER IE WITH GRAVE
+ {0x0451, 0x0451, prA}, // Ll CYRILLIC SMALL LETTER IO
+ {0x0452, 0x0481, prN}, // L& [48] CYRILLIC SMALL LETTER DJE..CYRILLIC SMALL LETTER KOPPA
+ {0x0482, 0x0482, prN}, // So CYRILLIC THOUSANDS SIGN
+ {0x0483, 0x0487, prN}, // Mn [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE
+ {0x0488, 0x0489, prN}, // Me [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN
+ {0x048A, 0x04FF, prN}, // L& [118] CYRILLIC CAPITAL LETTER SHORT I WITH TAIL..CYRILLIC SMALL LETTER HA WITH STROKE
+ {0x0500, 0x052F, prN}, // L& [48] CYRILLIC CAPITAL LETTER KOMI DE..CYRILLIC SMALL LETTER EL WITH DESCENDER
+ {0x0531, 0x0556, prN}, // Lu [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH
+ {0x0559, 0x0559, prN}, // Lm ARMENIAN MODIFIER LETTER LEFT HALF RING
+ {0x055A, 0x055F, prN}, // Po [6] ARMENIAN APOSTROPHE..ARMENIAN ABBREVIATION MARK
+ {0x0560, 0x0588, prN}, // Ll [41] ARMENIAN SMALL LETTER TURNED AYB..ARMENIAN SMALL LETTER YI WITH STROKE
+ {0x0589, 0x0589, prN}, // Po ARMENIAN FULL STOP
+ {0x058A, 0x058A, prN}, // Pd ARMENIAN HYPHEN
+ {0x058D, 0x058E, prN}, // So [2] RIGHT-FACING ARMENIAN ETERNITY SIGN..LEFT-FACING ARMENIAN ETERNITY SIGN
+ {0x058F, 0x058F, prN}, // Sc ARMENIAN DRAM SIGN
+ {0x0591, 0x05BD, prN}, // Mn [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG
+ {0x05BE, 0x05BE, prN}, // Pd HEBREW PUNCTUATION MAQAF
+ {0x05BF, 0x05BF, prN}, // Mn HEBREW POINT RAFE
+ {0x05C0, 0x05C0, prN}, // Po HEBREW PUNCTUATION PASEQ
+ {0x05C1, 0x05C2, prN}, // Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT
+ {0x05C3, 0x05C3, prN}, // Po HEBREW PUNCTUATION SOF PASUQ
+ {0x05C4, 0x05C5, prN}, // Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT
+ {0x05C6, 0x05C6, prN}, // Po HEBREW PUNCTUATION NUN HAFUKHA
+ {0x05C7, 0x05C7, prN}, // Mn HEBREW POINT QAMATS QATAN
+ {0x05D0, 0x05EA, prN}, // Lo [27] HEBREW LETTER ALEF..HEBREW LETTER TAV
+ {0x05EF, 0x05F2, prN}, // Lo [4] HEBREW YOD TRIANGLE..HEBREW LIGATURE YIDDISH DOUBLE YOD
+ {0x05F3, 0x05F4, prN}, // Po [2] HEBREW PUNCTUATION GERESH..HEBREW PUNCTUATION GERSHAYIM
+ {0x0600, 0x0605, prN}, // Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE
+ {0x0606, 0x0608, prN}, // Sm [3] ARABIC-INDIC CUBE ROOT..ARABIC RAY
+ {0x0609, 0x060A, prN}, // Po [2] ARABIC-INDIC PER MILLE SIGN..ARABIC-INDIC PER TEN THOUSAND SIGN
+ {0x060B, 0x060B, prN}, // Sc AFGHANI SIGN
+ {0x060C, 0x060D, prN}, // Po [2] ARABIC COMMA..ARABIC DATE SEPARATOR
+ {0x060E, 0x060F, prN}, // So [2] ARABIC POETIC VERSE SIGN..ARABIC SIGN MISRA
+ {0x0610, 0x061A, prN}, // Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA
+ {0x061B, 0x061B, prN}, // Po ARABIC SEMICOLON
+ {0x061C, 0x061C, prN}, // Cf ARABIC LETTER MARK
+ {0x061D, 0x061F, prN}, // Po [3] ARABIC END OF TEXT MARK..ARABIC QUESTION MARK
+ {0x0620, 0x063F, prN}, // Lo [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE
+ {0x0640, 0x0640, prN}, // Lm ARABIC TATWEEL
+ {0x0641, 0x064A, prN}, // Lo [10] ARABIC LETTER FEH..ARABIC LETTER YEH
+ {0x064B, 0x065F, prN}, // Mn [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW
+ {0x0660, 0x0669, prN}, // Nd [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE
+ {0x066A, 0x066D, prN}, // Po [4] ARABIC PERCENT SIGN..ARABIC FIVE POINTED STAR
+ {0x066E, 0x066F, prN}, // Lo [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF
+ {0x0670, 0x0670, prN}, // Mn ARABIC LETTER SUPERSCRIPT ALEF
+ {0x0671, 0x06D3, prN}, // Lo [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE
+ {0x06D4, 0x06D4, prN}, // Po ARABIC FULL STOP
+ {0x06D5, 0x06D5, prN}, // Lo ARABIC LETTER AE
+ {0x06D6, 0x06DC, prN}, // Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN
+ {0x06DD, 0x06DD, prN}, // Cf ARABIC END OF AYAH
+ {0x06DE, 0x06DE, prN}, // So ARABIC START OF RUB EL HIZB
+ {0x06DF, 0x06E4, prN}, // Mn [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA
+ {0x06E5, 0x06E6, prN}, // Lm [2] ARABIC SMALL WAW..ARABIC SMALL YEH
+ {0x06E7, 0x06E8, prN}, // Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON
+ {0x06E9, 0x06E9, prN}, // So ARABIC PLACE OF SAJDAH
+ {0x06EA, 0x06ED, prN}, // Mn [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM
+ {0x06EE, 0x06EF, prN}, // Lo [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V
+ {0x06F0, 0x06F9, prN}, // Nd [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE
+ {0x06FA, 0x06FC, prN}, // Lo [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW
+ {0x06FD, 0x06FE, prN}, // So [2] ARABIC SIGN SINDHI AMPERSAND..ARABIC SIGN SINDHI POSTPOSITION MEN
+ {0x06FF, 0x06FF, prN}, // Lo ARABIC LETTER HEH WITH INVERTED V
+ {0x0700, 0x070D, prN}, // Po [14] SYRIAC END OF PARAGRAPH..SYRIAC HARKLEAN ASTERISCUS
+ {0x070F, 0x070F, prN}, // Cf SYRIAC ABBREVIATION MARK
+ {0x0710, 0x0710, prN}, // Lo SYRIAC LETTER ALAPH
+ {0x0711, 0x0711, prN}, // Mn SYRIAC LETTER SUPERSCRIPT ALAPH
+ {0x0712, 0x072F, prN}, // Lo [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH
+ {0x0730, 0x074A, prN}, // Mn [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH
+ {0x074D, 0x074F, prN}, // Lo [3] SYRIAC LETTER SOGDIAN ZHAIN..SYRIAC LETTER SOGDIAN FE
+ {0x0750, 0x077F, prN}, // Lo [48] ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS ABOVE
+ {0x0780, 0x07A5, prN}, // Lo [38] THAANA LETTER HAA..THAANA LETTER WAAVU
+ {0x07A6, 0x07B0, prN}, // Mn [11] THAANA ABAFILI..THAANA SUKUN
+ {0x07B1, 0x07B1, prN}, // Lo THAANA LETTER NAA
+ {0x07C0, 0x07C9, prN}, // Nd [10] NKO DIGIT ZERO..NKO DIGIT NINE
+ {0x07CA, 0x07EA, prN}, // Lo [33] NKO LETTER A..NKO LETTER JONA RA
+ {0x07EB, 0x07F3, prN}, // Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE
+ {0x07F4, 0x07F5, prN}, // Lm [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE
+ {0x07F6, 0x07F6, prN}, // So NKO SYMBOL OO DENNEN
+ {0x07F7, 0x07F9, prN}, // Po [3] NKO SYMBOL GBAKURUNEN..NKO EXCLAMATION MARK
+ {0x07FA, 0x07FA, prN}, // Lm NKO LAJANYALAN
+ {0x07FD, 0x07FD, prN}, // Mn NKO DANTAYALAN
+ {0x07FE, 0x07FF, prN}, // Sc [2] NKO DOROME SIGN..NKO TAMAN SIGN
+ {0x0800, 0x0815, prN}, // Lo [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF
+ {0x0816, 0x0819, prN}, // Mn [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH
+ {0x081A, 0x081A, prN}, // Lm SAMARITAN MODIFIER LETTER EPENTHETIC YUT
+ {0x081B, 0x0823, prN}, // Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A
+ {0x0824, 0x0824, prN}, // Lm SAMARITAN MODIFIER LETTER SHORT A
+ {0x0825, 0x0827, prN}, // Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U
+ {0x0828, 0x0828, prN}, // Lm SAMARITAN MODIFIER LETTER I
+ {0x0829, 0x082D, prN}, // Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA
+ {0x0830, 0x083E, prN}, // Po [15] SAMARITAN PUNCTUATION NEQUDAA..SAMARITAN PUNCTUATION ANNAAU
+ {0x0840, 0x0858, prN}, // Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN
+ {0x0859, 0x085B, prN}, // Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK
+ {0x085E, 0x085E, prN}, // Po MANDAIC PUNCTUATION
+ {0x0860, 0x086A, prN}, // Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA
+ {0x0870, 0x0887, prN}, // Lo [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT
+ {0x0888, 0x0888, prN}, // Sk ARABIC RAISED ROUND DOT
+ {0x0889, 0x088E, prN}, // Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL
+ {0x0890, 0x0891, prN}, // Cf [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE
+ {0x0898, 0x089F, prN}, // Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA
+ {0x08A0, 0x08C8, prN}, // Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF
+ {0x08C9, 0x08C9, prN}, // Lm ARABIC SMALL FARSI YEH
+ {0x08CA, 0x08E1, prN}, // Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA
+ {0x08E2, 0x08E2, prN}, // Cf ARABIC DISPUTED END OF AYAH
+ {0x08E3, 0x08FF, prN}, // Mn [29] ARABIC TURNED DAMMA BELOW..ARABIC MARK SIDEWAYS NOON GHUNNA
+ {0x0900, 0x0902, prN}, // Mn [3] DEVANAGARI SIGN INVERTED CANDRABINDU..DEVANAGARI SIGN ANUSVARA
+ {0x0903, 0x0903, prN}, // Mc DEVANAGARI SIGN VISARGA
+ {0x0904, 0x0939, prN}, // Lo [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA
+ {0x093A, 0x093A, prN}, // Mn DEVANAGARI VOWEL SIGN OE
+ {0x093B, 0x093B, prN}, // Mc DEVANAGARI VOWEL SIGN OOE
+ {0x093C, 0x093C, prN}, // Mn DEVANAGARI SIGN NUKTA
+ {0x093D, 0x093D, prN}, // Lo DEVANAGARI SIGN AVAGRAHA
+ {0x093E, 0x0940, prN}, // Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II
+ {0x0941, 0x0948, prN}, // Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI
+ {0x0949, 0x094C, prN}, // Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU
+ {0x094D, 0x094D, prN}, // Mn DEVANAGARI SIGN VIRAMA
+ {0x094E, 0x094F, prN}, // Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW
+ {0x0950, 0x0950, prN}, // Lo DEVANAGARI OM
+ {0x0951, 0x0957, prN}, // Mn [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE
+ {0x0958, 0x0961, prN}, // Lo [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL
+ {0x0962, 0x0963, prN}, // Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL
+ {0x0964, 0x0965, prN}, // Po [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA
+ {0x0966, 0x096F, prN}, // Nd [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE
+ {0x0970, 0x0970, prN}, // Po DEVANAGARI ABBREVIATION SIGN
+ {0x0971, 0x0971, prN}, // Lm DEVANAGARI SIGN HIGH SPACING DOT
+ {0x0972, 0x097F, prN}, // Lo [14] DEVANAGARI LETTER CANDRA A..DEVANAGARI LETTER BBA
+ {0x0980, 0x0980, prN}, // Lo BENGALI ANJI
+ {0x0981, 0x0981, prN}, // Mn BENGALI SIGN CANDRABINDU
+ {0x0982, 0x0983, prN}, // Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA
+ {0x0985, 0x098C, prN}, // Lo [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L
+ {0x098F, 0x0990, prN}, // Lo [2] BENGALI LETTER E..BENGALI LETTER AI
+ {0x0993, 0x09A8, prN}, // Lo [22] BENGALI LETTER O..BENGALI LETTER NA
+ {0x09AA, 0x09B0, prN}, // Lo [7] BENGALI LETTER PA..BENGALI LETTER RA
+ {0x09B2, 0x09B2, prN}, // Lo BENGALI LETTER LA
+ {0x09B6, 0x09B9, prN}, // Lo [4] BENGALI LETTER SHA..BENGALI LETTER HA
+ {0x09BC, 0x09BC, prN}, // Mn BENGALI SIGN NUKTA
+ {0x09BD, 0x09BD, prN}, // Lo BENGALI SIGN AVAGRAHA
+ {0x09BE, 0x09C0, prN}, // Mc [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II
+ {0x09C1, 0x09C4, prN}, // Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR
+ {0x09C7, 0x09C8, prN}, // Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI
+ {0x09CB, 0x09CC, prN}, // Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU
+ {0x09CD, 0x09CD, prN}, // Mn BENGALI SIGN VIRAMA
+ {0x09CE, 0x09CE, prN}, // Lo BENGALI LETTER KHANDA TA
+ {0x09D7, 0x09D7, prN}, // Mc BENGALI AU LENGTH MARK
+ {0x09DC, 0x09DD, prN}, // Lo [2] BENGALI LETTER RRA..BENGALI LETTER RHA
+ {0x09DF, 0x09E1, prN}, // Lo [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL
+ {0x09E2, 0x09E3, prN}, // Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL
+ {0x09E6, 0x09EF, prN}, // Nd [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE
+ {0x09F0, 0x09F1, prN}, // Lo [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL
+ {0x09F2, 0x09F3, prN}, // Sc [2] BENGALI RUPEE MARK..BENGALI RUPEE SIGN
+ {0x09F4, 0x09F9, prN}, // No [6] BENGALI CURRENCY NUMERATOR ONE..BENGALI CURRENCY DENOMINATOR SIXTEEN
+ {0x09FA, 0x09FA, prN}, // So BENGALI ISSHAR
+ {0x09FB, 0x09FB, prN}, // Sc BENGALI GANDA MARK
+ {0x09FC, 0x09FC, prN}, // Lo BENGALI LETTER VEDIC ANUSVARA
+ {0x09FD, 0x09FD, prN}, // Po BENGALI ABBREVIATION SIGN
+ {0x09FE, 0x09FE, prN}, // Mn BENGALI SANDHI MARK
+ {0x0A01, 0x0A02, prN}, // Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI
+ {0x0A03, 0x0A03, prN}, // Mc GURMUKHI SIGN VISARGA
+ {0x0A05, 0x0A0A, prN}, // Lo [6] GURMUKHI LETTER A..GURMUKHI LETTER UU
+ {0x0A0F, 0x0A10, prN}, // Lo [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI
+ {0x0A13, 0x0A28, prN}, // Lo [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA
+ {0x0A2A, 0x0A30, prN}, // Lo [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA
+ {0x0A32, 0x0A33, prN}, // Lo [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA
+ {0x0A35, 0x0A36, prN}, // Lo [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA
+ {0x0A38, 0x0A39, prN}, // Lo [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA
+ {0x0A3C, 0x0A3C, prN}, // Mn GURMUKHI SIGN NUKTA
+ {0x0A3E, 0x0A40, prN}, // Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II
+ {0x0A41, 0x0A42, prN}, // Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU
+ {0x0A47, 0x0A48, prN}, // Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI
+ {0x0A4B, 0x0A4D, prN}, // Mn [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA
+ {0x0A51, 0x0A51, prN}, // Mn GURMUKHI SIGN UDAAT
+ {0x0A59, 0x0A5C, prN}, // Lo [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA
+ {0x0A5E, 0x0A5E, prN}, // Lo GURMUKHI LETTER FA
+ {0x0A66, 0x0A6F, prN}, // Nd [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE
+ {0x0A70, 0x0A71, prN}, // Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK
+ {0x0A72, 0x0A74, prN}, // Lo [3] GURMUKHI IRI..GURMUKHI EK ONKAR
+ {0x0A75, 0x0A75, prN}, // Mn GURMUKHI SIGN YAKASH
+ {0x0A76, 0x0A76, prN}, // Po GURMUKHI ABBREVIATION SIGN
+ {0x0A81, 0x0A82, prN}, // Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA
+ {0x0A83, 0x0A83, prN}, // Mc GUJARATI SIGN VISARGA
+ {0x0A85, 0x0A8D, prN}, // Lo [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E
+ {0x0A8F, 0x0A91, prN}, // Lo [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O
+ {0x0A93, 0x0AA8, prN}, // Lo [22] GUJARATI LETTER O..GUJARATI LETTER NA
+ {0x0AAA, 0x0AB0, prN}, // Lo [7] GUJARATI LETTER PA..GUJARATI LETTER RA
+ {0x0AB2, 0x0AB3, prN}, // Lo [2] GUJARATI LETTER LA..GUJARATI LETTER LLA
+ {0x0AB5, 0x0AB9, prN}, // Lo [5] GUJARATI LETTER VA..GUJARATI LETTER HA
+ {0x0ABC, 0x0ABC, prN}, // Mn GUJARATI SIGN NUKTA
+ {0x0ABD, 0x0ABD, prN}, // Lo GUJARATI SIGN AVAGRAHA
+ {0x0ABE, 0x0AC0, prN}, // Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II
+ {0x0AC1, 0x0AC5, prN}, // Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E
+ {0x0AC7, 0x0AC8, prN}, // Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI
+ {0x0AC9, 0x0AC9, prN}, // Mc GUJARATI VOWEL SIGN CANDRA O
+ {0x0ACB, 0x0ACC, prN}, // Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU
+ {0x0ACD, 0x0ACD, prN}, // Mn GUJARATI SIGN VIRAMA
+ {0x0AD0, 0x0AD0, prN}, // Lo GUJARATI OM
+ {0x0AE0, 0x0AE1, prN}, // Lo [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL
+ {0x0AE2, 0x0AE3, prN}, // Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL
+ {0x0AE6, 0x0AEF, prN}, // Nd [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE
+ {0x0AF0, 0x0AF0, prN}, // Po GUJARATI ABBREVIATION SIGN
+ {0x0AF1, 0x0AF1, prN}, // Sc GUJARATI RUPEE SIGN
+ {0x0AF9, 0x0AF9, prN}, // Lo GUJARATI LETTER ZHA
+ {0x0AFA, 0x0AFF, prN}, // Mn [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE
+ {0x0B01, 0x0B01, prN}, // Mn ORIYA SIGN CANDRABINDU
+ {0x0B02, 0x0B03, prN}, // Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA
+ {0x0B05, 0x0B0C, prN}, // Lo [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L
+ {0x0B0F, 0x0B10, prN}, // Lo [2] ORIYA LETTER E..ORIYA LETTER AI
+ {0x0B13, 0x0B28, prN}, // Lo [22] ORIYA LETTER O..ORIYA LETTER NA
+ {0x0B2A, 0x0B30, prN}, // Lo [7] ORIYA LETTER PA..ORIYA LETTER RA
+ {0x0B32, 0x0B33, prN}, // Lo [2] ORIYA LETTER LA..ORIYA LETTER LLA
+ {0x0B35, 0x0B39, prN}, // Lo [5] ORIYA LETTER VA..ORIYA LETTER HA
+ {0x0B3C, 0x0B3C, prN}, // Mn ORIYA SIGN NUKTA
+ {0x0B3D, 0x0B3D, prN}, // Lo ORIYA SIGN AVAGRAHA
+ {0x0B3E, 0x0B3E, prN}, // Mc ORIYA VOWEL SIGN AA
+ {0x0B3F, 0x0B3F, prN}, // Mn ORIYA VOWEL SIGN I
+ {0x0B40, 0x0B40, prN}, // Mc ORIYA VOWEL SIGN II
+ {0x0B41, 0x0B44, prN}, // Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR
+ {0x0B47, 0x0B48, prN}, // Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI
+ {0x0B4B, 0x0B4C, prN}, // Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU
+ {0x0B4D, 0x0B4D, prN}, // Mn ORIYA SIGN VIRAMA
+ {0x0B55, 0x0B56, prN}, // Mn [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK
+ {0x0B57, 0x0B57, prN}, // Mc ORIYA AU LENGTH MARK
+ {0x0B5C, 0x0B5D, prN}, // Lo [2] ORIYA LETTER RRA..ORIYA LETTER RHA
+ {0x0B5F, 0x0B61, prN}, // Lo [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL
+ {0x0B62, 0x0B63, prN}, // Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL
+ {0x0B66, 0x0B6F, prN}, // Nd [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE
+ {0x0B70, 0x0B70, prN}, // So ORIYA ISSHAR
+ {0x0B71, 0x0B71, prN}, // Lo ORIYA LETTER WA
+ {0x0B72, 0x0B77, prN}, // No [6] ORIYA FRACTION ONE QUARTER..ORIYA FRACTION THREE SIXTEENTHS
+ {0x0B82, 0x0B82, prN}, // Mn TAMIL SIGN ANUSVARA
+ {0x0B83, 0x0B83, prN}, // Lo TAMIL SIGN VISARGA
+ {0x0B85, 0x0B8A, prN}, // Lo [6] TAMIL LETTER A..TAMIL LETTER UU
+ {0x0B8E, 0x0B90, prN}, // Lo [3] TAMIL LETTER E..TAMIL LETTER AI
+ {0x0B92, 0x0B95, prN}, // Lo [4] TAMIL LETTER O..TAMIL LETTER KA
+ {0x0B99, 0x0B9A, prN}, // Lo [2] TAMIL LETTER NGA..TAMIL LETTER CA
+ {0x0B9C, 0x0B9C, prN}, // Lo TAMIL LETTER JA
+ {0x0B9E, 0x0B9F, prN}, // Lo [2] TAMIL LETTER NYA..TAMIL LETTER TTA
+ {0x0BA3, 0x0BA4, prN}, // Lo [2] TAMIL LETTER NNA..TAMIL LETTER TA
+ {0x0BA8, 0x0BAA, prN}, // Lo [3] TAMIL LETTER NA..TAMIL LETTER PA
+ {0x0BAE, 0x0BB9, prN}, // Lo [12] TAMIL LETTER MA..TAMIL LETTER HA
+ {0x0BBE, 0x0BBF, prN}, // Mc [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I
+ {0x0BC0, 0x0BC0, prN}, // Mn TAMIL VOWEL SIGN II
+ {0x0BC1, 0x0BC2, prN}, // Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU
+ {0x0BC6, 0x0BC8, prN}, // Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI
+ {0x0BCA, 0x0BCC, prN}, // Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU
+ {0x0BCD, 0x0BCD, prN}, // Mn TAMIL SIGN VIRAMA
+ {0x0BD0, 0x0BD0, prN}, // Lo TAMIL OM
+ {0x0BD7, 0x0BD7, prN}, // Mc TAMIL AU LENGTH MARK
+ {0x0BE6, 0x0BEF, prN}, // Nd [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE
+ {0x0BF0, 0x0BF2, prN}, // No [3] TAMIL NUMBER TEN..TAMIL NUMBER ONE THOUSAND
+ {0x0BF3, 0x0BF8, prN}, // So [6] TAMIL DAY SIGN..TAMIL AS ABOVE SIGN
+ {0x0BF9, 0x0BF9, prN}, // Sc TAMIL RUPEE SIGN
+ {0x0BFA, 0x0BFA, prN}, // So TAMIL NUMBER SIGN
+ {0x0C00, 0x0C00, prN}, // Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE
+ {0x0C01, 0x0C03, prN}, // Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA
+ {0x0C04, 0x0C04, prN}, // Mn TELUGU SIGN COMBINING ANUSVARA ABOVE
+ {0x0C05, 0x0C0C, prN}, // Lo [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L
+ {0x0C0E, 0x0C10, prN}, // Lo [3] TELUGU LETTER E..TELUGU LETTER AI
+ {0x0C12, 0x0C28, prN}, // Lo [23] TELUGU LETTER O..TELUGU LETTER NA
+ {0x0C2A, 0x0C39, prN}, // Lo [16] TELUGU LETTER PA..TELUGU LETTER HA
+ {0x0C3C, 0x0C3C, prN}, // Mn TELUGU SIGN NUKTA
+ {0x0C3D, 0x0C3D, prN}, // Lo TELUGU SIGN AVAGRAHA
+ {0x0C3E, 0x0C40, prN}, // Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II
+ {0x0C41, 0x0C44, prN}, // Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR
+ {0x0C46, 0x0C48, prN}, // Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI
+ {0x0C4A, 0x0C4D, prN}, // Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA
+ {0x0C55, 0x0C56, prN}, // Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK
+ {0x0C58, 0x0C5A, prN}, // Lo [3] TELUGU LETTER TSA..TELUGU LETTER RRRA
+ {0x0C5D, 0x0C5D, prN}, // Lo TELUGU LETTER NAKAARA POLLU
+ {0x0C60, 0x0C61, prN}, // Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL
+ {0x0C62, 0x0C63, prN}, // Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL
+ {0x0C66, 0x0C6F, prN}, // Nd [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE
+ {0x0C77, 0x0C77, prN}, // Po TELUGU SIGN SIDDHAM
+ {0x0C78, 0x0C7E, prN}, // No [7] TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR..TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR
+ {0x0C7F, 0x0C7F, prN}, // So TELUGU SIGN TUUMU
+ {0x0C80, 0x0C80, prN}, // Lo KANNADA SIGN SPACING CANDRABINDU
+ {0x0C81, 0x0C81, prN}, // Mn KANNADA SIGN CANDRABINDU
+ {0x0C82, 0x0C83, prN}, // Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA
+ {0x0C84, 0x0C84, prN}, // Po KANNADA SIGN SIDDHAM
+ {0x0C85, 0x0C8C, prN}, // Lo [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L
+ {0x0C8E, 0x0C90, prN}, // Lo [3] KANNADA LETTER E..KANNADA LETTER AI
+ {0x0C92, 0x0CA8, prN}, // Lo [23] KANNADA LETTER O..KANNADA LETTER NA
+ {0x0CAA, 0x0CB3, prN}, // Lo [10] KANNADA LETTER PA..KANNADA LETTER LLA
+ {0x0CB5, 0x0CB9, prN}, // Lo [5] KANNADA LETTER VA..KANNADA LETTER HA
+ {0x0CBC, 0x0CBC, prN}, // Mn KANNADA SIGN NUKTA
+ {0x0CBD, 0x0CBD, prN}, // Lo KANNADA SIGN AVAGRAHA
+ {0x0CBE, 0x0CBE, prN}, // Mc KANNADA VOWEL SIGN AA
+ {0x0CBF, 0x0CBF, prN}, // Mn KANNADA VOWEL SIGN I
+ {0x0CC0, 0x0CC4, prN}, // Mc [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR
+ {0x0CC6, 0x0CC6, prN}, // Mn KANNADA VOWEL SIGN E
+ {0x0CC7, 0x0CC8, prN}, // Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI
+ {0x0CCA, 0x0CCB, prN}, // Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO
+ {0x0CCC, 0x0CCD, prN}, // Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA
+ {0x0CD5, 0x0CD6, prN}, // Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK
+ {0x0CDD, 0x0CDE, prN}, // Lo [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA
+ {0x0CE0, 0x0CE1, prN}, // Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL
+ {0x0CE2, 0x0CE3, prN}, // Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL
+ {0x0CE6, 0x0CEF, prN}, // Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE
+ {0x0CF1, 0x0CF2, prN}, // Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA
+ {0x0CF3, 0x0CF3, prN}, // Mc KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT
+ {0x0D00, 0x0D01, prN}, // Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU
+ {0x0D02, 0x0D03, prN}, // Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
+ {0x0D04, 0x0D0C, prN}, // Lo [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L
+ {0x0D0E, 0x0D10, prN}, // Lo [3] MALAYALAM LETTER E..MALAYALAM LETTER AI
+ {0x0D12, 0x0D3A, prN}, // Lo [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA
+ {0x0D3B, 0x0D3C, prN}, // Mn [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA
+ {0x0D3D, 0x0D3D, prN}, // Lo MALAYALAM SIGN AVAGRAHA
+ {0x0D3E, 0x0D40, prN}, // Mc [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II
+ {0x0D41, 0x0D44, prN}, // Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR
+ {0x0D46, 0x0D48, prN}, // Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI
+ {0x0D4A, 0x0D4C, prN}, // Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU
+ {0x0D4D, 0x0D4D, prN}, // Mn MALAYALAM SIGN VIRAMA
+ {0x0D4E, 0x0D4E, prN}, // Lo MALAYALAM LETTER DOT REPH
+ {0x0D4F, 0x0D4F, prN}, // So MALAYALAM SIGN PARA
+ {0x0D54, 0x0D56, prN}, // Lo [3] MALAYALAM LETTER CHILLU M..MALAYALAM LETTER CHILLU LLL
+ {0x0D57, 0x0D57, prN}, // Mc MALAYALAM AU LENGTH MARK
+ {0x0D58, 0x0D5E, prN}, // No [7] MALAYALAM FRACTION ONE ONE-HUNDRED-AND-SIXTIETH..MALAYALAM FRACTION ONE FIFTH
+ {0x0D5F, 0x0D61, prN}, // Lo [3] MALAYALAM LETTER ARCHAIC II..MALAYALAM LETTER VOCALIC LL
+ {0x0D62, 0x0D63, prN}, // Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL
+ {0x0D66, 0x0D6F, prN}, // Nd [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE
+ {0x0D70, 0x0D78, prN}, // No [9] MALAYALAM NUMBER TEN..MALAYALAM FRACTION THREE SIXTEENTHS
+ {0x0D79, 0x0D79, prN}, // So MALAYALAM DATE MARK
+ {0x0D7A, 0x0D7F, prN}, // Lo [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K
+ {0x0D81, 0x0D81, prN}, // Mn SINHALA SIGN CANDRABINDU
+ {0x0D82, 0x0D83, prN}, // Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA
+ {0x0D85, 0x0D96, prN}, // Lo [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA
+ {0x0D9A, 0x0DB1, prN}, // Lo [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA
+ {0x0DB3, 0x0DBB, prN}, // Lo [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA
+ {0x0DBD, 0x0DBD, prN}, // Lo SINHALA LETTER DANTAJA LAYANNA
+ {0x0DC0, 0x0DC6, prN}, // Lo [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA
+ {0x0DCA, 0x0DCA, prN}, // Mn SINHALA SIGN AL-LAKUNA
+ {0x0DCF, 0x0DD1, prN}, // Mc [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA
+ {0x0DD2, 0x0DD4, prN}, // Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA
+ {0x0DD6, 0x0DD6, prN}, // Mn SINHALA VOWEL SIGN DIGA PAA-PILLA
+ {0x0DD8, 0x0DDF, prN}, // Mc [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA
+ {0x0DE6, 0x0DEF, prN}, // Nd [10] SINHALA LITH DIGIT ZERO..SINHALA LITH DIGIT NINE
+ {0x0DF2, 0x0DF3, prN}, // Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA
+ {0x0DF4, 0x0DF4, prN}, // Po SINHALA PUNCTUATION KUNDDALIYA
+ {0x0E01, 0x0E30, prN}, // Lo [48] THAI CHARACTER KO KAI..THAI CHARACTER SARA A
+ {0x0E31, 0x0E31, prN}, // Mn THAI CHARACTER MAI HAN-AKAT
+ {0x0E32, 0x0E33, prN}, // Lo [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM
+ {0x0E34, 0x0E3A, prN}, // Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU
+ {0x0E3F, 0x0E3F, prN}, // Sc THAI CURRENCY SYMBOL BAHT
+ {0x0E40, 0x0E45, prN}, // Lo [6] THAI CHARACTER SARA E..THAI CHARACTER LAKKHANGYAO
+ {0x0E46, 0x0E46, prN}, // Lm THAI CHARACTER MAIYAMOK
+ {0x0E47, 0x0E4E, prN}, // Mn [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN
+ {0x0E4F, 0x0E4F, prN}, // Po THAI CHARACTER FONGMAN
+ {0x0E50, 0x0E59, prN}, // Nd [10] THAI DIGIT ZERO..THAI DIGIT NINE
+ {0x0E5A, 0x0E5B, prN}, // Po [2] THAI CHARACTER ANGKHANKHU..THAI CHARACTER KHOMUT
+ {0x0E81, 0x0E82, prN}, // Lo [2] LAO LETTER KO..LAO LETTER KHO SUNG
+ {0x0E84, 0x0E84, prN}, // Lo LAO LETTER KHO TAM
+ {0x0E86, 0x0E8A, prN}, // Lo [5] LAO LETTER PALI GHA..LAO LETTER SO TAM
+ {0x0E8C, 0x0EA3, prN}, // Lo [24] LAO LETTER PALI JHA..LAO LETTER LO LING
+ {0x0EA5, 0x0EA5, prN}, // Lo LAO LETTER LO LOOT
+ {0x0EA7, 0x0EB0, prN}, // Lo [10] LAO LETTER WO..LAO VOWEL SIGN A
+ {0x0EB1, 0x0EB1, prN}, // Mn LAO VOWEL SIGN MAI KAN
+ {0x0EB2, 0x0EB3, prN}, // Lo [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM
+ {0x0EB4, 0x0EBC, prN}, // Mn [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO
+ {0x0EBD, 0x0EBD, prN}, // Lo LAO SEMIVOWEL SIGN NYO
+ {0x0EC0, 0x0EC4, prN}, // Lo [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI
+ {0x0EC6, 0x0EC6, prN}, // Lm LAO KO LA
+ {0x0EC8, 0x0ECE, prN}, // Mn [7] LAO TONE MAI EK..LAO YAMAKKAN
+ {0x0ED0, 0x0ED9, prN}, // Nd [10] LAO DIGIT ZERO..LAO DIGIT NINE
+ {0x0EDC, 0x0EDF, prN}, // Lo [4] LAO HO NO..LAO LETTER KHMU NYO
+ {0x0F00, 0x0F00, prN}, // Lo TIBETAN SYLLABLE OM
+ {0x0F01, 0x0F03, prN}, // So [3] TIBETAN MARK GTER YIG MGO TRUNCATED A..TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA
+ {0x0F04, 0x0F12, prN}, // Po [15] TIBETAN MARK INITIAL YIG MGO MDUN MA..TIBETAN MARK RGYA GRAM SHAD
+ {0x0F13, 0x0F13, prN}, // So TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN
+ {0x0F14, 0x0F14, prN}, // Po TIBETAN MARK GTER TSHEG
+ {0x0F15, 0x0F17, prN}, // So [3] TIBETAN LOGOTYPE SIGN CHAD RTAGS..TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS
+ {0x0F18, 0x0F19, prN}, // Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS
+ {0x0F1A, 0x0F1F, prN}, // So [6] TIBETAN SIGN RDEL DKAR GCIG..TIBETAN SIGN RDEL DKAR RDEL NAG
+ {0x0F20, 0x0F29, prN}, // Nd [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE
+ {0x0F2A, 0x0F33, prN}, // No [10] TIBETAN DIGIT HALF ONE..TIBETAN DIGIT HALF ZERO
+ {0x0F34, 0x0F34, prN}, // So TIBETAN MARK BSDUS RTAGS
+ {0x0F35, 0x0F35, prN}, // Mn TIBETAN MARK NGAS BZUNG NYI ZLA
+ {0x0F36, 0x0F36, prN}, // So TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN
+ {0x0F37, 0x0F37, prN}, // Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS
+ {0x0F38, 0x0F38, prN}, // So TIBETAN MARK CHE MGO
+ {0x0F39, 0x0F39, prN}, // Mn TIBETAN MARK TSA -PHRU
+ {0x0F3A, 0x0F3A, prN}, // Ps TIBETAN MARK GUG RTAGS GYON
+ {0x0F3B, 0x0F3B, prN}, // Pe TIBETAN MARK GUG RTAGS GYAS
+ {0x0F3C, 0x0F3C, prN}, // Ps TIBETAN MARK ANG KHANG GYON
+ {0x0F3D, 0x0F3D, prN}, // Pe TIBETAN MARK ANG KHANG GYAS
+ {0x0F3E, 0x0F3F, prN}, // Mc [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES
+ {0x0F40, 0x0F47, prN}, // Lo [8] TIBETAN LETTER KA..TIBETAN LETTER JA
+ {0x0F49, 0x0F6C, prN}, // Lo [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA
+ {0x0F71, 0x0F7E, prN}, // Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO
+ {0x0F7F, 0x0F7F, prN}, // Mc TIBETAN SIGN RNAM BCAD
+ {0x0F80, 0x0F84, prN}, // Mn [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA
+ {0x0F85, 0x0F85, prN}, // Po TIBETAN MARK PALUTA
+ {0x0F86, 0x0F87, prN}, // Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS
+ {0x0F88, 0x0F8C, prN}, // Lo [5] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN INVERTED MCHU CAN
+ {0x0F8D, 0x0F97, prN}, // Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA
+ {0x0F99, 0x0FBC, prN}, // Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA
+ {0x0FBE, 0x0FC5, prN}, // So [8] TIBETAN KU RU KHA..TIBETAN SYMBOL RDO RJE
+ {0x0FC6, 0x0FC6, prN}, // Mn TIBETAN SYMBOL PADMA GDAN
+ {0x0FC7, 0x0FCC, prN}, // So [6] TIBETAN SYMBOL RDO RJE RGYA GRAM..TIBETAN SYMBOL NOR BU BZHI -KHYIL
+ {0x0FCE, 0x0FCF, prN}, // So [2] TIBETAN SIGN RDEL NAG RDEL DKAR..TIBETAN SIGN RDEL NAG GSUM
+ {0x0FD0, 0x0FD4, prN}, // Po [5] TIBETAN MARK BSKA- SHOG GI MGO RGYAN..TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA
+ {0x0FD5, 0x0FD8, prN}, // So [4] RIGHT-FACING SVASTI SIGN..LEFT-FACING SVASTI SIGN WITH DOTS
+ {0x0FD9, 0x0FDA, prN}, // Po [2] TIBETAN MARK LEADING MCHAN RTAGS..TIBETAN MARK TRAILING MCHAN RTAGS
+ {0x1000, 0x102A, prN}, // Lo [43] MYANMAR LETTER KA..MYANMAR LETTER AU
+ {0x102B, 0x102C, prN}, // Mc [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA
+ {0x102D, 0x1030, prN}, // Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU
+ {0x1031, 0x1031, prN}, // Mc MYANMAR VOWEL SIGN E
+ {0x1032, 0x1037, prN}, // Mn [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW
+ {0x1038, 0x1038, prN}, // Mc MYANMAR SIGN VISARGA
+ {0x1039, 0x103A, prN}, // Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT
+ {0x103B, 0x103C, prN}, // Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA
+ {0x103D, 0x103E, prN}, // Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA
+ {0x103F, 0x103F, prN}, // Lo MYANMAR LETTER GREAT SA
+ {0x1040, 0x1049, prN}, // Nd [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE
+ {0x104A, 0x104F, prN}, // Po [6] MYANMAR SIGN LITTLE SECTION..MYANMAR SYMBOL GENITIVE
+ {0x1050, 0x1055, prN}, // Lo [6] MYANMAR LETTER SHA..MYANMAR LETTER VOCALIC LL
+ {0x1056, 0x1057, prN}, // Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR
+ {0x1058, 0x1059, prN}, // Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL
+ {0x105A, 0x105D, prN}, // Lo [4] MYANMAR LETTER MON NGA..MYANMAR LETTER MON BBE
+ {0x105E, 0x1060, prN}, // Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA
+ {0x1061, 0x1061, prN}, // Lo MYANMAR LETTER SGAW KAREN SHA
+ {0x1062, 0x1064, prN}, // Mc [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO
+ {0x1065, 0x1066, prN}, // Lo [2] MYANMAR LETTER WESTERN PWO KAREN THA..MYANMAR LETTER WESTERN PWO KAREN PWA
+ {0x1067, 0x106D, prN}, // Mc [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5
+ {0x106E, 0x1070, prN}, // Lo [3] MYANMAR LETTER EASTERN PWO KAREN NNA..MYANMAR LETTER EASTERN PWO KAREN GHWA
+ {0x1071, 0x1074, prN}, // Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE
+ {0x1075, 0x1081, prN}, // Lo [13] MYANMAR LETTER SHAN KA..MYANMAR LETTER SHAN HA
+ {0x1082, 0x1082, prN}, // Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA
+ {0x1083, 0x1084, prN}, // Mc [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E
+ {0x1085, 0x1086, prN}, // Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y
+ {0x1087, 0x108C, prN}, // Mc [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3
+ {0x108D, 0x108D, prN}, // Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE
+ {0x108E, 0x108E, prN}, // Lo MYANMAR LETTER RUMAI PALAUNG FA
+ {0x108F, 0x108F, prN}, // Mc MYANMAR SIGN RUMAI PALAUNG TONE-5
+ {0x1090, 0x1099, prN}, // Nd [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE
+ {0x109A, 0x109C, prN}, // Mc [3] MYANMAR SIGN KHAMTI TONE-1..MYANMAR VOWEL SIGN AITON A
+ {0x109D, 0x109D, prN}, // Mn MYANMAR VOWEL SIGN AITON AI
+ {0x109E, 0x109F, prN}, // So [2] MYANMAR SYMBOL SHAN ONE..MYANMAR SYMBOL SHAN EXCLAMATION
+ {0x10A0, 0x10C5, prN}, // Lu [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE
+ {0x10C7, 0x10C7, prN}, // Lu GEORGIAN CAPITAL LETTER YN
+ {0x10CD, 0x10CD, prN}, // Lu GEORGIAN CAPITAL LETTER AEN
+ {0x10D0, 0x10FA, prN}, // Ll [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN
+ {0x10FB, 0x10FB, prN}, // Po GEORGIAN PARAGRAPH SEPARATOR
+ {0x10FC, 0x10FC, prN}, // Lm MODIFIER LETTER GEORGIAN NAR
+ {0x10FD, 0x10FF, prN}, // Ll [3] GEORGIAN LETTER AEN..GEORGIAN LETTER LABIAL SIGN
+ {0x1100, 0x115F, prW}, // Lo [96] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG FILLER
+ {0x1160, 0x11FF, prN}, // Lo [160] HANGUL JUNGSEONG FILLER..HANGUL JONGSEONG SSANGNIEUN
+ {0x1200, 0x1248, prN}, // Lo [73] ETHIOPIC SYLLABLE HA..ETHIOPIC SYLLABLE QWA
+ {0x124A, 0x124D, prN}, // Lo [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE
+ {0x1250, 0x1256, prN}, // Lo [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO
+ {0x1258, 0x1258, prN}, // Lo ETHIOPIC SYLLABLE QHWA
+ {0x125A, 0x125D, prN}, // Lo [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE
+ {0x1260, 0x1288, prN}, // Lo [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA
+ {0x128A, 0x128D, prN}, // Lo [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE
+ {0x1290, 0x12B0, prN}, // Lo [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA
+ {0x12B2, 0x12B5, prN}, // Lo [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE
+ {0x12B8, 0x12BE, prN}, // Lo [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO
+ {0x12C0, 0x12C0, prN}, // Lo ETHIOPIC SYLLABLE KXWA
+ {0x12C2, 0x12C5, prN}, // Lo [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE
+ {0x12C8, 0x12D6, prN}, // Lo [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O
+ {0x12D8, 0x1310, prN}, // Lo [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA
+ {0x1312, 0x1315, prN}, // Lo [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE
+ {0x1318, 0x135A, prN}, // Lo [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA
+ {0x135D, 0x135F, prN}, // Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK
+ {0x1360, 0x1368, prN}, // Po [9] ETHIOPIC SECTION MARK..ETHIOPIC PARAGRAPH SEPARATOR
+ {0x1369, 0x137C, prN}, // No [20] ETHIOPIC DIGIT ONE..ETHIOPIC NUMBER TEN THOUSAND
+ {0x1380, 0x138F, prN}, // Lo [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE
+ {0x1390, 0x1399, prN}, // So [10] ETHIOPIC TONAL MARK YIZET..ETHIOPIC TONAL MARK KURT
+ {0x13A0, 0x13F5, prN}, // Lu [86] CHEROKEE LETTER A..CHEROKEE LETTER MV
+ {0x13F8, 0x13FD, prN}, // Ll [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV
+ {0x1400, 0x1400, prN}, // Pd CANADIAN SYLLABICS HYPHEN
+ {0x1401, 0x166C, prN}, // Lo [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA
+ {0x166D, 0x166D, prN}, // So CANADIAN SYLLABICS CHI SIGN
+ {0x166E, 0x166E, prN}, // Po CANADIAN SYLLABICS FULL STOP
+ {0x166F, 0x167F, prN}, // Lo [17] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS BLACKFOOT W
+ {0x1680, 0x1680, prN}, // Zs OGHAM SPACE MARK
+ {0x1681, 0x169A, prN}, // Lo [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH
+ {0x169B, 0x169B, prN}, // Ps OGHAM FEATHER MARK
+ {0x169C, 0x169C, prN}, // Pe OGHAM REVERSED FEATHER MARK
+ {0x16A0, 0x16EA, prN}, // Lo [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X
+ {0x16EB, 0x16ED, prN}, // Po [3] RUNIC SINGLE PUNCTUATION..RUNIC CROSS PUNCTUATION
+ {0x16EE, 0x16F0, prN}, // Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL
+ {0x16F1, 0x16F8, prN}, // Lo [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC
+ {0x1700, 0x1711, prN}, // Lo [18] TAGALOG LETTER A..TAGALOG LETTER HA
+ {0x1712, 0x1714, prN}, // Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA
+ {0x1715, 0x1715, prN}, // Mc TAGALOG SIGN PAMUDPOD
+ {0x171F, 0x171F, prN}, // Lo TAGALOG LETTER ARCHAIC RA
+ {0x1720, 0x1731, prN}, // Lo [18] HANUNOO LETTER A..HANUNOO LETTER HA
+ {0x1732, 0x1733, prN}, // Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U
+ {0x1734, 0x1734, prN}, // Mc HANUNOO SIGN PAMUDPOD
+ {0x1735, 0x1736, prN}, // Po [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION
+ {0x1740, 0x1751, prN}, // Lo [18] BUHID LETTER A..BUHID LETTER HA
+ {0x1752, 0x1753, prN}, // Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U
+ {0x1760, 0x176C, prN}, // Lo [13] TAGBANWA LETTER A..TAGBANWA LETTER YA
+ {0x176E, 0x1770, prN}, // Lo [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA
+ {0x1772, 0x1773, prN}, // Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U
+ {0x1780, 0x17B3, prN}, // Lo [52] KHMER LETTER KA..KHMER INDEPENDENT VOWEL QAU
+ {0x17B4, 0x17B5, prN}, // Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
+ {0x17B6, 0x17B6, prN}, // Mc KHMER VOWEL SIGN AA
+ {0x17B7, 0x17BD, prN}, // Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA
+ {0x17BE, 0x17C5, prN}, // Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU
+ {0x17C6, 0x17C6, prN}, // Mn KHMER SIGN NIKAHIT
+ {0x17C7, 0x17C8, prN}, // Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU
+ {0x17C9, 0x17D3, prN}, // Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT
+ {0x17D4, 0x17D6, prN}, // Po [3] KHMER SIGN KHAN..KHMER SIGN CAMNUC PII KUUH
+ {0x17D7, 0x17D7, prN}, // Lm KHMER SIGN LEK TOO
+ {0x17D8, 0x17DA, prN}, // Po [3] KHMER SIGN BEYYAL..KHMER SIGN KOOMUUT
+ {0x17DB, 0x17DB, prN}, // Sc KHMER CURRENCY SYMBOL RIEL
+ {0x17DC, 0x17DC, prN}, // Lo KHMER SIGN AVAKRAHASANYA
+ {0x17DD, 0x17DD, prN}, // Mn KHMER SIGN ATTHACAN
+ {0x17E0, 0x17E9, prN}, // Nd [10] KHMER DIGIT ZERO..KHMER DIGIT NINE
+ {0x17F0, 0x17F9, prN}, // No [10] KHMER SYMBOL LEK ATTAK SON..KHMER SYMBOL LEK ATTAK PRAM-BUON
+ {0x1800, 0x1805, prN}, // Po [6] MONGOLIAN BIRGA..MONGOLIAN FOUR DOTS
+ {0x1806, 0x1806, prN}, // Pd MONGOLIAN TODO SOFT HYPHEN
+ {0x1807, 0x180A, prN}, // Po [4] MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER..MONGOLIAN NIRUGU
+ {0x180B, 0x180D, prN}, // Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
+ {0x180E, 0x180E, prN}, // Cf MONGOLIAN VOWEL SEPARATOR
+ {0x180F, 0x180F, prN}, // Mn MONGOLIAN FREE VARIATION SELECTOR FOUR
+ {0x1810, 0x1819, prN}, // Nd [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE
+ {0x1820, 0x1842, prN}, // Lo [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI
+ {0x1843, 0x1843, prN}, // Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN
+ {0x1844, 0x1878, prN}, // Lo [53] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER CHA WITH TWO DOTS
+ {0x1880, 0x1884, prN}, // Lo [5] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI INVERTED UBADAMA
+ {0x1885, 0x1886, prN}, // Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA
+ {0x1887, 0x18A8, prN}, // Lo [34] MONGOLIAN LETTER ALI GALI A..MONGOLIAN LETTER MANCHU ALI GALI BHA
+ {0x18A9, 0x18A9, prN}, // Mn MONGOLIAN LETTER ALI GALI DAGALGA
+ {0x18AA, 0x18AA, prN}, // Lo MONGOLIAN LETTER MANCHU ALI GALI LHA
+ {0x18B0, 0x18F5, prN}, // Lo [70] CANADIAN SYLLABICS OY..CANADIAN SYLLABICS CARRIER DENTAL S
+ {0x1900, 0x191E, prN}, // Lo [31] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER TRA
+ {0x1920, 0x1922, prN}, // Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U
+ {0x1923, 0x1926, prN}, // Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU
+ {0x1927, 0x1928, prN}, // Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O
+ {0x1929, 0x192B, prN}, // Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA
+ {0x1930, 0x1931, prN}, // Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA
+ {0x1932, 0x1932, prN}, // Mn LIMBU SMALL LETTER ANUSVARA
+ {0x1933, 0x1938, prN}, // Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA
+ {0x1939, 0x193B, prN}, // Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I
+ {0x1940, 0x1940, prN}, // So LIMBU SIGN LOO
+ {0x1944, 0x1945, prN}, // Po [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK
+ {0x1946, 0x194F, prN}, // Nd [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE
+ {0x1950, 0x196D, prN}, // Lo [30] TAI LE LETTER KA..TAI LE LETTER AI
+ {0x1970, 0x1974, prN}, // Lo [5] TAI LE LETTER TONE-2..TAI LE LETTER TONE-6
+ {0x1980, 0x19AB, prN}, // Lo [44] NEW TAI LUE LETTER HIGH QA..NEW TAI LUE LETTER LOW SUA
+ {0x19B0, 0x19C9, prN}, // Lo [26] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE TONE MARK-2
+ {0x19D0, 0x19D9, prN}, // Nd [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE
+ {0x19DA, 0x19DA, prN}, // No NEW TAI LUE THAM DIGIT ONE
+ {0x19DE, 0x19DF, prN}, // So [2] NEW TAI LUE SIGN LAE..NEW TAI LUE SIGN LAEV
+ {0x19E0, 0x19FF, prN}, // So [32] KHMER SYMBOL PATHAMASAT..KHMER SYMBOL DAP-PRAM ROC
+ {0x1A00, 0x1A16, prN}, // Lo [23] BUGINESE LETTER KA..BUGINESE LETTER HA
+ {0x1A17, 0x1A18, prN}, // Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U
+ {0x1A19, 0x1A1A, prN}, // Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O
+ {0x1A1B, 0x1A1B, prN}, // Mn BUGINESE VOWEL SIGN AE
+ {0x1A1E, 0x1A1F, prN}, // Po [2] BUGINESE PALLAWA..BUGINESE END OF SECTION
+ {0x1A20, 0x1A54, prN}, // Lo [53] TAI THAM LETTER HIGH KA..TAI THAM LETTER GREAT SA
+ {0x1A55, 0x1A55, prN}, // Mc TAI THAM CONSONANT SIGN MEDIAL RA
+ {0x1A56, 0x1A56, prN}, // Mn TAI THAM CONSONANT SIGN MEDIAL LA
+ {0x1A57, 0x1A57, prN}, // Mc TAI THAM CONSONANT SIGN LA TANG LAI
+ {0x1A58, 0x1A5E, prN}, // Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA
+ {0x1A60, 0x1A60, prN}, // Mn TAI THAM SIGN SAKOT
+ {0x1A61, 0x1A61, prN}, // Mc TAI THAM VOWEL SIGN A
+ {0x1A62, 0x1A62, prN}, // Mn TAI THAM VOWEL SIGN MAI SAT
+ {0x1A63, 0x1A64, prN}, // Mc [2] TAI THAM VOWEL SIGN AA..TAI THAM VOWEL SIGN TALL AA
+ {0x1A65, 0x1A6C, prN}, // Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW
+ {0x1A6D, 0x1A72, prN}, // Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI
+ {0x1A73, 0x1A7C, prN}, // Mn [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN
+ {0x1A7F, 0x1A7F, prN}, // Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT
+ {0x1A80, 0x1A89, prN}, // Nd [10] TAI THAM HORA DIGIT ZERO..TAI THAM HORA DIGIT NINE
+ {0x1A90, 0x1A99, prN}, // Nd [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE
+ {0x1AA0, 0x1AA6, prN}, // Po [7] TAI THAM SIGN WIANG..TAI THAM SIGN REVERSED ROTATED RANA
+ {0x1AA7, 0x1AA7, prN}, // Lm TAI THAM SIGN MAI YAMOK
+ {0x1AA8, 0x1AAD, prN}, // Po [6] TAI THAM SIGN KAAN..TAI THAM SIGN CAANG
+ {0x1AB0, 0x1ABD, prN}, // Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW
+ {0x1ABE, 0x1ABE, prN}, // Me COMBINING PARENTHESES OVERLAY
+ {0x1ABF, 0x1ACE, prN}, // Mn [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T
+ {0x1B00, 0x1B03, prN}, // Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG
+ {0x1B04, 0x1B04, prN}, // Mc BALINESE SIGN BISAH
+ {0x1B05, 0x1B33, prN}, // Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA
+ {0x1B34, 0x1B34, prN}, // Mn BALINESE SIGN REREKAN
+ {0x1B35, 0x1B35, prN}, // Mc BALINESE VOWEL SIGN TEDUNG
+ {0x1B36, 0x1B3A, prN}, // Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA
+ {0x1B3B, 0x1B3B, prN}, // Mc BALINESE VOWEL SIGN RA REPA TEDUNG
+ {0x1B3C, 0x1B3C, prN}, // Mn BALINESE VOWEL SIGN LA LENGA
+ {0x1B3D, 0x1B41, prN}, // Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG
+ {0x1B42, 0x1B42, prN}, // Mn BALINESE VOWEL SIGN PEPET
+ {0x1B43, 0x1B44, prN}, // Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG
+ {0x1B45, 0x1B4C, prN}, // Lo [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA
+ {0x1B50, 0x1B59, prN}, // Nd [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE
+ {0x1B5A, 0x1B60, prN}, // Po [7] BALINESE PANTI..BALINESE PAMENENG
+ {0x1B61, 0x1B6A, prN}, // So [10] BALINESE MUSICAL SYMBOL DONG..BALINESE MUSICAL SYMBOL DANG GEDE
+ {0x1B6B, 0x1B73, prN}, // Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG
+ {0x1B74, 0x1B7C, prN}, // So [9] BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG..BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING
+ {0x1B7D, 0x1B7E, prN}, // Po [2] BALINESE PANTI LANTANG..BALINESE PAMADA LANTANG
+ {0x1B80, 0x1B81, prN}, // Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR
+ {0x1B82, 0x1B82, prN}, // Mc SUNDANESE SIGN PANGWISAD
+ {0x1B83, 0x1BA0, prN}, // Lo [30] SUNDANESE LETTER A..SUNDANESE LETTER HA
+ {0x1BA1, 0x1BA1, prN}, // Mc SUNDANESE CONSONANT SIGN PAMINGKAL
+ {0x1BA2, 0x1BA5, prN}, // Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU
+ {0x1BA6, 0x1BA7, prN}, // Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG
+ {0x1BA8, 0x1BA9, prN}, // Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG
+ {0x1BAA, 0x1BAA, prN}, // Mc SUNDANESE SIGN PAMAAEH
+ {0x1BAB, 0x1BAD, prN}, // Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA
+ {0x1BAE, 0x1BAF, prN}, // Lo [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA
+ {0x1BB0, 0x1BB9, prN}, // Nd [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE
+ {0x1BBA, 0x1BBF, prN}, // Lo [6] SUNDANESE AVAGRAHA..SUNDANESE LETTER FINAL M
+ {0x1BC0, 0x1BE5, prN}, // Lo [38] BATAK LETTER A..BATAK LETTER U
+ {0x1BE6, 0x1BE6, prN}, // Mn BATAK SIGN TOMPI
+ {0x1BE7, 0x1BE7, prN}, // Mc BATAK VOWEL SIGN E
+ {0x1BE8, 0x1BE9, prN}, // Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE
+ {0x1BEA, 0x1BEC, prN}, // Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O
+ {0x1BED, 0x1BED, prN}, // Mn BATAK VOWEL SIGN KARO O
+ {0x1BEE, 0x1BEE, prN}, // Mc BATAK VOWEL SIGN U
+ {0x1BEF, 0x1BF1, prN}, // Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H
+ {0x1BF2, 0x1BF3, prN}, // Mc [2] BATAK PANGOLAT..BATAK PANONGONAN
+ {0x1BFC, 0x1BFF, prN}, // Po [4] BATAK SYMBOL BINDU NA METEK..BATAK SYMBOL BINDU PANGOLAT
+ {0x1C00, 0x1C23, prN}, // Lo [36] LEPCHA LETTER KA..LEPCHA LETTER A
+ {0x1C24, 0x1C2B, prN}, // Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU
+ {0x1C2C, 0x1C33, prN}, // Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T
+ {0x1C34, 0x1C35, prN}, // Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG
+ {0x1C36, 0x1C37, prN}, // Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA
+ {0x1C3B, 0x1C3F, prN}, // Po [5] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION TSHOOK
+ {0x1C40, 0x1C49, prN}, // Nd [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE
+ {0x1C4D, 0x1C4F, prN}, // Lo [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA
+ {0x1C50, 0x1C59, prN}, // Nd [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE
+ {0x1C5A, 0x1C77, prN}, // Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH
+ {0x1C78, 0x1C7D, prN}, // Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD
+ {0x1C7E, 0x1C7F, prN}, // Po [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD
+ {0x1C80, 0x1C88, prN}, // Ll [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK
+ {0x1C90, 0x1CBA, prN}, // Lu [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN
+ {0x1CBD, 0x1CBF, prN}, // Lu [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN
+ {0x1CC0, 0x1CC7, prN}, // Po [8] SUNDANESE PUNCTUATION BINDU SURYA..SUNDANESE PUNCTUATION BINDU BA SATANGA
+ {0x1CD0, 0x1CD2, prN}, // Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA
+ {0x1CD3, 0x1CD3, prN}, // Po VEDIC SIGN NIHSHVASA
+ {0x1CD4, 0x1CE0, prN}, // Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA
+ {0x1CE1, 0x1CE1, prN}, // Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA
+ {0x1CE2, 0x1CE8, prN}, // Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL
+ {0x1CE9, 0x1CEC, prN}, // Lo [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL
+ {0x1CED, 0x1CED, prN}, // Mn VEDIC SIGN TIRYAK
+ {0x1CEE, 0x1CF3, prN}, // Lo [6] VEDIC SIGN HEXIFORM LONG ANUSVARA..VEDIC SIGN ROTATED ARDHAVISARGA
+ {0x1CF4, 0x1CF4, prN}, // Mn VEDIC TONE CANDRA ABOVE
+ {0x1CF5, 0x1CF6, prN}, // Lo [2] VEDIC SIGN JIHVAMULIYA..VEDIC SIGN UPADHMANIYA
+ {0x1CF7, 0x1CF7, prN}, // Mc VEDIC SIGN ATIKRAMA
+ {0x1CF8, 0x1CF9, prN}, // Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE
+ {0x1CFA, 0x1CFA, prN}, // Lo VEDIC SIGN DOUBLE ANUSVARA ANTARGOMUKHA
+ {0x1D00, 0x1D2B, prN}, // Ll [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL
+ {0x1D2C, 0x1D6A, prN}, // Lm [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI
+ {0x1D6B, 0x1D77, prN}, // Ll [13] LATIN SMALL LETTER UE..LATIN SMALL LETTER TURNED G
+ {0x1D78, 0x1D78, prN}, // Lm MODIFIER LETTER CYRILLIC EN
+ {0x1D79, 0x1D7F, prN}, // Ll [7] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER UPSILON WITH STROKE
+ {0x1D80, 0x1D9A, prN}, // Ll [27] LATIN SMALL LETTER B WITH PALATAL HOOK..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK
+ {0x1D9B, 0x1DBF, prN}, // Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA
+ {0x1DC0, 0x1DFF, prN}, // Mn [64] COMBINING DOTTED GRAVE ACCENT..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW
+ {0x1E00, 0x1EFF, prN}, // L& [256] LATIN CAPITAL LETTER A WITH RING BELOW..LATIN SMALL LETTER Y WITH LOOP
+ {0x1F00, 0x1F15, prN}, // L& [22] GREEK SMALL LETTER ALPHA WITH PSILI..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA
+ {0x1F18, 0x1F1D, prN}, // Lu [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
+ {0x1F20, 0x1F45, prN}, // L& [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA
+ {0x1F48, 0x1F4D, prN}, // Lu [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
+ {0x1F50, 0x1F57, prN}, // Ll [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI
+ {0x1F59, 0x1F59, prN}, // Lu GREEK CAPITAL LETTER UPSILON WITH DASIA
+ {0x1F5B, 0x1F5B, prN}, // Lu GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
+ {0x1F5D, 0x1F5D, prN}, // Lu GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
+ {0x1F5F, 0x1F7D, prN}, // L& [31] GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI..GREEK SMALL LETTER OMEGA WITH OXIA
+ {0x1F80, 0x1FB4, prN}, // L& [53] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
+ {0x1FB6, 0x1FBC, prN}, // L& [7] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
+ {0x1FBD, 0x1FBD, prN}, // Sk GREEK KORONIS
+ {0x1FBE, 0x1FBE, prN}, // Ll GREEK PROSGEGRAMMENI
+ {0x1FBF, 0x1FC1, prN}, // Sk [3] GREEK PSILI..GREEK DIALYTIKA AND PERISPOMENI
+ {0x1FC2, 0x1FC4, prN}, // Ll [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
+ {0x1FC6, 0x1FCC, prN}, // L& [7] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
+ {0x1FCD, 0x1FCF, prN}, // Sk [3] GREEK PSILI AND VARIA..GREEK PSILI AND PERISPOMENI
+ {0x1FD0, 0x1FD3, prN}, // Ll [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
+ {0x1FD6, 0x1FDB, prN}, // L& [6] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK CAPITAL LETTER IOTA WITH OXIA
+ {0x1FDD, 0x1FDF, prN}, // Sk [3] GREEK DASIA AND VARIA..GREEK DASIA AND PERISPOMENI
+ {0x1FE0, 0x1FEC, prN}, // L& [13] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA
+ {0x1FED, 0x1FEF, prN}, // Sk [3] GREEK DIALYTIKA AND VARIA..GREEK VARIA
+ {0x1FF2, 0x1FF4, prN}, // Ll [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
+ {0x1FF6, 0x1FFC, prN}, // L& [7] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
+ {0x1FFD, 0x1FFE, prN}, // Sk [2] GREEK OXIA..GREEK DASIA
+ {0x2000, 0x200A, prN}, // Zs [11] EN QUAD..HAIR SPACE
+ {0x200B, 0x200F, prN}, // Cf [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK
+ {0x2010, 0x2010, prA}, // Pd HYPHEN
+ {0x2011, 0x2012, prN}, // Pd [2] NON-BREAKING HYPHEN..FIGURE DASH
+ {0x2013, 0x2015, prA}, // Pd [3] EN DASH..HORIZONTAL BAR
+ {0x2016, 0x2016, prA}, // Po DOUBLE VERTICAL LINE
+ {0x2017, 0x2017, prN}, // Po DOUBLE LOW LINE
+ {0x2018, 0x2018, prA}, // Pi LEFT SINGLE QUOTATION MARK
+ {0x2019, 0x2019, prA}, // Pf RIGHT SINGLE QUOTATION MARK
+ {0x201A, 0x201A, prN}, // Ps SINGLE LOW-9 QUOTATION MARK
+ {0x201B, 0x201B, prN}, // Pi SINGLE HIGH-REVERSED-9 QUOTATION MARK
+ {0x201C, 0x201C, prA}, // Pi LEFT DOUBLE QUOTATION MARK
+ {0x201D, 0x201D, prA}, // Pf RIGHT DOUBLE QUOTATION MARK
+ {0x201E, 0x201E, prN}, // Ps DOUBLE LOW-9 QUOTATION MARK
+ {0x201F, 0x201F, prN}, // Pi DOUBLE HIGH-REVERSED-9 QUOTATION MARK
+ {0x2020, 0x2022, prA}, // Po [3] DAGGER..BULLET
+ {0x2023, 0x2023, prN}, // Po TRIANGULAR BULLET
+ {0x2024, 0x2027, prA}, // Po [4] ONE DOT LEADER..HYPHENATION POINT
+ {0x2028, 0x2028, prN}, // Zl LINE SEPARATOR
+ {0x2029, 0x2029, prN}, // Zp PARAGRAPH SEPARATOR
+ {0x202A, 0x202E, prN}, // Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
+ {0x202F, 0x202F, prN}, // Zs NARROW NO-BREAK SPACE
+ {0x2030, 0x2030, prA}, // Po PER MILLE SIGN
+ {0x2031, 0x2031, prN}, // Po PER TEN THOUSAND SIGN
+ {0x2032, 0x2033, prA}, // Po [2] PRIME..DOUBLE PRIME
+ {0x2034, 0x2034, prN}, // Po TRIPLE PRIME
+ {0x2035, 0x2035, prA}, // Po REVERSED PRIME
+ {0x2036, 0x2038, prN}, // Po [3] REVERSED DOUBLE PRIME..CARET
+ {0x2039, 0x2039, prN}, // Pi SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+ {0x203A, 0x203A, prN}, // Pf SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+ {0x203B, 0x203B, prA}, // Po REFERENCE MARK
+ {0x203C, 0x203D, prN}, // Po [2] DOUBLE EXCLAMATION MARK..INTERROBANG
+ {0x203E, 0x203E, prA}, // Po OVERLINE
+ {0x203F, 0x2040, prN}, // Pc [2] UNDERTIE..CHARACTER TIE
+ {0x2041, 0x2043, prN}, // Po [3] CARET INSERTION POINT..HYPHEN BULLET
+ {0x2044, 0x2044, prN}, // Sm FRACTION SLASH
+ {0x2045, 0x2045, prN}, // Ps LEFT SQUARE BRACKET WITH QUILL
+ {0x2046, 0x2046, prN}, // Pe RIGHT SQUARE BRACKET WITH QUILL
+ {0x2047, 0x2051, prN}, // Po [11] DOUBLE QUESTION MARK..TWO ASTERISKS ALIGNED VERTICALLY
+ {0x2052, 0x2052, prN}, // Sm COMMERCIAL MINUS SIGN
+ {0x2053, 0x2053, prN}, // Po SWUNG DASH
+ {0x2054, 0x2054, prN}, // Pc INVERTED UNDERTIE
+ {0x2055, 0x205E, prN}, // Po [10] FLOWER PUNCTUATION MARK..VERTICAL FOUR DOTS
+ {0x205F, 0x205F, prN}, // Zs MEDIUM MATHEMATICAL SPACE
+ {0x2060, 0x2064, prN}, // Cf [5] WORD JOINER..INVISIBLE PLUS
+ {0x2066, 0x206F, prN}, // Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES
+ {0x2070, 0x2070, prN}, // No SUPERSCRIPT ZERO
+ {0x2071, 0x2071, prN}, // Lm SUPERSCRIPT LATIN SMALL LETTER I
+ {0x2074, 0x2074, prA}, // No SUPERSCRIPT FOUR
+ {0x2075, 0x2079, prN}, // No [5] SUPERSCRIPT FIVE..SUPERSCRIPT NINE
+ {0x207A, 0x207C, prN}, // Sm [3] SUPERSCRIPT PLUS SIGN..SUPERSCRIPT EQUALS SIGN
+ {0x207D, 0x207D, prN}, // Ps SUPERSCRIPT LEFT PARENTHESIS
+ {0x207E, 0x207E, prN}, // Pe SUPERSCRIPT RIGHT PARENTHESIS
+ {0x207F, 0x207F, prA}, // Lm SUPERSCRIPT LATIN SMALL LETTER N
+ {0x2080, 0x2080, prN}, // No SUBSCRIPT ZERO
+ {0x2081, 0x2084, prA}, // No [4] SUBSCRIPT ONE..SUBSCRIPT FOUR
+ {0x2085, 0x2089, prN}, // No [5] SUBSCRIPT FIVE..SUBSCRIPT NINE
+ {0x208A, 0x208C, prN}, // Sm [3] SUBSCRIPT PLUS SIGN..SUBSCRIPT EQUALS SIGN
+ {0x208D, 0x208D, prN}, // Ps SUBSCRIPT LEFT PARENTHESIS
+ {0x208E, 0x208E, prN}, // Pe SUBSCRIPT RIGHT PARENTHESIS
+ {0x2090, 0x209C, prN}, // Lm [13] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER T
+ {0x20A0, 0x20A8, prN}, // Sc [9] EURO-CURRENCY SIGN..RUPEE SIGN
+ {0x20A9, 0x20A9, prH}, // Sc WON SIGN
+ {0x20AA, 0x20AB, prN}, // Sc [2] NEW SHEQEL SIGN..DONG SIGN
+ {0x20AC, 0x20AC, prA}, // Sc EURO SIGN
+ {0x20AD, 0x20C0, prN}, // Sc [20] KIP SIGN..SOM SIGN
+ {0x20D0, 0x20DC, prN}, // Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE
+ {0x20DD, 0x20E0, prN}, // Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH
+ {0x20E1, 0x20E1, prN}, // Mn COMBINING LEFT RIGHT ARROW ABOVE
+ {0x20E2, 0x20E4, prN}, // Me [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE
+ {0x20E5, 0x20F0, prN}, // Mn [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE
+ {0x2100, 0x2101, prN}, // So [2] ACCOUNT OF..ADDRESSED TO THE SUBJECT
+ {0x2102, 0x2102, prN}, // Lu DOUBLE-STRUCK CAPITAL C
+ {0x2103, 0x2103, prA}, // So DEGREE CELSIUS
+ {0x2104, 0x2104, prN}, // So CENTRE LINE SYMBOL
+ {0x2105, 0x2105, prA}, // So CARE OF
+ {0x2106, 0x2106, prN}, // So CADA UNA
+ {0x2107, 0x2107, prN}, // Lu EULER CONSTANT
+ {0x2108, 0x2108, prN}, // So SCRUPLE
+ {0x2109, 0x2109, prA}, // So DEGREE FAHRENHEIT
+ {0x210A, 0x2112, prN}, // L& [9] SCRIPT SMALL G..SCRIPT CAPITAL L
+ {0x2113, 0x2113, prA}, // Ll SCRIPT SMALL L
+ {0x2114, 0x2114, prN}, // So L B BAR SYMBOL
+ {0x2115, 0x2115, prN}, // Lu DOUBLE-STRUCK CAPITAL N
+ {0x2116, 0x2116, prA}, // So NUMERO SIGN
+ {0x2117, 0x2117, prN}, // So SOUND RECORDING COPYRIGHT
+ {0x2118, 0x2118, prN}, // Sm SCRIPT CAPITAL P
+ {0x2119, 0x211D, prN}, // Lu [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R
+ {0x211E, 0x2120, prN}, // So [3] PRESCRIPTION TAKE..SERVICE MARK
+ {0x2121, 0x2122, prA}, // So [2] TELEPHONE SIGN..TRADE MARK SIGN
+ {0x2123, 0x2123, prN}, // So VERSICLE
+ {0x2124, 0x2124, prN}, // Lu DOUBLE-STRUCK CAPITAL Z
+ {0x2125, 0x2125, prN}, // So OUNCE SIGN
+ {0x2126, 0x2126, prA}, // Lu OHM SIGN
+ {0x2127, 0x2127, prN}, // So INVERTED OHM SIGN
+ {0x2128, 0x2128, prN}, // Lu BLACK-LETTER CAPITAL Z
+ {0x2129, 0x2129, prN}, // So TURNED GREEK SMALL LETTER IOTA
+ {0x212A, 0x212A, prN}, // Lu KELVIN SIGN
+ {0x212B, 0x212B, prA}, // Lu ANGSTROM SIGN
+ {0x212C, 0x212D, prN}, // Lu [2] SCRIPT CAPITAL B..BLACK-LETTER CAPITAL C
+ {0x212E, 0x212E, prN}, // So ESTIMATED SYMBOL
+ {0x212F, 0x2134, prN}, // L& [6] SCRIPT SMALL E..SCRIPT SMALL O
+ {0x2135, 0x2138, prN}, // Lo [4] ALEF SYMBOL..DALET SYMBOL
+ {0x2139, 0x2139, prN}, // Ll INFORMATION SOURCE
+ {0x213A, 0x213B, prN}, // So [2] ROTATED CAPITAL Q..FACSIMILE SIGN
+ {0x213C, 0x213F, prN}, // L& [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI
+ {0x2140, 0x2144, prN}, // Sm [5] DOUBLE-STRUCK N-ARY SUMMATION..TURNED SANS-SERIF CAPITAL Y
+ {0x2145, 0x2149, prN}, // L& [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J
+ {0x214A, 0x214A, prN}, // So PROPERTY LINE
+ {0x214B, 0x214B, prN}, // Sm TURNED AMPERSAND
+ {0x214C, 0x214D, prN}, // So [2] PER SIGN..AKTIESELSKAB
+ {0x214E, 0x214E, prN}, // Ll TURNED SMALL F
+ {0x214F, 0x214F, prN}, // So SYMBOL FOR SAMARITAN SOURCE
+ {0x2150, 0x2152, prN}, // No [3] VULGAR FRACTION ONE SEVENTH..VULGAR FRACTION ONE TENTH
+ {0x2153, 0x2154, prA}, // No [2] VULGAR FRACTION ONE THIRD..VULGAR FRACTION TWO THIRDS
+ {0x2155, 0x215A, prN}, // No [6] VULGAR FRACTION ONE FIFTH..VULGAR FRACTION FIVE SIXTHS
+ {0x215B, 0x215E, prA}, // No [4] VULGAR FRACTION ONE EIGHTH..VULGAR FRACTION SEVEN EIGHTHS
+ {0x215F, 0x215F, prN}, // No FRACTION NUMERATOR ONE
+ {0x2160, 0x216B, prA}, // Nl [12] ROMAN NUMERAL ONE..ROMAN NUMERAL TWELVE
+ {0x216C, 0x216F, prN}, // Nl [4] ROMAN NUMERAL FIFTY..ROMAN NUMERAL ONE THOUSAND
+ {0x2170, 0x2179, prA}, // Nl [10] SMALL ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL TEN
+ {0x217A, 0x2182, prN}, // Nl [9] SMALL ROMAN NUMERAL ELEVEN..ROMAN NUMERAL TEN THOUSAND
+ {0x2183, 0x2184, prN}, // L& [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C
+ {0x2185, 0x2188, prN}, // Nl [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND
+ {0x2189, 0x2189, prA}, // No VULGAR FRACTION ZERO THIRDS
+ {0x218A, 0x218B, prN}, // So [2] TURNED DIGIT TWO..TURNED DIGIT THREE
+ {0x2190, 0x2194, prA}, // Sm [5] LEFTWARDS ARROW..LEFT RIGHT ARROW
+ {0x2195, 0x2199, prA}, // So [5] UP DOWN ARROW..SOUTH WEST ARROW
+ {0x219A, 0x219B, prN}, // Sm [2] LEFTWARDS ARROW WITH STROKE..RIGHTWARDS ARROW WITH STROKE
+ {0x219C, 0x219F, prN}, // So [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW
+ {0x21A0, 0x21A0, prN}, // Sm RIGHTWARDS TWO HEADED ARROW
+ {0x21A1, 0x21A2, prN}, // So [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL
+ {0x21A3, 0x21A3, prN}, // Sm RIGHTWARDS ARROW WITH TAIL
+ {0x21A4, 0x21A5, prN}, // So [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR
+ {0x21A6, 0x21A6, prN}, // Sm RIGHTWARDS ARROW FROM BAR
+ {0x21A7, 0x21AD, prN}, // So [7] DOWNWARDS ARROW FROM BAR..LEFT RIGHT WAVE ARROW
+ {0x21AE, 0x21AE, prN}, // Sm LEFT RIGHT ARROW WITH STROKE
+ {0x21AF, 0x21B7, prN}, // So [9] DOWNWARDS ZIGZAG ARROW..CLOCKWISE TOP SEMICIRCLE ARROW
+ {0x21B8, 0x21B9, prA}, // So [2] NORTH WEST ARROW TO LONG BAR..LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR
+ {0x21BA, 0x21CD, prN}, // So [20] ANTICLOCKWISE OPEN CIRCLE ARROW..LEFTWARDS DOUBLE ARROW WITH STROKE
+ {0x21CE, 0x21CF, prN}, // Sm [2] LEFT RIGHT DOUBLE ARROW WITH STROKE..RIGHTWARDS DOUBLE ARROW WITH STROKE
+ {0x21D0, 0x21D1, prN}, // So [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW
+ {0x21D2, 0x21D2, prA}, // Sm RIGHTWARDS DOUBLE ARROW
+ {0x21D3, 0x21D3, prN}, // So DOWNWARDS DOUBLE ARROW
+ {0x21D4, 0x21D4, prA}, // Sm LEFT RIGHT DOUBLE ARROW
+ {0x21D5, 0x21E6, prN}, // So [18] UP DOWN DOUBLE ARROW..LEFTWARDS WHITE ARROW
+ {0x21E7, 0x21E7, prA}, // So UPWARDS WHITE ARROW
+ {0x21E8, 0x21F3, prN}, // So [12] RIGHTWARDS WHITE ARROW..UP DOWN WHITE ARROW
+ {0x21F4, 0x21FF, prN}, // Sm [12] RIGHT ARROW WITH SMALL CIRCLE..LEFT RIGHT OPEN-HEADED ARROW
+ {0x2200, 0x2200, prA}, // Sm FOR ALL
+ {0x2201, 0x2201, prN}, // Sm COMPLEMENT
+ {0x2202, 0x2203, prA}, // Sm [2] PARTIAL DIFFERENTIAL..THERE EXISTS
+ {0x2204, 0x2206, prN}, // Sm [3] THERE DOES NOT EXIST..INCREMENT
+ {0x2207, 0x2208, prA}, // Sm [2] NABLA..ELEMENT OF
+ {0x2209, 0x220A, prN}, // Sm [2] NOT AN ELEMENT OF..SMALL ELEMENT OF
+ {0x220B, 0x220B, prA}, // Sm CONTAINS AS MEMBER
+ {0x220C, 0x220E, prN}, // Sm [3] DOES NOT CONTAIN AS MEMBER..END OF PROOF
+ {0x220F, 0x220F, prA}, // Sm N-ARY PRODUCT
+ {0x2210, 0x2210, prN}, // Sm N-ARY COPRODUCT
+ {0x2211, 0x2211, prA}, // Sm N-ARY SUMMATION
+ {0x2212, 0x2214, prN}, // Sm [3] MINUS SIGN..DOT PLUS
+ {0x2215, 0x2215, prA}, // Sm DIVISION SLASH
+ {0x2216, 0x2219, prN}, // Sm [4] SET MINUS..BULLET OPERATOR
+ {0x221A, 0x221A, prA}, // Sm SQUARE ROOT
+ {0x221B, 0x221C, prN}, // Sm [2] CUBE ROOT..FOURTH ROOT
+ {0x221D, 0x2220, prA}, // Sm [4] PROPORTIONAL TO..ANGLE
+ {0x2221, 0x2222, prN}, // Sm [2] MEASURED ANGLE..SPHERICAL ANGLE
+ {0x2223, 0x2223, prA}, // Sm DIVIDES
+ {0x2224, 0x2224, prN}, // Sm DOES NOT DIVIDE
+ {0x2225, 0x2225, prA}, // Sm PARALLEL TO
+ {0x2226, 0x2226, prN}, // Sm NOT PARALLEL TO
+ {0x2227, 0x222C, prA}, // Sm [6] LOGICAL AND..DOUBLE INTEGRAL
+ {0x222D, 0x222D, prN}, // Sm TRIPLE INTEGRAL
+ {0x222E, 0x222E, prA}, // Sm CONTOUR INTEGRAL
+ {0x222F, 0x2233, prN}, // Sm [5] SURFACE INTEGRAL..ANTICLOCKWISE CONTOUR INTEGRAL
+ {0x2234, 0x2237, prA}, // Sm [4] THEREFORE..PROPORTION
+ {0x2238, 0x223B, prN}, // Sm [4] DOT MINUS..HOMOTHETIC
+ {0x223C, 0x223D, prA}, // Sm [2] TILDE OPERATOR..REVERSED TILDE
+ {0x223E, 0x2247, prN}, // Sm [10] INVERTED LAZY S..NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO
+ {0x2248, 0x2248, prA}, // Sm ALMOST EQUAL TO
+ {0x2249, 0x224B, prN}, // Sm [3] NOT ALMOST EQUAL TO..TRIPLE TILDE
+ {0x224C, 0x224C, prA}, // Sm ALL EQUAL TO
+ {0x224D, 0x2251, prN}, // Sm [5] EQUIVALENT TO..GEOMETRICALLY EQUAL TO
+ {0x2252, 0x2252, prA}, // Sm APPROXIMATELY EQUAL TO OR THE IMAGE OF
+ {0x2253, 0x225F, prN}, // Sm [13] IMAGE OF OR APPROXIMATELY EQUAL TO..QUESTIONED EQUAL TO
+ {0x2260, 0x2261, prA}, // Sm [2] NOT EQUAL TO..IDENTICAL TO
+ {0x2262, 0x2263, prN}, // Sm [2] NOT IDENTICAL TO..STRICTLY EQUIVALENT TO
+ {0x2264, 0x2267, prA}, // Sm [4] LESS-THAN OR EQUAL TO..GREATER-THAN OVER EQUAL TO
+ {0x2268, 0x2269, prN}, // Sm [2] LESS-THAN BUT NOT EQUAL TO..GREATER-THAN BUT NOT EQUAL TO
+ {0x226A, 0x226B, prA}, // Sm [2] MUCH LESS-THAN..MUCH GREATER-THAN
+ {0x226C, 0x226D, prN}, // Sm [2] BETWEEN..NOT EQUIVALENT TO
+ {0x226E, 0x226F, prA}, // Sm [2] NOT LESS-THAN..NOT GREATER-THAN
+ {0x2270, 0x2281, prN}, // Sm [18] NEITHER LESS-THAN NOR EQUAL TO..DOES NOT SUCCEED
+ {0x2282, 0x2283, prA}, // Sm [2] SUBSET OF..SUPERSET OF
+ {0x2284, 0x2285, prN}, // Sm [2] NOT A SUBSET OF..NOT A SUPERSET OF
+ {0x2286, 0x2287, prA}, // Sm [2] SUBSET OF OR EQUAL TO..SUPERSET OF OR EQUAL TO
+ {0x2288, 0x2294, prN}, // Sm [13] NEITHER A SUBSET OF NOR EQUAL TO..SQUARE CUP
+ {0x2295, 0x2295, prA}, // Sm CIRCLED PLUS
+ {0x2296, 0x2298, prN}, // Sm [3] CIRCLED MINUS..CIRCLED DIVISION SLASH
+ {0x2299, 0x2299, prA}, // Sm CIRCLED DOT OPERATOR
+ {0x229A, 0x22A4, prN}, // Sm [11] CIRCLED RING OPERATOR..DOWN TACK
+ {0x22A5, 0x22A5, prA}, // Sm UP TACK
+ {0x22A6, 0x22BE, prN}, // Sm [25] ASSERTION..RIGHT ANGLE WITH ARC
+ {0x22BF, 0x22BF, prA}, // Sm RIGHT TRIANGLE
+ {0x22C0, 0x22FF, prN}, // Sm [64] N-ARY LOGICAL AND..Z NOTATION BAG MEMBERSHIP
+ {0x2300, 0x2307, prN}, // So [8] DIAMETER SIGN..WAVY LINE
+ {0x2308, 0x2308, prN}, // Ps LEFT CEILING
+ {0x2309, 0x2309, prN}, // Pe RIGHT CEILING
+ {0x230A, 0x230A, prN}, // Ps LEFT FLOOR
+ {0x230B, 0x230B, prN}, // Pe RIGHT FLOOR
+ {0x230C, 0x2311, prN}, // So [6] BOTTOM RIGHT CROP..SQUARE LOZENGE
+ {0x2312, 0x2312, prA}, // So ARC
+ {0x2313, 0x2319, prN}, // So [7] SEGMENT..TURNED NOT SIGN
+ {0x231A, 0x231B, prW}, // So [2] WATCH..HOURGLASS
+ {0x231C, 0x231F, prN}, // So [4] TOP LEFT CORNER..BOTTOM RIGHT CORNER
+ {0x2320, 0x2321, prN}, // Sm [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL
+ {0x2322, 0x2328, prN}, // So [7] FROWN..KEYBOARD
+ {0x2329, 0x2329, prW}, // Ps LEFT-POINTING ANGLE BRACKET
+ {0x232A, 0x232A, prW}, // Pe RIGHT-POINTING ANGLE BRACKET
+ {0x232B, 0x237B, prN}, // So [81] ERASE TO THE LEFT..NOT CHECK MARK
+ {0x237C, 0x237C, prN}, // Sm RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW
+ {0x237D, 0x239A, prN}, // So [30] SHOULDERED OPEN BOX..CLEAR SCREEN SYMBOL
+ {0x239B, 0x23B3, prN}, // Sm [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM
+ {0x23B4, 0x23DB, prN}, // So [40] TOP SQUARE BRACKET..FUSE
+ {0x23DC, 0x23E1, prN}, // Sm [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET
+ {0x23E2, 0x23E8, prN}, // So [7] WHITE TRAPEZIUM..DECIMAL EXPONENT SYMBOL
+ {0x23E9, 0x23EC, prW}, // So [4] BLACK RIGHT-POINTING DOUBLE TRIANGLE..BLACK DOWN-POINTING DOUBLE TRIANGLE
+ {0x23ED, 0x23EF, prN}, // So [3] BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR..BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR
+ {0x23F0, 0x23F0, prW}, // So ALARM CLOCK
+ {0x23F1, 0x23F2, prN}, // So [2] STOPWATCH..TIMER CLOCK
+ {0x23F3, 0x23F3, prW}, // So HOURGLASS WITH FLOWING SAND
+ {0x23F4, 0x23FF, prN}, // So [12] BLACK MEDIUM LEFT-POINTING TRIANGLE..OBSERVER EYE SYMBOL
+ {0x2400, 0x2426, prN}, // So [39] SYMBOL FOR NULL..SYMBOL FOR SUBSTITUTE FORM TWO
+ {0x2440, 0x244A, prN}, // So [11] OCR HOOK..OCR DOUBLE BACKSLASH
+ {0x2460, 0x249B, prA}, // No [60] CIRCLED DIGIT ONE..NUMBER TWENTY FULL STOP
+ {0x249C, 0x24E9, prA}, // So [78] PARENTHESIZED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z
+ {0x24EA, 0x24EA, prN}, // No CIRCLED DIGIT ZERO
+ {0x24EB, 0x24FF, prA}, // No [21] NEGATIVE CIRCLED NUMBER ELEVEN..NEGATIVE CIRCLED DIGIT ZERO
+ {0x2500, 0x254B, prA}, // So [76] BOX DRAWINGS LIGHT HORIZONTAL..BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
+ {0x254C, 0x254F, prN}, // So [4] BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL..BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL
+ {0x2550, 0x2573, prA}, // So [36] BOX DRAWINGS DOUBLE HORIZONTAL..BOX DRAWINGS LIGHT DIAGONAL CROSS
+ {0x2574, 0x257F, prN}, // So [12] BOX DRAWINGS LIGHT LEFT..BOX DRAWINGS HEAVY UP AND LIGHT DOWN
+ {0x2580, 0x258F, prA}, // So [16] UPPER HALF BLOCK..LEFT ONE EIGHTH BLOCK
+ {0x2590, 0x2591, prN}, // So [2] RIGHT HALF BLOCK..LIGHT SHADE
+ {0x2592, 0x2595, prA}, // So [4] MEDIUM SHADE..RIGHT ONE EIGHTH BLOCK
+ {0x2596, 0x259F, prN}, // So [10] QUADRANT LOWER LEFT..QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
+ {0x25A0, 0x25A1, prA}, // So [2] BLACK SQUARE..WHITE SQUARE
+ {0x25A2, 0x25A2, prN}, // So WHITE SQUARE WITH ROUNDED CORNERS
+ {0x25A3, 0x25A9, prA}, // So [7] WHITE SQUARE CONTAINING BLACK SMALL SQUARE..SQUARE WITH DIAGONAL CROSSHATCH FILL
+ {0x25AA, 0x25B1, prN}, // So [8] BLACK SMALL SQUARE..WHITE PARALLELOGRAM
+ {0x25B2, 0x25B3, prA}, // So [2] BLACK UP-POINTING TRIANGLE..WHITE UP-POINTING TRIANGLE
+ {0x25B4, 0x25B5, prN}, // So [2] BLACK UP-POINTING SMALL TRIANGLE..WHITE UP-POINTING SMALL TRIANGLE
+ {0x25B6, 0x25B6, prA}, // So BLACK RIGHT-POINTING TRIANGLE
+ {0x25B7, 0x25B7, prA}, // Sm WHITE RIGHT-POINTING TRIANGLE
+ {0x25B8, 0x25BB, prN}, // So [4] BLACK RIGHT-POINTING SMALL TRIANGLE..WHITE RIGHT-POINTING POINTER
+ {0x25BC, 0x25BD, prA}, // So [2] BLACK DOWN-POINTING TRIANGLE..WHITE DOWN-POINTING TRIANGLE
+ {0x25BE, 0x25BF, prN}, // So [2] BLACK DOWN-POINTING SMALL TRIANGLE..WHITE DOWN-POINTING SMALL TRIANGLE
+ {0x25C0, 0x25C0, prA}, // So BLACK LEFT-POINTING TRIANGLE
+ {0x25C1, 0x25C1, prA}, // Sm WHITE LEFT-POINTING TRIANGLE
+ {0x25C2, 0x25C5, prN}, // So [4] BLACK LEFT-POINTING SMALL TRIANGLE..WHITE LEFT-POINTING POINTER
+ {0x25C6, 0x25C8, prA}, // So [3] BLACK DIAMOND..WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND
+ {0x25C9, 0x25CA, prN}, // So [2] FISHEYE..LOZENGE
+ {0x25CB, 0x25CB, prA}, // So WHITE CIRCLE
+ {0x25CC, 0x25CD, prN}, // So [2] DOTTED CIRCLE..CIRCLE WITH VERTICAL FILL
+ {0x25CE, 0x25D1, prA}, // So [4] BULLSEYE..CIRCLE WITH RIGHT HALF BLACK
+ {0x25D2, 0x25E1, prN}, // So [16] CIRCLE WITH LOWER HALF BLACK..LOWER HALF CIRCLE
+ {0x25E2, 0x25E5, prA}, // So [4] BLACK LOWER RIGHT TRIANGLE..BLACK UPPER RIGHT TRIANGLE
+ {0x25E6, 0x25EE, prN}, // So [9] WHITE BULLET..UP-POINTING TRIANGLE WITH RIGHT HALF BLACK
+ {0x25EF, 0x25EF, prA}, // So LARGE CIRCLE
+ {0x25F0, 0x25F7, prN}, // So [8] WHITE SQUARE WITH UPPER LEFT QUADRANT..WHITE CIRCLE WITH UPPER RIGHT QUADRANT
+ {0x25F8, 0x25FC, prN}, // Sm [5] UPPER LEFT TRIANGLE..BLACK MEDIUM SQUARE
+ {0x25FD, 0x25FE, prW}, // Sm [2] WHITE MEDIUM SMALL SQUARE..BLACK MEDIUM SMALL SQUARE
+ {0x25FF, 0x25FF, prN}, // Sm LOWER RIGHT TRIANGLE
+ {0x2600, 0x2604, prN}, // So [5] BLACK SUN WITH RAYS..COMET
+ {0x2605, 0x2606, prA}, // So [2] BLACK STAR..WHITE STAR
+ {0x2607, 0x2608, prN}, // So [2] LIGHTNING..THUNDERSTORM
+ {0x2609, 0x2609, prA}, // So SUN
+ {0x260A, 0x260D, prN}, // So [4] ASCENDING NODE..OPPOSITION
+ {0x260E, 0x260F, prA}, // So [2] BLACK TELEPHONE..WHITE TELEPHONE
+ {0x2610, 0x2613, prN}, // So [4] BALLOT BOX..SALTIRE
+ {0x2614, 0x2615, prW}, // So [2] UMBRELLA WITH RAIN DROPS..HOT BEVERAGE
+ {0x2616, 0x261B, prN}, // So [6] WHITE SHOGI PIECE..BLACK RIGHT POINTING INDEX
+ {0x261C, 0x261C, prA}, // So WHITE LEFT POINTING INDEX
+ {0x261D, 0x261D, prN}, // So WHITE UP POINTING INDEX
+ {0x261E, 0x261E, prA}, // So WHITE RIGHT POINTING INDEX
+ {0x261F, 0x263F, prN}, // So [33] WHITE DOWN POINTING INDEX..MERCURY
+ {0x2640, 0x2640, prA}, // So FEMALE SIGN
+ {0x2641, 0x2641, prN}, // So EARTH
+ {0x2642, 0x2642, prA}, // So MALE SIGN
+ {0x2643, 0x2647, prN}, // So [5] JUPITER..PLUTO
+ {0x2648, 0x2653, prW}, // So [12] ARIES..PISCES
+ {0x2654, 0x265F, prN}, // So [12] WHITE CHESS KING..BLACK CHESS PAWN
+ {0x2660, 0x2661, prA}, // So [2] BLACK SPADE SUIT..WHITE HEART SUIT
+ {0x2662, 0x2662, prN}, // So WHITE DIAMOND SUIT
+ {0x2663, 0x2665, prA}, // So [3] BLACK CLUB SUIT..BLACK HEART SUIT
+ {0x2666, 0x2666, prN}, // So BLACK DIAMOND SUIT
+ {0x2667, 0x266A, prA}, // So [4] WHITE CLUB SUIT..EIGHTH NOTE
+ {0x266B, 0x266B, prN}, // So BEAMED EIGHTH NOTES
+ {0x266C, 0x266D, prA}, // So [2] BEAMED SIXTEENTH NOTES..MUSIC FLAT SIGN
+ {0x266E, 0x266E, prN}, // So MUSIC NATURAL SIGN
+ {0x266F, 0x266F, prA}, // Sm MUSIC SHARP SIGN
+ {0x2670, 0x267E, prN}, // So [15] WEST SYRIAC CROSS..PERMANENT PAPER SIGN
+ {0x267F, 0x267F, prW}, // So WHEELCHAIR SYMBOL
+ {0x2680, 0x2692, prN}, // So [19] DIE FACE-1..HAMMER AND PICK
+ {0x2693, 0x2693, prW}, // So ANCHOR
+ {0x2694, 0x269D, prN}, // So [10] CROSSED SWORDS..OUTLINED WHITE STAR
+ {0x269E, 0x269F, prA}, // So [2] THREE LINES CONVERGING RIGHT..THREE LINES CONVERGING LEFT
+ {0x26A0, 0x26A0, prN}, // So WARNING SIGN
+ {0x26A1, 0x26A1, prW}, // So HIGH VOLTAGE SIGN
+ {0x26A2, 0x26A9, prN}, // So [8] DOUBLED FEMALE SIGN..HORIZONTAL MALE WITH STROKE SIGN
+ {0x26AA, 0x26AB, prW}, // So [2] MEDIUM WHITE CIRCLE..MEDIUM BLACK CIRCLE
+ {0x26AC, 0x26BC, prN}, // So [17] MEDIUM SMALL WHITE CIRCLE..SESQUIQUADRATE
+ {0x26BD, 0x26BE, prW}, // So [2] SOCCER BALL..BASEBALL
+ {0x26BF, 0x26BF, prA}, // So SQUARED KEY
+ {0x26C0, 0x26C3, prN}, // So [4] WHITE DRAUGHTS MAN..BLACK DRAUGHTS KING
+ {0x26C4, 0x26C5, prW}, // So [2] SNOWMAN WITHOUT SNOW..SUN BEHIND CLOUD
+ {0x26C6, 0x26CD, prA}, // So [8] RAIN..DISABLED CAR
+ {0x26CE, 0x26CE, prW}, // So OPHIUCHUS
+ {0x26CF, 0x26D3, prA}, // So [5] PICK..CHAINS
+ {0x26D4, 0x26D4, prW}, // So NO ENTRY
+ {0x26D5, 0x26E1, prA}, // So [13] ALTERNATE ONE-WAY LEFT WAY TRAFFIC..RESTRICTED LEFT ENTRY-2
+ {0x26E2, 0x26E2, prN}, // So ASTRONOMICAL SYMBOL FOR URANUS
+ {0x26E3, 0x26E3, prA}, // So HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE
+ {0x26E4, 0x26E7, prN}, // So [4] PENTAGRAM..INVERTED PENTAGRAM
+ {0x26E8, 0x26E9, prA}, // So [2] BLACK CROSS ON SHIELD..SHINTO SHRINE
+ {0x26EA, 0x26EA, prW}, // So CHURCH
+ {0x26EB, 0x26F1, prA}, // So [7] CASTLE..UMBRELLA ON GROUND
+ {0x26F2, 0x26F3, prW}, // So [2] FOUNTAIN..FLAG IN HOLE
+ {0x26F4, 0x26F4, prA}, // So FERRY
+ {0x26F5, 0x26F5, prW}, // So SAILBOAT
+ {0x26F6, 0x26F9, prA}, // So [4] SQUARE FOUR CORNERS..PERSON WITH BALL
+ {0x26FA, 0x26FA, prW}, // So TENT
+ {0x26FB, 0x26FC, prA}, // So [2] JAPANESE BANK SYMBOL..HEADSTONE GRAVEYARD SYMBOL
+ {0x26FD, 0x26FD, prW}, // So FUEL PUMP
+ {0x26FE, 0x26FF, prA}, // So [2] CUP ON BLACK SQUARE..WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE
+ {0x2700, 0x2704, prN}, // So [5] BLACK SAFETY SCISSORS..WHITE SCISSORS
+ {0x2705, 0x2705, prW}, // So WHITE HEAVY CHECK MARK
+ {0x2706, 0x2709, prN}, // So [4] TELEPHONE LOCATION SIGN..ENVELOPE
+ {0x270A, 0x270B, prW}, // So [2] RAISED FIST..RAISED HAND
+ {0x270C, 0x2727, prN}, // So [28] VICTORY HAND..WHITE FOUR POINTED STAR
+ {0x2728, 0x2728, prW}, // So SPARKLES
+ {0x2729, 0x273C, prN}, // So [20] STRESS OUTLINED WHITE STAR..OPEN CENTRE TEARDROP-SPOKED ASTERISK
+ {0x273D, 0x273D, prA}, // So HEAVY TEARDROP-SPOKED ASTERISK
+ {0x273E, 0x274B, prN}, // So [14] SIX PETALLED BLACK AND WHITE FLORETTE..HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK
+ {0x274C, 0x274C, prW}, // So CROSS MARK
+ {0x274D, 0x274D, prN}, // So SHADOWED WHITE CIRCLE
+ {0x274E, 0x274E, prW}, // So NEGATIVE SQUARED CROSS MARK
+ {0x274F, 0x2752, prN}, // So [4] LOWER RIGHT DROP-SHADOWED WHITE SQUARE..UPPER RIGHT SHADOWED WHITE SQUARE
+ {0x2753, 0x2755, prW}, // So [3] BLACK QUESTION MARK ORNAMENT..WHITE EXCLAMATION MARK ORNAMENT
+ {0x2756, 0x2756, prN}, // So BLACK DIAMOND MINUS WHITE X
+ {0x2757, 0x2757, prW}, // So HEAVY EXCLAMATION MARK SYMBOL
+ {0x2758, 0x2767, prN}, // So [16] LIGHT VERTICAL BAR..ROTATED FLORAL HEART BULLET
+ {0x2768, 0x2768, prN}, // Ps MEDIUM LEFT PARENTHESIS ORNAMENT
+ {0x2769, 0x2769, prN}, // Pe MEDIUM RIGHT PARENTHESIS ORNAMENT
+ {0x276A, 0x276A, prN}, // Ps MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT
+ {0x276B, 0x276B, prN}, // Pe MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT
+ {0x276C, 0x276C, prN}, // Ps MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT
+ {0x276D, 0x276D, prN}, // Pe MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT
+ {0x276E, 0x276E, prN}, // Ps HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT
+ {0x276F, 0x276F, prN}, // Pe HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT
+ {0x2770, 0x2770, prN}, // Ps HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT
+ {0x2771, 0x2771, prN}, // Pe HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT
+ {0x2772, 0x2772, prN}, // Ps LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT
+ {0x2773, 0x2773, prN}, // Pe LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT
+ {0x2774, 0x2774, prN}, // Ps MEDIUM LEFT CURLY BRACKET ORNAMENT
+ {0x2775, 0x2775, prN}, // Pe MEDIUM RIGHT CURLY BRACKET ORNAMENT
+ {0x2776, 0x277F, prA}, // No [10] DINGBAT NEGATIVE CIRCLED DIGIT ONE..DINGBAT NEGATIVE CIRCLED NUMBER TEN
+ {0x2780, 0x2793, prN}, // No [20] DINGBAT CIRCLED SANS-SERIF DIGIT ONE..DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN
+ {0x2794, 0x2794, prN}, // So HEAVY WIDE-HEADED RIGHTWARDS ARROW
+ {0x2795, 0x2797, prW}, // So [3] HEAVY PLUS SIGN..HEAVY DIVISION SIGN
+ {0x2798, 0x27AF, prN}, // So [24] HEAVY SOUTH EAST ARROW..NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
+ {0x27B0, 0x27B0, prW}, // So CURLY LOOP
+ {0x27B1, 0x27BE, prN}, // So [14] NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW..OPEN-OUTLINED RIGHTWARDS ARROW
+ {0x27BF, 0x27BF, prW}, // So DOUBLE CURLY LOOP
+ {0x27C0, 0x27C4, prN}, // Sm [5] THREE DIMENSIONAL ANGLE..OPEN SUPERSET
+ {0x27C5, 0x27C5, prN}, // Ps LEFT S-SHAPED BAG DELIMITER
+ {0x27C6, 0x27C6, prN}, // Pe RIGHT S-SHAPED BAG DELIMITER
+ {0x27C7, 0x27E5, prN}, // Sm [31] OR WITH DOT INSIDE..WHITE SQUARE WITH RIGHTWARDS TICK
+ {0x27E6, 0x27E6, prNa}, // Ps MATHEMATICAL LEFT WHITE SQUARE BRACKET
+ {0x27E7, 0x27E7, prNa}, // Pe MATHEMATICAL RIGHT WHITE SQUARE BRACKET
+ {0x27E8, 0x27E8, prNa}, // Ps MATHEMATICAL LEFT ANGLE BRACKET
+ {0x27E9, 0x27E9, prNa}, // Pe MATHEMATICAL RIGHT ANGLE BRACKET
+ {0x27EA, 0x27EA, prNa}, // Ps MATHEMATICAL LEFT DOUBLE ANGLE BRACKET
+ {0x27EB, 0x27EB, prNa}, // Pe MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET
+ {0x27EC, 0x27EC, prNa}, // Ps MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET
+ {0x27ED, 0x27ED, prNa}, // Pe MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET
+ {0x27EE, 0x27EE, prN}, // Ps MATHEMATICAL LEFT FLATTENED PARENTHESIS
+ {0x27EF, 0x27EF, prN}, // Pe MATHEMATICAL RIGHT FLATTENED PARENTHESIS
+ {0x27F0, 0x27FF, prN}, // Sm [16] UPWARDS QUADRUPLE ARROW..LONG RIGHTWARDS SQUIGGLE ARROW
+ {0x2800, 0x28FF, prN}, // So [256] BRAILLE PATTERN BLANK..BRAILLE PATTERN DOTS-12345678
+ {0x2900, 0x297F, prN}, // Sm [128] RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE..DOWN FISH TAIL
+ {0x2980, 0x2982, prN}, // Sm [3] TRIPLE VERTICAL BAR DELIMITER..Z NOTATION TYPE COLON
+ {0x2983, 0x2983, prN}, // Ps LEFT WHITE CURLY BRACKET
+ {0x2984, 0x2984, prN}, // Pe RIGHT WHITE CURLY BRACKET
+ {0x2985, 0x2985, prNa}, // Ps LEFT WHITE PARENTHESIS
+ {0x2986, 0x2986, prNa}, // Pe RIGHT WHITE PARENTHESIS
+ {0x2987, 0x2987, prN}, // Ps Z NOTATION LEFT IMAGE BRACKET
+ {0x2988, 0x2988, prN}, // Pe Z NOTATION RIGHT IMAGE BRACKET
+ {0x2989, 0x2989, prN}, // Ps Z NOTATION LEFT BINDING BRACKET
+ {0x298A, 0x298A, prN}, // Pe Z NOTATION RIGHT BINDING BRACKET
+ {0x298B, 0x298B, prN}, // Ps LEFT SQUARE BRACKET WITH UNDERBAR
+ {0x298C, 0x298C, prN}, // Pe RIGHT SQUARE BRACKET WITH UNDERBAR
+ {0x298D, 0x298D, prN}, // Ps LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
+ {0x298E, 0x298E, prN}, // Pe RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
+ {0x298F, 0x298F, prN}, // Ps LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
+ {0x2990, 0x2990, prN}, // Pe RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER
+ {0x2991, 0x2991, prN}, // Ps LEFT ANGLE BRACKET WITH DOT
+ {0x2992, 0x2992, prN}, // Pe RIGHT ANGLE BRACKET WITH DOT
+ {0x2993, 0x2993, prN}, // Ps LEFT ARC LESS-THAN BRACKET
+ {0x2994, 0x2994, prN}, // Pe RIGHT ARC GREATER-THAN BRACKET
+ {0x2995, 0x2995, prN}, // Ps DOUBLE LEFT ARC GREATER-THAN BRACKET
+ {0x2996, 0x2996, prN}, // Pe DOUBLE RIGHT ARC LESS-THAN BRACKET
+ {0x2997, 0x2997, prN}, // Ps LEFT BLACK TORTOISE SHELL BRACKET
+ {0x2998, 0x2998, prN}, // Pe RIGHT BLACK TORTOISE SHELL BRACKET
+ {0x2999, 0x29D7, prN}, // Sm [63] DOTTED FENCE..BLACK HOURGLASS
+ {0x29D8, 0x29D8, prN}, // Ps LEFT WIGGLY FENCE
+ {0x29D9, 0x29D9, prN}, // Pe RIGHT WIGGLY FENCE
+ {0x29DA, 0x29DA, prN}, // Ps LEFT DOUBLE WIGGLY FENCE
+ {0x29DB, 0x29DB, prN}, // Pe RIGHT DOUBLE WIGGLY FENCE
+ {0x29DC, 0x29FB, prN}, // Sm [32] INCOMPLETE INFINITY..TRIPLE PLUS
+ {0x29FC, 0x29FC, prN}, // Ps LEFT-POINTING CURVED ANGLE BRACKET
+ {0x29FD, 0x29FD, prN}, // Pe RIGHT-POINTING CURVED ANGLE BRACKET
+ {0x29FE, 0x29FF, prN}, // Sm [2] TINY..MINY
+ {0x2A00, 0x2AFF, prN}, // Sm [256] N-ARY CIRCLED DOT OPERATOR..N-ARY WHITE VERTICAL BAR
+ {0x2B00, 0x2B1A, prN}, // So [27] NORTH EAST WHITE ARROW..DOTTED SQUARE
+ {0x2B1B, 0x2B1C, prW}, // So [2] BLACK LARGE SQUARE..WHITE LARGE SQUARE
+ {0x2B1D, 0x2B2F, prN}, // So [19] BLACK VERY SMALL SQUARE..WHITE VERTICAL ELLIPSE
+ {0x2B30, 0x2B44, prN}, // Sm [21] LEFT ARROW WITH SMALL CIRCLE..RIGHTWARDS ARROW THROUGH SUPERSET
+ {0x2B45, 0x2B46, prN}, // So [2] LEFTWARDS QUADRUPLE ARROW..RIGHTWARDS QUADRUPLE ARROW
+ {0x2B47, 0x2B4C, prN}, // Sm [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR
+ {0x2B4D, 0x2B4F, prN}, // So [3] DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW..SHORT BACKSLANTED SOUTH ARROW
+ {0x2B50, 0x2B50, prW}, // So WHITE MEDIUM STAR
+ {0x2B51, 0x2B54, prN}, // So [4] BLACK SMALL STAR..WHITE RIGHT-POINTING PENTAGON
+ {0x2B55, 0x2B55, prW}, // So HEAVY LARGE CIRCLE
+ {0x2B56, 0x2B59, prA}, // So [4] HEAVY OVAL WITH OVAL INSIDE..HEAVY CIRCLED SALTIRE
+ {0x2B5A, 0x2B73, prN}, // So [26] SLANTED NORTH ARROW WITH HOOKED HEAD..DOWNWARDS TRIANGLE-HEADED ARROW TO BAR
+ {0x2B76, 0x2B95, prN}, // So [32] NORTH WEST TRIANGLE-HEADED ARROW TO BAR..RIGHTWARDS BLACK ARROW
+ {0x2B97, 0x2BFF, prN}, // So [105] SYMBOL FOR TYPE A ELECTRONICS..HELLSCHREIBER PAUSE SYMBOL
+ {0x2C00, 0x2C5F, prN}, // L& [96] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC SMALL LETTER CAUDATE CHRIVI
+ {0x2C60, 0x2C7B, prN}, // L& [28] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN LETTER SMALL CAPITAL TURNED E
+ {0x2C7C, 0x2C7D, prN}, // Lm [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V
+ {0x2C7E, 0x2C7F, prN}, // Lu [2] LATIN CAPITAL LETTER S WITH SWASH TAIL..LATIN CAPITAL LETTER Z WITH SWASH TAIL
+ {0x2C80, 0x2CE4, prN}, // L& [101] COPTIC CAPITAL LETTER ALFA..COPTIC SYMBOL KAI
+ {0x2CE5, 0x2CEA, prN}, // So [6] COPTIC SYMBOL MI RO..COPTIC SYMBOL SHIMA SIMA
+ {0x2CEB, 0x2CEE, prN}, // L& [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA
+ {0x2CEF, 0x2CF1, prN}, // Mn [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS
+ {0x2CF2, 0x2CF3, prN}, // L& [2] COPTIC CAPITAL LETTER BOHAIRIC KHEI..COPTIC SMALL LETTER BOHAIRIC KHEI
+ {0x2CF9, 0x2CFC, prN}, // Po [4] COPTIC OLD NUBIAN FULL STOP..COPTIC OLD NUBIAN VERSE DIVIDER
+ {0x2CFD, 0x2CFD, prN}, // No COPTIC FRACTION ONE HALF
+ {0x2CFE, 0x2CFF, prN}, // Po [2] COPTIC FULL STOP..COPTIC MORPHOLOGICAL DIVIDER
+ {0x2D00, 0x2D25, prN}, // Ll [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE
+ {0x2D27, 0x2D27, prN}, // Ll GEORGIAN SMALL LETTER YN
+ {0x2D2D, 0x2D2D, prN}, // Ll GEORGIAN SMALL LETTER AEN
+ {0x2D30, 0x2D67, prN}, // Lo [56] TIFINAGH LETTER YA..TIFINAGH LETTER YO
+ {0x2D6F, 0x2D6F, prN}, // Lm TIFINAGH MODIFIER LETTER LABIALIZATION MARK
+ {0x2D70, 0x2D70, prN}, // Po TIFINAGH SEPARATOR MARK
+ {0x2D7F, 0x2D7F, prN}, // Mn TIFINAGH CONSONANT JOINER
+ {0x2D80, 0x2D96, prN}, // Lo [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE
+ {0x2DA0, 0x2DA6, prN}, // Lo [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO
+ {0x2DA8, 0x2DAE, prN}, // Lo [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO
+ {0x2DB0, 0x2DB6, prN}, // Lo [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO
+ {0x2DB8, 0x2DBE, prN}, // Lo [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO
+ {0x2DC0, 0x2DC6, prN}, // Lo [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO
+ {0x2DC8, 0x2DCE, prN}, // Lo [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO
+ {0x2DD0, 0x2DD6, prN}, // Lo [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO
+ {0x2DD8, 0x2DDE, prN}, // Lo [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO
+ {0x2DE0, 0x2DFF, prN}, // Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS
+ {0x2E00, 0x2E01, prN}, // Po [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER
+ {0x2E02, 0x2E02, prN}, // Pi LEFT SUBSTITUTION BRACKET
+ {0x2E03, 0x2E03, prN}, // Pf RIGHT SUBSTITUTION BRACKET
+ {0x2E04, 0x2E04, prN}, // Pi LEFT DOTTED SUBSTITUTION BRACKET
+ {0x2E05, 0x2E05, prN}, // Pf RIGHT DOTTED SUBSTITUTION BRACKET
+ {0x2E06, 0x2E08, prN}, // Po [3] RAISED INTERPOLATION MARKER..DOTTED TRANSPOSITION MARKER
+ {0x2E09, 0x2E09, prN}, // Pi LEFT TRANSPOSITION BRACKET
+ {0x2E0A, 0x2E0A, prN}, // Pf RIGHT TRANSPOSITION BRACKET
+ {0x2E0B, 0x2E0B, prN}, // Po RAISED SQUARE
+ {0x2E0C, 0x2E0C, prN}, // Pi LEFT RAISED OMISSION BRACKET
+ {0x2E0D, 0x2E0D, prN}, // Pf RIGHT RAISED OMISSION BRACKET
+ {0x2E0E, 0x2E16, prN}, // Po [9] EDITORIAL CORONIS..DOTTED RIGHT-POINTING ANGLE
+ {0x2E17, 0x2E17, prN}, // Pd DOUBLE OBLIQUE HYPHEN
+ {0x2E18, 0x2E19, prN}, // Po [2] INVERTED INTERROBANG..PALM BRANCH
+ {0x2E1A, 0x2E1A, prN}, // Pd HYPHEN WITH DIAERESIS
+ {0x2E1B, 0x2E1B, prN}, // Po TILDE WITH RING ABOVE
+ {0x2E1C, 0x2E1C, prN}, // Pi LEFT LOW PARAPHRASE BRACKET
+ {0x2E1D, 0x2E1D, prN}, // Pf RIGHT LOW PARAPHRASE BRACKET
+ {0x2E1E, 0x2E1F, prN}, // Po [2] TILDE WITH DOT ABOVE..TILDE WITH DOT BELOW
+ {0x2E20, 0x2E20, prN}, // Pi LEFT VERTICAL BAR WITH QUILL
+ {0x2E21, 0x2E21, prN}, // Pf RIGHT VERTICAL BAR WITH QUILL
+ {0x2E22, 0x2E22, prN}, // Ps TOP LEFT HALF BRACKET
+ {0x2E23, 0x2E23, prN}, // Pe TOP RIGHT HALF BRACKET
+ {0x2E24, 0x2E24, prN}, // Ps BOTTOM LEFT HALF BRACKET
+ {0x2E25, 0x2E25, prN}, // Pe BOTTOM RIGHT HALF BRACKET
+ {0x2E26, 0x2E26, prN}, // Ps LEFT SIDEWAYS U BRACKET
+ {0x2E27, 0x2E27, prN}, // Pe RIGHT SIDEWAYS U BRACKET
+ {0x2E28, 0x2E28, prN}, // Ps LEFT DOUBLE PARENTHESIS
+ {0x2E29, 0x2E29, prN}, // Pe RIGHT DOUBLE PARENTHESIS
+ {0x2E2A, 0x2E2E, prN}, // Po [5] TWO DOTS OVER ONE DOT PUNCTUATION..REVERSED QUESTION MARK
+ {0x2E2F, 0x2E2F, prN}, // Lm VERTICAL TILDE
+ {0x2E30, 0x2E39, prN}, // Po [10] RING POINT..TOP HALF SECTION SIGN
+ {0x2E3A, 0x2E3B, prN}, // Pd [2] TWO-EM DASH..THREE-EM DASH
+ {0x2E3C, 0x2E3F, prN}, // Po [4] STENOGRAPHIC FULL STOP..CAPITULUM
+ {0x2E40, 0x2E40, prN}, // Pd DOUBLE HYPHEN
+ {0x2E41, 0x2E41, prN}, // Po REVERSED COMMA
+ {0x2E42, 0x2E42, prN}, // Ps DOUBLE LOW-REVERSED-9 QUOTATION MARK
+ {0x2E43, 0x2E4F, prN}, // Po [13] DASH WITH LEFT UPTURN..CORNISH VERSE DIVIDER
+ {0x2E50, 0x2E51, prN}, // So [2] CROSS PATTY WITH RIGHT CROSSBAR..CROSS PATTY WITH LEFT CROSSBAR
+ {0x2E52, 0x2E54, prN}, // Po [3] TIRONIAN SIGN CAPITAL ET..MEDIEVAL QUESTION MARK
+ {0x2E55, 0x2E55, prN}, // Ps LEFT SQUARE BRACKET WITH STROKE
+ {0x2E56, 0x2E56, prN}, // Pe RIGHT SQUARE BRACKET WITH STROKE
+ {0x2E57, 0x2E57, prN}, // Ps LEFT SQUARE BRACKET WITH DOUBLE STROKE
+ {0x2E58, 0x2E58, prN}, // Pe RIGHT SQUARE BRACKET WITH DOUBLE STROKE
+ {0x2E59, 0x2E59, prN}, // Ps TOP HALF LEFT PARENTHESIS
+ {0x2E5A, 0x2E5A, prN}, // Pe TOP HALF RIGHT PARENTHESIS
+ {0x2E5B, 0x2E5B, prN}, // Ps BOTTOM HALF LEFT PARENTHESIS
+ {0x2E5C, 0x2E5C, prN}, // Pe BOTTOM HALF RIGHT PARENTHESIS
+ {0x2E5D, 0x2E5D, prN}, // Pd OBLIQUE HYPHEN
+ {0x2E80, 0x2E99, prW}, // So [26] CJK RADICAL REPEAT..CJK RADICAL RAP
+ {0x2E9B, 0x2EF3, prW}, // So [89] CJK RADICAL CHOKE..CJK RADICAL C-SIMPLIFIED TURTLE
+ {0x2F00, 0x2FD5, prW}, // So [214] KANGXI RADICAL ONE..KANGXI RADICAL FLUTE
+ {0x2FF0, 0x2FFB, prW}, // So [12] IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT..IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID
+ {0x3000, 0x3000, prF}, // Zs IDEOGRAPHIC SPACE
+ {0x3001, 0x3003, prW}, // Po [3] IDEOGRAPHIC COMMA..DITTO MARK
+ {0x3004, 0x3004, prW}, // So JAPANESE INDUSTRIAL STANDARD SYMBOL
+ {0x3005, 0x3005, prW}, // Lm IDEOGRAPHIC ITERATION MARK
+ {0x3006, 0x3006, prW}, // Lo IDEOGRAPHIC CLOSING MARK
+ {0x3007, 0x3007, prW}, // Nl IDEOGRAPHIC NUMBER ZERO
+ {0x3008, 0x3008, prW}, // Ps LEFT ANGLE BRACKET
+ {0x3009, 0x3009, prW}, // Pe RIGHT ANGLE BRACKET
+ {0x300A, 0x300A, prW}, // Ps LEFT DOUBLE ANGLE BRACKET
+ {0x300B, 0x300B, prW}, // Pe RIGHT DOUBLE ANGLE BRACKET
+ {0x300C, 0x300C, prW}, // Ps LEFT CORNER BRACKET
+ {0x300D, 0x300D, prW}, // Pe RIGHT CORNER BRACKET
+ {0x300E, 0x300E, prW}, // Ps LEFT WHITE CORNER BRACKET
+ {0x300F, 0x300F, prW}, // Pe RIGHT WHITE CORNER BRACKET
+ {0x3010, 0x3010, prW}, // Ps LEFT BLACK LENTICULAR BRACKET
+ {0x3011, 0x3011, prW}, // Pe RIGHT BLACK LENTICULAR BRACKET
+ {0x3012, 0x3013, prW}, // So [2] POSTAL MARK..GETA MARK
+ {0x3014, 0x3014, prW}, // Ps LEFT TORTOISE SHELL BRACKET
+ {0x3015, 0x3015, prW}, // Pe RIGHT TORTOISE SHELL BRACKET
+ {0x3016, 0x3016, prW}, // Ps LEFT WHITE LENTICULAR BRACKET
+ {0x3017, 0x3017, prW}, // Pe RIGHT WHITE LENTICULAR BRACKET
+ {0x3018, 0x3018, prW}, // Ps LEFT WHITE TORTOISE SHELL BRACKET
+ {0x3019, 0x3019, prW}, // Pe RIGHT WHITE TORTOISE SHELL BRACKET
+ {0x301A, 0x301A, prW}, // Ps LEFT WHITE SQUARE BRACKET
+ {0x301B, 0x301B, prW}, // Pe RIGHT WHITE SQUARE BRACKET
+ {0x301C, 0x301C, prW}, // Pd WAVE DASH
+ {0x301D, 0x301D, prW}, // Ps REVERSED DOUBLE PRIME QUOTATION MARK
+ {0x301E, 0x301F, prW}, // Pe [2] DOUBLE PRIME QUOTATION MARK..LOW DOUBLE PRIME QUOTATION MARK
+ {0x3020, 0x3020, prW}, // So POSTAL MARK FACE
+ {0x3021, 0x3029, prW}, // Nl [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE
+ {0x302A, 0x302D, prW}, // Mn [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK
+ {0x302E, 0x302F, prW}, // Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK
+ {0x3030, 0x3030, prW}, // Pd WAVY DASH
+ {0x3031, 0x3035, prW}, // Lm [5] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT MARK LOWER HALF
+ {0x3036, 0x3037, prW}, // So [2] CIRCLED POSTAL MARK..IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL
+ {0x3038, 0x303A, prW}, // Nl [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY
+ {0x303B, 0x303B, prW}, // Lm VERTICAL IDEOGRAPHIC ITERATION MARK
+ {0x303C, 0x303C, prW}, // Lo MASU MARK
+ {0x303D, 0x303D, prW}, // Po PART ALTERNATION MARK
+ {0x303E, 0x303E, prW}, // So IDEOGRAPHIC VARIATION INDICATOR
+ {0x303F, 0x303F, prN}, // So IDEOGRAPHIC HALF FILL SPACE
+ {0x3041, 0x3096, prW}, // Lo [86] HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE
+ {0x3099, 0x309A, prW}, // Mn [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+ {0x309B, 0x309C, prW}, // Sk [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+ {0x309D, 0x309E, prW}, // Lm [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK
+ {0x309F, 0x309F, prW}, // Lo HIRAGANA DIGRAPH YORI
+ {0x30A0, 0x30A0, prW}, // Pd KATAKANA-HIRAGANA DOUBLE HYPHEN
+ {0x30A1, 0x30FA, prW}, // Lo [90] KATAKANA LETTER SMALL A..KATAKANA LETTER VO
+ {0x30FB, 0x30FB, prW}, // Po KATAKANA MIDDLE DOT
+ {0x30FC, 0x30FE, prW}, // Lm [3] KATAKANA-HIRAGANA PROLONGED SOUND MARK..KATAKANA VOICED ITERATION MARK
+ {0x30FF, 0x30FF, prW}, // Lo KATAKANA DIGRAPH KOTO
+ {0x3105, 0x312F, prW}, // Lo [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN
+ {0x3131, 0x318E, prW}, // Lo [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE
+ {0x3190, 0x3191, prW}, // So [2] IDEOGRAPHIC ANNOTATION LINKING MARK..IDEOGRAPHIC ANNOTATION REVERSE MARK
+ {0x3192, 0x3195, prW}, // No [4] IDEOGRAPHIC ANNOTATION ONE MARK..IDEOGRAPHIC ANNOTATION FOUR MARK
+ {0x3196, 0x319F, prW}, // So [10] IDEOGRAPHIC ANNOTATION TOP MARK..IDEOGRAPHIC ANNOTATION MAN MARK
+ {0x31A0, 0x31BF, prW}, // Lo [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH
+ {0x31C0, 0x31E3, prW}, // So [36] CJK STROKE T..CJK STROKE Q
+ {0x31F0, 0x31FF, prW}, // Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO
+ {0x3200, 0x321E, prW}, // So [31] PARENTHESIZED HANGUL KIYEOK..PARENTHESIZED KOREAN CHARACTER O HU
+ {0x3220, 0x3229, prW}, // No [10] PARENTHESIZED IDEOGRAPH ONE..PARENTHESIZED IDEOGRAPH TEN
+ {0x322A, 0x3247, prW}, // So [30] PARENTHESIZED IDEOGRAPH MOON..CIRCLED IDEOGRAPH KOTO
+ {0x3248, 0x324F, prA}, // No [8] CIRCLED NUMBER TEN ON BLACK SQUARE..CIRCLED NUMBER EIGHTY ON BLACK SQUARE
+ {0x3250, 0x3250, prW}, // So PARTNERSHIP SIGN
+ {0x3251, 0x325F, prW}, // No [15] CIRCLED NUMBER TWENTY ONE..CIRCLED NUMBER THIRTY FIVE
+ {0x3260, 0x327F, prW}, // So [32] CIRCLED HANGUL KIYEOK..KOREAN STANDARD SYMBOL
+ {0x3280, 0x3289, prW}, // No [10] CIRCLED IDEOGRAPH ONE..CIRCLED IDEOGRAPH TEN
+ {0x328A, 0x32B0, prW}, // So [39] CIRCLED IDEOGRAPH MOON..CIRCLED IDEOGRAPH NIGHT
+ {0x32B1, 0x32BF, prW}, // No [15] CIRCLED NUMBER THIRTY SIX..CIRCLED NUMBER FIFTY
+ {0x32C0, 0x32FF, prW}, // So [64] IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY..SQUARE ERA NAME REIWA
+ {0x3300, 0x33FF, prW}, // So [256] SQUARE APAATO..SQUARE GAL
+ {0x3400, 0x4DBF, prW}, // Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF
+ {0x4DC0, 0x4DFF, prN}, // So [64] HEXAGRAM FOR THE CREATIVE HEAVEN..HEXAGRAM FOR BEFORE COMPLETION
+ {0x4E00, 0x9FFF, prW}, // Lo [20992] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFF
+ {0xA000, 0xA014, prW}, // Lo [21] YI SYLLABLE IT..YI SYLLABLE E
+ {0xA015, 0xA015, prW}, // Lm YI SYLLABLE WU
+ {0xA016, 0xA48C, prW}, // Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR
+ {0xA490, 0xA4C6, prW}, // So [55] YI RADICAL QOT..YI RADICAL KE
+ {0xA4D0, 0xA4F7, prN}, // Lo [40] LISU LETTER BA..LISU LETTER OE
+ {0xA4F8, 0xA4FD, prN}, // Lm [6] LISU LETTER TONE MYA TI..LISU LETTER TONE MYA JEU
+ {0xA4FE, 0xA4FF, prN}, // Po [2] LISU PUNCTUATION COMMA..LISU PUNCTUATION FULL STOP
+ {0xA500, 0xA60B, prN}, // Lo [268] VAI SYLLABLE EE..VAI SYLLABLE NG
+ {0xA60C, 0xA60C, prN}, // Lm VAI SYLLABLE LENGTHENER
+ {0xA60D, 0xA60F, prN}, // Po [3] VAI COMMA..VAI QUESTION MARK
+ {0xA610, 0xA61F, prN}, // Lo [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG
+ {0xA620, 0xA629, prN}, // Nd [10] VAI DIGIT ZERO..VAI DIGIT NINE
+ {0xA62A, 0xA62B, prN}, // Lo [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO
+ {0xA640, 0xA66D, prN}, // L& [46] CYRILLIC CAPITAL LETTER ZEMLYA..CYRILLIC SMALL LETTER DOUBLE MONOCULAR O
+ {0xA66E, 0xA66E, prN}, // Lo CYRILLIC LETTER MULTIOCULAR O
+ {0xA66F, 0xA66F, prN}, // Mn COMBINING CYRILLIC VZMET
+ {0xA670, 0xA672, prN}, // Me [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN
+ {0xA673, 0xA673, prN}, // Po SLAVONIC ASTERISK
+ {0xA674, 0xA67D, prN}, // Mn [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK
+ {0xA67E, 0xA67E, prN}, // Po CYRILLIC KAVYKA
+ {0xA67F, 0xA67F, prN}, // Lm CYRILLIC PAYEROK
+ {0xA680, 0xA69B, prN}, // L& [28] CYRILLIC CAPITAL LETTER DWE..CYRILLIC SMALL LETTER CROSSED O
+ {0xA69C, 0xA69D, prN}, // Lm [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN
+ {0xA69E, 0xA69F, prN}, // Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E
+ {0xA6A0, 0xA6E5, prN}, // Lo [70] BAMUM LETTER A..BAMUM LETTER KI
+ {0xA6E6, 0xA6EF, prN}, // Nl [10] BAMUM LETTER MO..BAMUM LETTER KOGHOM
+ {0xA6F0, 0xA6F1, prN}, // Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS
+ {0xA6F2, 0xA6F7, prN}, // Po [6] BAMUM NJAEMLI..BAMUM QUESTION MARK
+ {0xA700, 0xA716, prN}, // Sk [23] MODIFIER LETTER CHINESE TONE YIN PING..MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR
+ {0xA717, 0xA71F, prN}, // Lm [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK
+ {0xA720, 0xA721, prN}, // Sk [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIFIER LETTER STRESS AND LOW TONE
+ {0xA722, 0xA76F, prN}, // L& [78] LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF..LATIN SMALL LETTER CON
+ {0xA770, 0xA770, prN}, // Lm MODIFIER LETTER US
+ {0xA771, 0xA787, prN}, // L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T
+ {0xA788, 0xA788, prN}, // Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT
+ {0xA789, 0xA78A, prN}, // Sk [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN
+ {0xA78B, 0xA78E, prN}, // L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT
+ {0xA78F, 0xA78F, prN}, // Lo LATIN LETTER SINOLOGICAL DOT
+ {0xA790, 0xA7CA, prN}, // L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY
+ {0xA7D0, 0xA7D1, prN}, // L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G
+ {0xA7D3, 0xA7D3, prN}, // Ll LATIN SMALL LETTER DOUBLE THORN
+ {0xA7D5, 0xA7D9, prN}, // L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S
+ {0xA7F2, 0xA7F4, prN}, // Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q
+ {0xA7F5, 0xA7F6, prN}, // L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H
+ {0xA7F7, 0xA7F7, prN}, // Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I
+ {0xA7F8, 0xA7F9, prN}, // Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE
+ {0xA7FA, 0xA7FA, prN}, // Ll LATIN LETTER SMALL CAPITAL TURNED M
+ {0xA7FB, 0xA7FF, prN}, // Lo [5] LATIN EPIGRAPHIC LETTER REVERSED F..LATIN EPIGRAPHIC LETTER ARCHAIC M
+ {0xA800, 0xA801, prN}, // Lo [2] SYLOTI NAGRI LETTER A..SYLOTI NAGRI LETTER I
+ {0xA802, 0xA802, prN}, // Mn SYLOTI NAGRI SIGN DVISVARA
+ {0xA803, 0xA805, prN}, // Lo [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O
+ {0xA806, 0xA806, prN}, // Mn SYLOTI NAGRI SIGN HASANTA
+ {0xA807, 0xA80A, prN}, // Lo [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO
+ {0xA80B, 0xA80B, prN}, // Mn SYLOTI NAGRI SIGN ANUSVARA
+ {0xA80C, 0xA822, prN}, // Lo [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO
+ {0xA823, 0xA824, prN}, // Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I
+ {0xA825, 0xA826, prN}, // Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E
+ {0xA827, 0xA827, prN}, // Mc SYLOTI NAGRI VOWEL SIGN OO
+ {0xA828, 0xA82B, prN}, // So [4] SYLOTI NAGRI POETRY MARK-1..SYLOTI NAGRI POETRY MARK-4
+ {0xA82C, 0xA82C, prN}, // Mn SYLOTI NAGRI SIGN ALTERNATE HASANTA
+ {0xA830, 0xA835, prN}, // No [6] NORTH INDIC FRACTION ONE QUARTER..NORTH INDIC FRACTION THREE SIXTEENTHS
+ {0xA836, 0xA837, prN}, // So [2] NORTH INDIC QUARTER MARK..NORTH INDIC PLACEHOLDER MARK
+ {0xA838, 0xA838, prN}, // Sc NORTH INDIC RUPEE MARK
+ {0xA839, 0xA839, prN}, // So NORTH INDIC QUANTITY MARK
+ {0xA840, 0xA873, prN}, // Lo [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU
+ {0xA874, 0xA877, prN}, // Po [4] PHAGS-PA SINGLE HEAD MARK..PHAGS-PA MARK DOUBLE SHAD
+ {0xA880, 0xA881, prN}, // Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA
+ {0xA882, 0xA8B3, prN}, // Lo [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA
+ {0xA8B4, 0xA8C3, prN}, // Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU
+ {0xA8C4, 0xA8C5, prN}, // Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU
+ {0xA8CE, 0xA8CF, prN}, // Po [2] SAURASHTRA DANDA..SAURASHTRA DOUBLE DANDA
+ {0xA8D0, 0xA8D9, prN}, // Nd [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE
+ {0xA8E0, 0xA8F1, prN}, // Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA
+ {0xA8F2, 0xA8F7, prN}, // Lo [6] DEVANAGARI SIGN SPACING CANDRABINDU..DEVANAGARI SIGN CANDRABINDU AVAGRAHA
+ {0xA8F8, 0xA8FA, prN}, // Po [3] DEVANAGARI SIGN PUSHPIKA..DEVANAGARI CARET
+ {0xA8FB, 0xA8FB, prN}, // Lo DEVANAGARI HEADSTROKE
+ {0xA8FC, 0xA8FC, prN}, // Po DEVANAGARI SIGN SIDDHAM
+ {0xA8FD, 0xA8FE, prN}, // Lo [2] DEVANAGARI JAIN OM..DEVANAGARI LETTER AY
+ {0xA8FF, 0xA8FF, prN}, // Mn DEVANAGARI VOWEL SIGN AY
+ {0xA900, 0xA909, prN}, // Nd [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE
+ {0xA90A, 0xA925, prN}, // Lo [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO
+ {0xA926, 0xA92D, prN}, // Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU
+ {0xA92E, 0xA92F, prN}, // Po [2] KAYAH LI SIGN CWI..KAYAH LI SIGN SHYA
+ {0xA930, 0xA946, prN}, // Lo [23] REJANG LETTER KA..REJANG LETTER A
+ {0xA947, 0xA951, prN}, // Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R
+ {0xA952, 0xA953, prN}, // Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA
+ {0xA95F, 0xA95F, prN}, // Po REJANG SECTION MARK
+ {0xA960, 0xA97C, prW}, // Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH
+ {0xA980, 0xA982, prN}, // Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR
+ {0xA983, 0xA983, prN}, // Mc JAVANESE SIGN WIGNYAN
+ {0xA984, 0xA9B2, prN}, // Lo [47] JAVANESE LETTER A..JAVANESE LETTER HA
+ {0xA9B3, 0xA9B3, prN}, // Mn JAVANESE SIGN CECAK TELU
+ {0xA9B4, 0xA9B5, prN}, // Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG
+ {0xA9B6, 0xA9B9, prN}, // Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT
+ {0xA9BA, 0xA9BB, prN}, // Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE
+ {0xA9BC, 0xA9BD, prN}, // Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET
+ {0xA9BE, 0xA9C0, prN}, // Mc [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON
+ {0xA9C1, 0xA9CD, prN}, // Po [13] JAVANESE LEFT RERENGGAN..JAVANESE TURNED PADA PISELEH
+ {0xA9CF, 0xA9CF, prN}, // Lm JAVANESE PANGRANGKEP
+ {0xA9D0, 0xA9D9, prN}, // Nd [10] JAVANESE DIGIT ZERO..JAVANESE DIGIT NINE
+ {0xA9DE, 0xA9DF, prN}, // Po [2] JAVANESE PADA TIRTA TUMETES..JAVANESE PADA ISEN-ISEN
+ {0xA9E0, 0xA9E4, prN}, // Lo [5] MYANMAR LETTER SHAN GHA..MYANMAR LETTER SHAN BHA
+ {0xA9E5, 0xA9E5, prN}, // Mn MYANMAR SIGN SHAN SAW
+ {0xA9E6, 0xA9E6, prN}, // Lm MYANMAR MODIFIER LETTER SHAN REDUPLICATION
+ {0xA9E7, 0xA9EF, prN}, // Lo [9] MYANMAR LETTER TAI LAING NYA..MYANMAR LETTER TAI LAING NNA
+ {0xA9F0, 0xA9F9, prN}, // Nd [10] MYANMAR TAI LAING DIGIT ZERO..MYANMAR TAI LAING DIGIT NINE
+ {0xA9FA, 0xA9FE, prN}, // Lo [5] MYANMAR LETTER TAI LAING LLA..MYANMAR LETTER TAI LAING BHA
+ {0xAA00, 0xAA28, prN}, // Lo [41] CHAM LETTER A..CHAM LETTER HA
+ {0xAA29, 0xAA2E, prN}, // Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE
+ {0xAA2F, 0xAA30, prN}, // Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI
+ {0xAA31, 0xAA32, prN}, // Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE
+ {0xAA33, 0xAA34, prN}, // Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA
+ {0xAA35, 0xAA36, prN}, // Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA
+ {0xAA40, 0xAA42, prN}, // Lo [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG
+ {0xAA43, 0xAA43, prN}, // Mn CHAM CONSONANT SIGN FINAL NG
+ {0xAA44, 0xAA4B, prN}, // Lo [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS
+ {0xAA4C, 0xAA4C, prN}, // Mn CHAM CONSONANT SIGN FINAL M
+ {0xAA4D, 0xAA4D, prN}, // Mc CHAM CONSONANT SIGN FINAL H
+ {0xAA50, 0xAA59, prN}, // Nd [10] CHAM DIGIT ZERO..CHAM DIGIT NINE
+ {0xAA5C, 0xAA5F, prN}, // Po [4] CHAM PUNCTUATION SPIRAL..CHAM PUNCTUATION TRIPLE DANDA
+ {0xAA60, 0xAA6F, prN}, // Lo [16] MYANMAR LETTER KHAMTI GA..MYANMAR LETTER KHAMTI FA
+ {0xAA70, 0xAA70, prN}, // Lm MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION
+ {0xAA71, 0xAA76, prN}, // Lo [6] MYANMAR LETTER KHAMTI XA..MYANMAR LOGOGRAM KHAMTI HM
+ {0xAA77, 0xAA79, prN}, // So [3] MYANMAR SYMBOL AITON EXCLAMATION..MYANMAR SYMBOL AITON TWO
+ {0xAA7A, 0xAA7A, prN}, // Lo MYANMAR LETTER AITON RA
+ {0xAA7B, 0xAA7B, prN}, // Mc MYANMAR SIGN PAO KAREN TONE
+ {0xAA7C, 0xAA7C, prN}, // Mn MYANMAR SIGN TAI LAING TONE-2
+ {0xAA7D, 0xAA7D, prN}, // Mc MYANMAR SIGN TAI LAING TONE-5
+ {0xAA7E, 0xAA7F, prN}, // Lo [2] MYANMAR LETTER SHWE PALAUNG CHA..MYANMAR LETTER SHWE PALAUNG SHA
+ {0xAA80, 0xAAAF, prN}, // Lo [48] TAI VIET LETTER LOW KO..TAI VIET LETTER HIGH O
+ {0xAAB0, 0xAAB0, prN}, // Mn TAI VIET MAI KANG
+ {0xAAB1, 0xAAB1, prN}, // Lo TAI VIET VOWEL AA
+ {0xAAB2, 0xAAB4, prN}, // Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U
+ {0xAAB5, 0xAAB6, prN}, // Lo [2] TAI VIET VOWEL E..TAI VIET VOWEL O
+ {0xAAB7, 0xAAB8, prN}, // Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA
+ {0xAAB9, 0xAABD, prN}, // Lo [5] TAI VIET VOWEL UEA..TAI VIET VOWEL AN
+ {0xAABE, 0xAABF, prN}, // Mn [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK
+ {0xAAC0, 0xAAC0, prN}, // Lo TAI VIET TONE MAI NUENG
+ {0xAAC1, 0xAAC1, prN}, // Mn TAI VIET TONE MAI THO
+ {0xAAC2, 0xAAC2, prN}, // Lo TAI VIET TONE MAI SONG
+ {0xAADB, 0xAADC, prN}, // Lo [2] TAI VIET SYMBOL KON..TAI VIET SYMBOL NUENG
+ {0xAADD, 0xAADD, prN}, // Lm TAI VIET SYMBOL SAM
+ {0xAADE, 0xAADF, prN}, // Po [2] TAI VIET SYMBOL HO HOI..TAI VIET SYMBOL KOI KOI
+ {0xAAE0, 0xAAEA, prN}, // Lo [11] MEETEI MAYEK LETTER E..MEETEI MAYEK LETTER SSA
+ {0xAAEB, 0xAAEB, prN}, // Mc MEETEI MAYEK VOWEL SIGN II
+ {0xAAEC, 0xAAED, prN}, // Mn [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI
+ {0xAAEE, 0xAAEF, prN}, // Mc [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU
+ {0xAAF0, 0xAAF1, prN}, // Po [2] MEETEI MAYEK CHEIKHAN..MEETEI MAYEK AHANG KHUDAM
+ {0xAAF2, 0xAAF2, prN}, // Lo MEETEI MAYEK ANJI
+ {0xAAF3, 0xAAF4, prN}, // Lm [2] MEETEI MAYEK SYLLABLE REPETITION MARK..MEETEI MAYEK WORD REPETITION MARK
+ {0xAAF5, 0xAAF5, prN}, // Mc MEETEI MAYEK VOWEL SIGN VISARGA
+ {0xAAF6, 0xAAF6, prN}, // Mn MEETEI MAYEK VIRAMA
+ {0xAB01, 0xAB06, prN}, // Lo [6] ETHIOPIC SYLLABLE TTHU..ETHIOPIC SYLLABLE TTHO
+ {0xAB09, 0xAB0E, prN}, // Lo [6] ETHIOPIC SYLLABLE DDHU..ETHIOPIC SYLLABLE DDHO
+ {0xAB11, 0xAB16, prN}, // Lo [6] ETHIOPIC SYLLABLE DZU..ETHIOPIC SYLLABLE DZO
+ {0xAB20, 0xAB26, prN}, // Lo [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE CCHHO
+ {0xAB28, 0xAB2E, prN}, // Lo [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO
+ {0xAB30, 0xAB5A, prN}, // Ll [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG
+ {0xAB5B, 0xAB5B, prN}, // Sk MODIFIER BREVE WITH INVERTED BREVE
+ {0xAB5C, 0xAB5F, prN}, // Lm [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK
+ {0xAB60, 0xAB68, prN}, // Ll [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE
+ {0xAB69, 0xAB69, prN}, // Lm MODIFIER LETTER SMALL TURNED W
+ {0xAB6A, 0xAB6B, prN}, // Sk [2] MODIFIER LETTER LEFT TACK..MODIFIER LETTER RIGHT TACK
+ {0xAB70, 0xABBF, prN}, // Ll [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA
+ {0xABC0, 0xABE2, prN}, // Lo [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM
+ {0xABE3, 0xABE4, prN}, // Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP
+ {0xABE5, 0xABE5, prN}, // Mn MEETEI MAYEK VOWEL SIGN ANAP
+ {0xABE6, 0xABE7, prN}, // Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP
+ {0xABE8, 0xABE8, prN}, // Mn MEETEI MAYEK VOWEL SIGN UNAP
+ {0xABE9, 0xABEA, prN}, // Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG
+ {0xABEB, 0xABEB, prN}, // Po MEETEI MAYEK CHEIKHEI
+ {0xABEC, 0xABEC, prN}, // Mc MEETEI MAYEK LUM IYEK
+ {0xABED, 0xABED, prN}, // Mn MEETEI MAYEK APUN IYEK
+ {0xABF0, 0xABF9, prN}, // Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DIGIT NINE
+ {0xAC00, 0xD7A3, prW}, // Lo [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH
+ {0xD7B0, 0xD7C6, prN}, // Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E
+ {0xD7CB, 0xD7FB, prN}, // Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH
+ {0xD800, 0xDB7F, prN}, // Cs [896] ..
+ {0xDB80, 0xDBFF, prN}, // Cs [128] ..
+ {0xDC00, 0xDFFF, prN}, // Cs [1024] ..
+ {0xE000, 0xF8FF, prA}, // Co [6400] ..
+ {0xF900, 0xFA6D, prW}, // Lo [366] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA6D
+ {0xFA6E, 0xFA6F, prW}, // Cn [2] ..
+ {0xFA70, 0xFAD9, prW}, // Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9
+ {0xFADA, 0xFAFF, prW}, // Cn [38] ..
+ {0xFB00, 0xFB06, prN}, // Ll [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST
+ {0xFB13, 0xFB17, prN}, // Ll [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH
+ {0xFB1D, 0xFB1D, prN}, // Lo HEBREW LETTER YOD WITH HIRIQ
+ {0xFB1E, 0xFB1E, prN}, // Mn HEBREW POINT JUDEO-SPANISH VARIKA
+ {0xFB1F, 0xFB28, prN}, // Lo [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV
+ {0xFB29, 0xFB29, prN}, // Sm HEBREW LETTER ALTERNATIVE PLUS SIGN
+ {0xFB2A, 0xFB36, prN}, // Lo [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH
+ {0xFB38, 0xFB3C, prN}, // Lo [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH
+ {0xFB3E, 0xFB3E, prN}, // Lo HEBREW LETTER MEM WITH DAGESH
+ {0xFB40, 0xFB41, prN}, // Lo [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH
+ {0xFB43, 0xFB44, prN}, // Lo [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH
+ {0xFB46, 0xFB4F, prN}, // Lo [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATURE ALEF LAMED
+ {0xFB50, 0xFBB1, prN}, // Lo [98] ARABIC LETTER ALEF WASLA ISOLATED FORM..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM
+ {0xFBB2, 0xFBC2, prN}, // Sk [17] ARABIC SYMBOL DOT ABOVE..ARABIC SYMBOL WASLA ABOVE
+ {0xFBD3, 0xFD3D, prN}, // Lo [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM
+ {0xFD3E, 0xFD3E, prN}, // Pe ORNATE LEFT PARENTHESIS
+ {0xFD3F, 0xFD3F, prN}, // Ps ORNATE RIGHT PARENTHESIS
+ {0xFD40, 0xFD4F, prN}, // So [16] ARABIC LIGATURE RAHIMAHU ALLAAH..ARABIC LIGATURE RAHIMAHUM ALLAAH
+ {0xFD50, 0xFD8F, prN}, // Lo [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM
+ {0xFD92, 0xFDC7, prN}, // Lo [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM
+ {0xFDCF, 0xFDCF, prN}, // So ARABIC LIGATURE SALAAMUHU ALAYNAA
+ {0xFDF0, 0xFDFB, prN}, // Lo [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU
+ {0xFDFC, 0xFDFC, prN}, // Sc RIAL SIGN
+ {0xFDFD, 0xFDFF, prN}, // So [3] ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM..ARABIC LIGATURE AZZA WA JALL
+ {0xFE00, 0xFE0F, prA}, // Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16
+ {0xFE10, 0xFE16, prW}, // Po [7] PRESENTATION FORM FOR VERTICAL COMMA..PRESENTATION FORM FOR VERTICAL QUESTION MARK
+ {0xFE17, 0xFE17, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET
+ {0xFE18, 0xFE18, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET
+ {0xFE19, 0xFE19, prW}, // Po PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS
+ {0xFE20, 0xFE2F, prN}, // Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF
+ {0xFE30, 0xFE30, prW}, // Po PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
+ {0xFE31, 0xFE32, prW}, // Pd [2] PRESENTATION FORM FOR VERTICAL EM DASH..PRESENTATION FORM FOR VERTICAL EN DASH
+ {0xFE33, 0xFE34, prW}, // Pc [2] PRESENTATION FORM FOR VERTICAL LOW LINE..PRESENTATION FORM FOR VERTICAL WAVY LOW LINE
+ {0xFE35, 0xFE35, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS
+ {0xFE36, 0xFE36, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS
+ {0xFE37, 0xFE37, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET
+ {0xFE38, 0xFE38, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET
+ {0xFE39, 0xFE39, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET
+ {0xFE3A, 0xFE3A, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET
+ {0xFE3B, 0xFE3B, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET
+ {0xFE3C, 0xFE3C, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET
+ {0xFE3D, 0xFE3D, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET
+ {0xFE3E, 0xFE3E, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET
+ {0xFE3F, 0xFE3F, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET
+ {0xFE40, 0xFE40, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET
+ {0xFE41, 0xFE41, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET
+ {0xFE42, 0xFE42, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET
+ {0xFE43, 0xFE43, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET
+ {0xFE44, 0xFE44, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET
+ {0xFE45, 0xFE46, prW}, // Po [2] SESAME DOT..WHITE SESAME DOT
+ {0xFE47, 0xFE47, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET
+ {0xFE48, 0xFE48, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET
+ {0xFE49, 0xFE4C, prW}, // Po [4] DASHED OVERLINE..DOUBLE WAVY OVERLINE
+ {0xFE4D, 0xFE4F, prW}, // Pc [3] DASHED LOW LINE..WAVY LOW LINE
+ {0xFE50, 0xFE52, prW}, // Po [3] SMALL COMMA..SMALL FULL STOP
+ {0xFE54, 0xFE57, prW}, // Po [4] SMALL SEMICOLON..SMALL EXCLAMATION MARK
+ {0xFE58, 0xFE58, prW}, // Pd SMALL EM DASH
+ {0xFE59, 0xFE59, prW}, // Ps SMALL LEFT PARENTHESIS
+ {0xFE5A, 0xFE5A, prW}, // Pe SMALL RIGHT PARENTHESIS
+ {0xFE5B, 0xFE5B, prW}, // Ps SMALL LEFT CURLY BRACKET
+ {0xFE5C, 0xFE5C, prW}, // Pe SMALL RIGHT CURLY BRACKET
+ {0xFE5D, 0xFE5D, prW}, // Ps SMALL LEFT TORTOISE SHELL BRACKET
+ {0xFE5E, 0xFE5E, prW}, // Pe SMALL RIGHT TORTOISE SHELL BRACKET
+ {0xFE5F, 0xFE61, prW}, // Po [3] SMALL NUMBER SIGN..SMALL ASTERISK
+ {0xFE62, 0xFE62, prW}, // Sm SMALL PLUS SIGN
+ {0xFE63, 0xFE63, prW}, // Pd SMALL HYPHEN-MINUS
+ {0xFE64, 0xFE66, prW}, // Sm [3] SMALL LESS-THAN SIGN..SMALL EQUALS SIGN
+ {0xFE68, 0xFE68, prW}, // Po SMALL REVERSE SOLIDUS
+ {0xFE69, 0xFE69, prW}, // Sc SMALL DOLLAR SIGN
+ {0xFE6A, 0xFE6B, prW}, // Po [2] SMALL PERCENT SIGN..SMALL COMMERCIAL AT
+ {0xFE70, 0xFE74, prN}, // Lo [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM
+ {0xFE76, 0xFEFC, prN}, // Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM
+ {0xFEFF, 0xFEFF, prN}, // Cf ZERO WIDTH NO-BREAK SPACE
+ {0xFF01, 0xFF03, prF}, // Po [3] FULLWIDTH EXCLAMATION MARK..FULLWIDTH NUMBER SIGN
+ {0xFF04, 0xFF04, prF}, // Sc FULLWIDTH DOLLAR SIGN
+ {0xFF05, 0xFF07, prF}, // Po [3] FULLWIDTH PERCENT SIGN..FULLWIDTH APOSTROPHE
+ {0xFF08, 0xFF08, prF}, // Ps FULLWIDTH LEFT PARENTHESIS
+ {0xFF09, 0xFF09, prF}, // Pe FULLWIDTH RIGHT PARENTHESIS
+ {0xFF0A, 0xFF0A, prF}, // Po FULLWIDTH ASTERISK
+ {0xFF0B, 0xFF0B, prF}, // Sm FULLWIDTH PLUS SIGN
+ {0xFF0C, 0xFF0C, prF}, // Po FULLWIDTH COMMA
+ {0xFF0D, 0xFF0D, prF}, // Pd FULLWIDTH HYPHEN-MINUS
+ {0xFF0E, 0xFF0F, prF}, // Po [2] FULLWIDTH FULL STOP..FULLWIDTH SOLIDUS
+ {0xFF10, 0xFF19, prF}, // Nd [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE
+ {0xFF1A, 0xFF1B, prF}, // Po [2] FULLWIDTH COLON..FULLWIDTH SEMICOLON
+ {0xFF1C, 0xFF1E, prF}, // Sm [3] FULLWIDTH LESS-THAN SIGN..FULLWIDTH GREATER-THAN SIGN
+ {0xFF1F, 0xFF20, prF}, // Po [2] FULLWIDTH QUESTION MARK..FULLWIDTH COMMERCIAL AT
+ {0xFF21, 0xFF3A, prF}, // Lu [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z
+ {0xFF3B, 0xFF3B, prF}, // Ps FULLWIDTH LEFT SQUARE BRACKET
+ {0xFF3C, 0xFF3C, prF}, // Po FULLWIDTH REVERSE SOLIDUS
+ {0xFF3D, 0xFF3D, prF}, // Pe FULLWIDTH RIGHT SQUARE BRACKET
+ {0xFF3E, 0xFF3E, prF}, // Sk FULLWIDTH CIRCUMFLEX ACCENT
+ {0xFF3F, 0xFF3F, prF}, // Pc FULLWIDTH LOW LINE
+ {0xFF40, 0xFF40, prF}, // Sk FULLWIDTH GRAVE ACCENT
+ {0xFF41, 0xFF5A, prF}, // Ll [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z
+ {0xFF5B, 0xFF5B, prF}, // Ps FULLWIDTH LEFT CURLY BRACKET
+ {0xFF5C, 0xFF5C, prF}, // Sm FULLWIDTH VERTICAL LINE
+ {0xFF5D, 0xFF5D, prF}, // Pe FULLWIDTH RIGHT CURLY BRACKET
+ {0xFF5E, 0xFF5E, prF}, // Sm FULLWIDTH TILDE
+ {0xFF5F, 0xFF5F, prF}, // Ps FULLWIDTH LEFT WHITE PARENTHESIS
+ {0xFF60, 0xFF60, prF}, // Pe FULLWIDTH RIGHT WHITE PARENTHESIS
+ {0xFF61, 0xFF61, prH}, // Po HALFWIDTH IDEOGRAPHIC FULL STOP
+ {0xFF62, 0xFF62, prH}, // Ps HALFWIDTH LEFT CORNER BRACKET
+ {0xFF63, 0xFF63, prH}, // Pe HALFWIDTH RIGHT CORNER BRACKET
+ {0xFF64, 0xFF65, prH}, // Po [2] HALFWIDTH IDEOGRAPHIC COMMA..HALFWIDTH KATAKANA MIDDLE DOT
+ {0xFF66, 0xFF6F, prH}, // Lo [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU
+ {0xFF70, 0xFF70, prH}, // Lm HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
+ {0xFF71, 0xFF9D, prH}, // Lo [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N
+ {0xFF9E, 0xFF9F, prH}, // Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
+ {0xFFA0, 0xFFBE, prH}, // Lo [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH
+ {0xFFC2, 0xFFC7, prH}, // Lo [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E
+ {0xFFCA, 0xFFCF, prH}, // Lo [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE
+ {0xFFD2, 0xFFD7, prH}, // Lo [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU
+ {0xFFDA, 0xFFDC, prH}, // Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I
+ {0xFFE0, 0xFFE1, prF}, // Sc [2] FULLWIDTH CENT SIGN..FULLWIDTH POUND SIGN
+ {0xFFE2, 0xFFE2, prF}, // Sm FULLWIDTH NOT SIGN
+ {0xFFE3, 0xFFE3, prF}, // Sk FULLWIDTH MACRON
+ {0xFFE4, 0xFFE4, prF}, // So FULLWIDTH BROKEN BAR
+ {0xFFE5, 0xFFE6, prF}, // Sc [2] FULLWIDTH YEN SIGN..FULLWIDTH WON SIGN
+ {0xFFE8, 0xFFE8, prH}, // So HALFWIDTH FORMS LIGHT VERTICAL
+ {0xFFE9, 0xFFEC, prH}, // Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS ARROW
+ {0xFFED, 0xFFEE, prH}, // So [2] HALFWIDTH BLACK SQUARE..HALFWIDTH WHITE CIRCLE
+ {0xFFF9, 0xFFFB, prN}, // Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR
+ {0xFFFC, 0xFFFC, prN}, // So OBJECT REPLACEMENT CHARACTER
+ {0xFFFD, 0xFFFD, prA}, // So REPLACEMENT CHARACTER
+ {0x10000, 0x1000B, prN}, // Lo [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE
+ {0x1000D, 0x10026, prN}, // Lo [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO
+ {0x10028, 0x1003A, prN}, // Lo [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO
+ {0x1003C, 0x1003D, prN}, // Lo [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE
+ {0x1003F, 0x1004D, prN}, // Lo [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO
+ {0x10050, 0x1005D, prN}, // Lo [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089
+ {0x10080, 0x100FA, prN}, // Lo [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305
+ {0x10100, 0x10102, prN}, // Po [3] AEGEAN WORD SEPARATOR LINE..AEGEAN CHECK MARK
+ {0x10107, 0x10133, prN}, // No [45] AEGEAN NUMBER ONE..AEGEAN NUMBER NINETY THOUSAND
+ {0x10137, 0x1013F, prN}, // So [9] AEGEAN WEIGHT BASE UNIT..AEGEAN MEASURE THIRD SUBUNIT
+ {0x10140, 0x10174, prN}, // Nl [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS
+ {0x10175, 0x10178, prN}, // No [4] GREEK ONE HALF SIGN..GREEK THREE QUARTERS SIGN
+ {0x10179, 0x10189, prN}, // So [17] GREEK YEAR SIGN..GREEK TRYBLION BASE SIGN
+ {0x1018A, 0x1018B, prN}, // No [2] GREEK ZERO SIGN..GREEK ONE QUARTER SIGN
+ {0x1018C, 0x1018E, prN}, // So [3] GREEK SINUSOID SIGN..NOMISMA SIGN
+ {0x10190, 0x1019C, prN}, // So [13] ROMAN SEXTANS SIGN..ASCIA SYMBOL
+ {0x101A0, 0x101A0, prN}, // So GREEK SYMBOL TAU RHO
+ {0x101D0, 0x101FC, prN}, // So [45] PHAISTOS DISC SIGN PEDESTRIAN..PHAISTOS DISC SIGN WAVY BAND
+ {0x101FD, 0x101FD, prN}, // Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE
+ {0x10280, 0x1029C, prN}, // Lo [29] LYCIAN LETTER A..LYCIAN LETTER X
+ {0x102A0, 0x102D0, prN}, // Lo [49] CARIAN LETTER A..CARIAN LETTER UUU3
+ {0x102E0, 0x102E0, prN}, // Mn COPTIC EPACT THOUSANDS MARK
+ {0x102E1, 0x102FB, prN}, // No [27] COPTIC EPACT DIGIT ONE..COPTIC EPACT NUMBER NINE HUNDRED
+ {0x10300, 0x1031F, prN}, // Lo [32] OLD ITALIC LETTER A..OLD ITALIC LETTER ESS
+ {0x10320, 0x10323, prN}, // No [4] OLD ITALIC NUMERAL ONE..OLD ITALIC NUMERAL FIFTY
+ {0x1032D, 0x1032F, prN}, // Lo [3] OLD ITALIC LETTER YE..OLD ITALIC LETTER SOUTHERN TSE
+ {0x10330, 0x10340, prN}, // Lo [17] GOTHIC LETTER AHSA..GOTHIC LETTER PAIRTHRA
+ {0x10341, 0x10341, prN}, // Nl GOTHIC LETTER NINETY
+ {0x10342, 0x10349, prN}, // Lo [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL
+ {0x1034A, 0x1034A, prN}, // Nl GOTHIC LETTER NINE HUNDRED
+ {0x10350, 0x10375, prN}, // Lo [38] OLD PERMIC LETTER AN..OLD PERMIC LETTER IA
+ {0x10376, 0x1037A, prN}, // Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII
+ {0x10380, 0x1039D, prN}, // Lo [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU
+ {0x1039F, 0x1039F, prN}, // Po UGARITIC WORD DIVIDER
+ {0x103A0, 0x103C3, prN}, // Lo [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA
+ {0x103C8, 0x103CF, prN}, // Lo [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH
+ {0x103D0, 0x103D0, prN}, // Po OLD PERSIAN WORD DIVIDER
+ {0x103D1, 0x103D5, prN}, // Nl [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED
+ {0x10400, 0x1044F, prN}, // L& [80] DESERET CAPITAL LETTER LONG I..DESERET SMALL LETTER EW
+ {0x10450, 0x1047F, prN}, // Lo [48] SHAVIAN LETTER PEEP..SHAVIAN LETTER YEW
+ {0x10480, 0x1049D, prN}, // Lo [30] OSMANYA LETTER ALEF..OSMANYA LETTER OO
+ {0x104A0, 0x104A9, prN}, // Nd [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE
+ {0x104B0, 0x104D3, prN}, // Lu [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA
+ {0x104D8, 0x104FB, prN}, // Ll [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA
+ {0x10500, 0x10527, prN}, // Lo [40] ELBASAN LETTER A..ELBASAN LETTER KHE
+ {0x10530, 0x10563, prN}, // Lo [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW
+ {0x1056F, 0x1056F, prN}, // Po CAUCASIAN ALBANIAN CITATION MARK
+ {0x10570, 0x1057A, prN}, // Lu [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA
+ {0x1057C, 0x1058A, prN}, // Lu [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE
+ {0x1058C, 0x10592, prN}, // Lu [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE
+ {0x10594, 0x10595, prN}, // Lu [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE
+ {0x10597, 0x105A1, prN}, // Ll [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA
+ {0x105A3, 0x105B1, prN}, // Ll [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE
+ {0x105B3, 0x105B9, prN}, // Ll [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE
+ {0x105BB, 0x105BC, prN}, // Ll [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE
+ {0x10600, 0x10736, prN}, // Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664
+ {0x10740, 0x10755, prN}, // Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE
+ {0x10760, 0x10767, prN}, // Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807
+ {0x10780, 0x10785, prN}, // Lm [6] MODIFIER LETTER SMALL CAPITAL AA..MODIFIER LETTER SMALL B WITH HOOK
+ {0x10787, 0x107B0, prN}, // Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK
+ {0x107B2, 0x107BA, prN}, // Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL
+ {0x10800, 0x10805, prN}, // Lo [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA
+ {0x10808, 0x10808, prN}, // Lo CYPRIOT SYLLABLE JO
+ {0x1080A, 0x10835, prN}, // Lo [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO
+ {0x10837, 0x10838, prN}, // Lo [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE
+ {0x1083C, 0x1083C, prN}, // Lo CYPRIOT SYLLABLE ZA
+ {0x1083F, 0x1083F, prN}, // Lo CYPRIOT SYLLABLE ZO
+ {0x10840, 0x10855, prN}, // Lo [22] IMPERIAL ARAMAIC LETTER ALEPH..IMPERIAL ARAMAIC LETTER TAW
+ {0x10857, 0x10857, prN}, // Po IMPERIAL ARAMAIC SECTION SIGN
+ {0x10858, 0x1085F, prN}, // No [8] IMPERIAL ARAMAIC NUMBER ONE..IMPERIAL ARAMAIC NUMBER TEN THOUSAND
+ {0x10860, 0x10876, prN}, // Lo [23] PALMYRENE LETTER ALEPH..PALMYRENE LETTER TAW
+ {0x10877, 0x10878, prN}, // So [2] PALMYRENE LEFT-POINTING FLEURON..PALMYRENE RIGHT-POINTING FLEURON
+ {0x10879, 0x1087F, prN}, // No [7] PALMYRENE NUMBER ONE..PALMYRENE NUMBER TWENTY
+ {0x10880, 0x1089E, prN}, // Lo [31] NABATAEAN LETTER FINAL ALEPH..NABATAEAN LETTER TAW
+ {0x108A7, 0x108AF, prN}, // No [9] NABATAEAN NUMBER ONE..NABATAEAN NUMBER ONE HUNDRED
+ {0x108E0, 0x108F2, prN}, // Lo [19] HATRAN LETTER ALEPH..HATRAN LETTER QOPH
+ {0x108F4, 0x108F5, prN}, // Lo [2] HATRAN LETTER SHIN..HATRAN LETTER TAW
+ {0x108FB, 0x108FF, prN}, // No [5] HATRAN NUMBER ONE..HATRAN NUMBER ONE HUNDRED
+ {0x10900, 0x10915, prN}, // Lo [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU
+ {0x10916, 0x1091B, prN}, // No [6] PHOENICIAN NUMBER ONE..PHOENICIAN NUMBER THREE
+ {0x1091F, 0x1091F, prN}, // Po PHOENICIAN WORD SEPARATOR
+ {0x10920, 0x10939, prN}, // Lo [26] LYDIAN LETTER A..LYDIAN LETTER C
+ {0x1093F, 0x1093F, prN}, // Po LYDIAN TRIANGULAR MARK
+ {0x10980, 0x1099F, prN}, // Lo [32] MEROITIC HIEROGLYPHIC LETTER A..MEROITIC HIEROGLYPHIC SYMBOL VIDJ-2
+ {0x109A0, 0x109B7, prN}, // Lo [24] MEROITIC CURSIVE LETTER A..MEROITIC CURSIVE LETTER DA
+ {0x109BC, 0x109BD, prN}, // No [2] MEROITIC CURSIVE FRACTION ELEVEN TWELFTHS..MEROITIC CURSIVE FRACTION ONE HALF
+ {0x109BE, 0x109BF, prN}, // Lo [2] MEROITIC CURSIVE LOGOGRAM RMT..MEROITIC CURSIVE LOGOGRAM IMN
+ {0x109C0, 0x109CF, prN}, // No [16] MEROITIC CURSIVE NUMBER ONE..MEROITIC CURSIVE NUMBER SEVENTY
+ {0x109D2, 0x109FF, prN}, // No [46] MEROITIC CURSIVE NUMBER ONE HUNDRED..MEROITIC CURSIVE FRACTION TEN TWELFTHS
+ {0x10A00, 0x10A00, prN}, // Lo KHAROSHTHI LETTER A
+ {0x10A01, 0x10A03, prN}, // Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R
+ {0x10A05, 0x10A06, prN}, // Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O
+ {0x10A0C, 0x10A0F, prN}, // Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA
+ {0x10A10, 0x10A13, prN}, // Lo [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA
+ {0x10A15, 0x10A17, prN}, // Lo [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA
+ {0x10A19, 0x10A35, prN}, // Lo [29] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER VHA
+ {0x10A38, 0x10A3A, prN}, // Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW
+ {0x10A3F, 0x10A3F, prN}, // Mn KHAROSHTHI VIRAMA
+ {0x10A40, 0x10A48, prN}, // No [9] KHAROSHTHI DIGIT ONE..KHAROSHTHI FRACTION ONE HALF
+ {0x10A50, 0x10A58, prN}, // Po [9] KHAROSHTHI PUNCTUATION DOT..KHAROSHTHI PUNCTUATION LINES
+ {0x10A60, 0x10A7C, prN}, // Lo [29] OLD SOUTH ARABIAN LETTER HE..OLD SOUTH ARABIAN LETTER THETH
+ {0x10A7D, 0x10A7E, prN}, // No [2] OLD SOUTH ARABIAN NUMBER ONE..OLD SOUTH ARABIAN NUMBER FIFTY
+ {0x10A7F, 0x10A7F, prN}, // Po OLD SOUTH ARABIAN NUMERIC INDICATOR
+ {0x10A80, 0x10A9C, prN}, // Lo [29] OLD NORTH ARABIAN LETTER HEH..OLD NORTH ARABIAN LETTER ZAH
+ {0x10A9D, 0x10A9F, prN}, // No [3] OLD NORTH ARABIAN NUMBER ONE..OLD NORTH ARABIAN NUMBER TWENTY
+ {0x10AC0, 0x10AC7, prN}, // Lo [8] MANICHAEAN LETTER ALEPH..MANICHAEAN LETTER WAW
+ {0x10AC8, 0x10AC8, prN}, // So MANICHAEAN SIGN UD
+ {0x10AC9, 0x10AE4, prN}, // Lo [28] MANICHAEAN LETTER ZAYIN..MANICHAEAN LETTER TAW
+ {0x10AE5, 0x10AE6, prN}, // Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW
+ {0x10AEB, 0x10AEF, prN}, // No [5] MANICHAEAN NUMBER ONE..MANICHAEAN NUMBER ONE HUNDRED
+ {0x10AF0, 0x10AF6, prN}, // Po [7] MANICHAEAN PUNCTUATION STAR..MANICHAEAN PUNCTUATION LINE FILLER
+ {0x10B00, 0x10B35, prN}, // Lo [54] AVESTAN LETTER A..AVESTAN LETTER HE
+ {0x10B39, 0x10B3F, prN}, // Po [7] AVESTAN ABBREVIATION MARK..LARGE ONE RING OVER TWO RINGS PUNCTUATION
+ {0x10B40, 0x10B55, prN}, // Lo [22] INSCRIPTIONAL PARTHIAN LETTER ALEPH..INSCRIPTIONAL PARTHIAN LETTER TAW
+ {0x10B58, 0x10B5F, prN}, // No [8] INSCRIPTIONAL PARTHIAN NUMBER ONE..INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND
+ {0x10B60, 0x10B72, prN}, // Lo [19] INSCRIPTIONAL PAHLAVI LETTER ALEPH..INSCRIPTIONAL PAHLAVI LETTER TAW
+ {0x10B78, 0x10B7F, prN}, // No [8] INSCRIPTIONAL PAHLAVI NUMBER ONE..INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND
+ {0x10B80, 0x10B91, prN}, // Lo [18] PSALTER PAHLAVI LETTER ALEPH..PSALTER PAHLAVI LETTER TAW
+ {0x10B99, 0x10B9C, prN}, // Po [4] PSALTER PAHLAVI SECTION MARK..PSALTER PAHLAVI FOUR DOTS WITH DOT
+ {0x10BA9, 0x10BAF, prN}, // No [7] PSALTER PAHLAVI NUMBER ONE..PSALTER PAHLAVI NUMBER ONE HUNDRED
+ {0x10C00, 0x10C48, prN}, // Lo [73] OLD TURKIC LETTER ORKHON A..OLD TURKIC LETTER ORKHON BASH
+ {0x10C80, 0x10CB2, prN}, // Lu [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US
+ {0x10CC0, 0x10CF2, prN}, // Ll [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US
+ {0x10CFA, 0x10CFF, prN}, // No [6] OLD HUNGARIAN NUMBER ONE..OLD HUNGARIAN NUMBER ONE THOUSAND
+ {0x10D00, 0x10D23, prN}, // Lo [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA
+ {0x10D24, 0x10D27, prN}, // Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI
+ {0x10D30, 0x10D39, prN}, // Nd [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE
+ {0x10E60, 0x10E7E, prN}, // No [31] RUMI DIGIT ONE..RUMI FRACTION TWO THIRDS
+ {0x10E80, 0x10EA9, prN}, // Lo [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET
+ {0x10EAB, 0x10EAC, prN}, // Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK
+ {0x10EAD, 0x10EAD, prN}, // Pd YEZIDI HYPHENATION MARK
+ {0x10EB0, 0x10EB1, prN}, // Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE
+ {0x10EFD, 0x10EFF, prN}, // Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA
+ {0x10F00, 0x10F1C, prN}, // Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL
+ {0x10F1D, 0x10F26, prN}, // No [10] OLD SOGDIAN NUMBER ONE..OLD SOGDIAN FRACTION ONE HALF
+ {0x10F27, 0x10F27, prN}, // Lo OLD SOGDIAN LIGATURE AYIN-DALETH
+ {0x10F30, 0x10F45, prN}, // Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN
+ {0x10F46, 0x10F50, prN}, // Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW
+ {0x10F51, 0x10F54, prN}, // No [4] SOGDIAN NUMBER ONE..SOGDIAN NUMBER ONE HUNDRED
+ {0x10F55, 0x10F59, prN}, // Po [5] SOGDIAN PUNCTUATION TWO VERTICAL BARS..SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT
+ {0x10F70, 0x10F81, prN}, // Lo [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH
+ {0x10F82, 0x10F85, prN}, // Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW
+ {0x10F86, 0x10F89, prN}, // Po [4] OLD UYGHUR PUNCTUATION BAR..OLD UYGHUR PUNCTUATION FOUR DOTS
+ {0x10FB0, 0x10FC4, prN}, // Lo [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW
+ {0x10FC5, 0x10FCB, prN}, // No [7] CHORASMIAN NUMBER ONE..CHORASMIAN NUMBER ONE HUNDRED
+ {0x10FE0, 0x10FF6, prN}, // Lo [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH
+ {0x11000, 0x11000, prN}, // Mc BRAHMI SIGN CANDRABINDU
+ {0x11001, 0x11001, prN}, // Mn BRAHMI SIGN ANUSVARA
+ {0x11002, 0x11002, prN}, // Mc BRAHMI SIGN VISARGA
+ {0x11003, 0x11037, prN}, // Lo [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA
+ {0x11038, 0x11046, prN}, // Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA
+ {0x11047, 0x1104D, prN}, // Po [7] BRAHMI DANDA..BRAHMI PUNCTUATION LOTUS
+ {0x11052, 0x11065, prN}, // No [20] BRAHMI NUMBER ONE..BRAHMI NUMBER ONE THOUSAND
+ {0x11066, 0x1106F, prN}, // Nd [10] BRAHMI DIGIT ZERO..BRAHMI DIGIT NINE
+ {0x11070, 0x11070, prN}, // Mn BRAHMI SIGN OLD TAMIL VIRAMA
+ {0x11071, 0x11072, prN}, // Lo [2] BRAHMI LETTER OLD TAMIL SHORT E..BRAHMI LETTER OLD TAMIL SHORT O
+ {0x11073, 0x11074, prN}, // Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O
+ {0x11075, 0x11075, prN}, // Lo BRAHMI LETTER OLD TAMIL LLA
+ {0x1107F, 0x1107F, prN}, // Mn BRAHMI NUMBER JOINER
+ {0x11080, 0x11081, prN}, // Mn [2] KAITHI SIGN CANDRABINDU..KAITHI SIGN ANUSVARA
+ {0x11082, 0x11082, prN}, // Mc KAITHI SIGN VISARGA
+ {0x11083, 0x110AF, prN}, // Lo [45] KAITHI LETTER A..KAITHI LETTER HA
+ {0x110B0, 0x110B2, prN}, // Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II
+ {0x110B3, 0x110B6, prN}, // Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI
+ {0x110B7, 0x110B8, prN}, // Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU
+ {0x110B9, 0x110BA, prN}, // Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA
+ {0x110BB, 0x110BC, prN}, // Po [2] KAITHI ABBREVIATION SIGN..KAITHI ENUMERATION SIGN
+ {0x110BD, 0x110BD, prN}, // Cf KAITHI NUMBER SIGN
+ {0x110BE, 0x110C1, prN}, // Po [4] KAITHI SECTION MARK..KAITHI DOUBLE DANDA
+ {0x110C2, 0x110C2, prN}, // Mn KAITHI VOWEL SIGN VOCALIC R
+ {0x110CD, 0x110CD, prN}, // Cf KAITHI NUMBER SIGN ABOVE
+ {0x110D0, 0x110E8, prN}, // Lo [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE
+ {0x110F0, 0x110F9, prN}, // Nd [10] SORA SOMPENG DIGIT ZERO..SORA SOMPENG DIGIT NINE
+ {0x11100, 0x11102, prN}, // Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA
+ {0x11103, 0x11126, prN}, // Lo [36] CHAKMA LETTER AA..CHAKMA LETTER HAA
+ {0x11127, 0x1112B, prN}, // Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU
+ {0x1112C, 0x1112C, prN}, // Mc CHAKMA VOWEL SIGN E
+ {0x1112D, 0x11134, prN}, // Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA
+ {0x11136, 0x1113F, prN}, // Nd [10] CHAKMA DIGIT ZERO..CHAKMA DIGIT NINE
+ {0x11140, 0x11143, prN}, // Po [4] CHAKMA SECTION MARK..CHAKMA QUESTION MARK
+ {0x11144, 0x11144, prN}, // Lo CHAKMA LETTER LHAA
+ {0x11145, 0x11146, prN}, // Mc [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI
+ {0x11147, 0x11147, prN}, // Lo CHAKMA LETTER VAA
+ {0x11150, 0x11172, prN}, // Lo [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA
+ {0x11173, 0x11173, prN}, // Mn MAHAJANI SIGN NUKTA
+ {0x11174, 0x11175, prN}, // Po [2] MAHAJANI ABBREVIATION SIGN..MAHAJANI SECTION MARK
+ {0x11176, 0x11176, prN}, // Lo MAHAJANI LIGATURE SHRI
+ {0x11180, 0x11181, prN}, // Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA
+ {0x11182, 0x11182, prN}, // Mc SHARADA SIGN VISARGA
+ {0x11183, 0x111B2, prN}, // Lo [48] SHARADA LETTER A..SHARADA LETTER HA
+ {0x111B3, 0x111B5, prN}, // Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II
+ {0x111B6, 0x111BE, prN}, // Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O
+ {0x111BF, 0x111C0, prN}, // Mc [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA
+ {0x111C1, 0x111C4, prN}, // Lo [4] SHARADA SIGN AVAGRAHA..SHARADA OM
+ {0x111C5, 0x111C8, prN}, // Po [4] SHARADA DANDA..SHARADA SEPARATOR
+ {0x111C9, 0x111CC, prN}, // Mn [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK
+ {0x111CD, 0x111CD, prN}, // Po SHARADA SUTRA MARK
+ {0x111CE, 0x111CE, prN}, // Mc SHARADA VOWEL SIGN PRISHTHAMATRA E
+ {0x111CF, 0x111CF, prN}, // Mn SHARADA SIGN INVERTED CANDRABINDU
+ {0x111D0, 0x111D9, prN}, // Nd [10] SHARADA DIGIT ZERO..SHARADA DIGIT NINE
+ {0x111DA, 0x111DA, prN}, // Lo SHARADA EKAM
+ {0x111DB, 0x111DB, prN}, // Po SHARADA SIGN SIDDHAM
+ {0x111DC, 0x111DC, prN}, // Lo SHARADA HEADSTROKE
+ {0x111DD, 0x111DF, prN}, // Po [3] SHARADA CONTINUATION SIGN..SHARADA SECTION MARK-2
+ {0x111E1, 0x111F4, prN}, // No [20] SINHALA ARCHAIC DIGIT ONE..SINHALA ARCHAIC NUMBER ONE THOUSAND
+ {0x11200, 0x11211, prN}, // Lo [18] KHOJKI LETTER A..KHOJKI LETTER JJA
+ {0x11213, 0x1122B, prN}, // Lo [25] KHOJKI LETTER NYA..KHOJKI LETTER LLA
+ {0x1122C, 0x1122E, prN}, // Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II
+ {0x1122F, 0x11231, prN}, // Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI
+ {0x11232, 0x11233, prN}, // Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU
+ {0x11234, 0x11234, prN}, // Mn KHOJKI SIGN ANUSVARA
+ {0x11235, 0x11235, prN}, // Mc KHOJKI SIGN VIRAMA
+ {0x11236, 0x11237, prN}, // Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA
+ {0x11238, 0x1123D, prN}, // Po [6] KHOJKI DANDA..KHOJKI ABBREVIATION SIGN
+ {0x1123E, 0x1123E, prN}, // Mn KHOJKI SIGN SUKUN
+ {0x1123F, 0x11240, prN}, // Lo [2] KHOJKI LETTER QA..KHOJKI LETTER SHORT I
+ {0x11241, 0x11241, prN}, // Mn KHOJKI VOWEL SIGN VOCALIC R
+ {0x11280, 0x11286, prN}, // Lo [7] MULTANI LETTER A..MULTANI LETTER GA
+ {0x11288, 0x11288, prN}, // Lo MULTANI LETTER GHA
+ {0x1128A, 0x1128D, prN}, // Lo [4] MULTANI LETTER CA..MULTANI LETTER JJA
+ {0x1128F, 0x1129D, prN}, // Lo [15] MULTANI LETTER NYA..MULTANI LETTER BA
+ {0x1129F, 0x112A8, prN}, // Lo [10] MULTANI LETTER BHA..MULTANI LETTER RHA
+ {0x112A9, 0x112A9, prN}, // Po MULTANI SECTION MARK
+ {0x112B0, 0x112DE, prN}, // Lo [47] KHUDAWADI LETTER A..KHUDAWADI LETTER HA
+ {0x112DF, 0x112DF, prN}, // Mn KHUDAWADI SIGN ANUSVARA
+ {0x112E0, 0x112E2, prN}, // Mc [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II
+ {0x112E3, 0x112EA, prN}, // Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA
+ {0x112F0, 0x112F9, prN}, // Nd [10] KHUDAWADI DIGIT ZERO..KHUDAWADI DIGIT NINE
+ {0x11300, 0x11301, prN}, // Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU
+ {0x11302, 0x11303, prN}, // Mc [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA
+ {0x11305, 0x1130C, prN}, // Lo [8] GRANTHA LETTER A..GRANTHA LETTER VOCALIC L
+ {0x1130F, 0x11310, prN}, // Lo [2] GRANTHA LETTER EE..GRANTHA LETTER AI
+ {0x11313, 0x11328, prN}, // Lo [22] GRANTHA LETTER OO..GRANTHA LETTER NA
+ {0x1132A, 0x11330, prN}, // Lo [7] GRANTHA LETTER PA..GRANTHA LETTER RA
+ {0x11332, 0x11333, prN}, // Lo [2] GRANTHA LETTER LA..GRANTHA LETTER LLA
+ {0x11335, 0x11339, prN}, // Lo [5] GRANTHA LETTER VA..GRANTHA LETTER HA
+ {0x1133B, 0x1133C, prN}, // Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA
+ {0x1133D, 0x1133D, prN}, // Lo GRANTHA SIGN AVAGRAHA
+ {0x1133E, 0x1133F, prN}, // Mc [2] GRANTHA VOWEL SIGN AA..GRANTHA VOWEL SIGN I
+ {0x11340, 0x11340, prN}, // Mn GRANTHA VOWEL SIGN II
+ {0x11341, 0x11344, prN}, // Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR
+ {0x11347, 0x11348, prN}, // Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI
+ {0x1134B, 0x1134D, prN}, // Mc [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA
+ {0x11350, 0x11350, prN}, // Lo GRANTHA OM
+ {0x11357, 0x11357, prN}, // Mc GRANTHA AU LENGTH MARK
+ {0x1135D, 0x11361, prN}, // Lo [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL
+ {0x11362, 0x11363, prN}, // Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL
+ {0x11366, 0x1136C, prN}, // Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX
+ {0x11370, 0x11374, prN}, // Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA
+ {0x11400, 0x11434, prN}, // Lo [53] NEWA LETTER A..NEWA LETTER HA
+ {0x11435, 0x11437, prN}, // Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II
+ {0x11438, 0x1143F, prN}, // Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI
+ {0x11440, 0x11441, prN}, // Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU
+ {0x11442, 0x11444, prN}, // Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA
+ {0x11445, 0x11445, prN}, // Mc NEWA SIGN VISARGA
+ {0x11446, 0x11446, prN}, // Mn NEWA SIGN NUKTA
+ {0x11447, 0x1144A, prN}, // Lo [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI
+ {0x1144B, 0x1144F, prN}, // Po [5] NEWA DANDA..NEWA ABBREVIATION SIGN
+ {0x11450, 0x11459, prN}, // Nd [10] NEWA DIGIT ZERO..NEWA DIGIT NINE
+ {0x1145A, 0x1145B, prN}, // Po [2] NEWA DOUBLE COMMA..NEWA PLACEHOLDER MARK
+ {0x1145D, 0x1145D, prN}, // Po NEWA INSERTION SIGN
+ {0x1145E, 0x1145E, prN}, // Mn NEWA SANDHI MARK
+ {0x1145F, 0x11461, prN}, // Lo [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA
+ {0x11480, 0x114AF, prN}, // Lo [48] TIRHUTA ANJI..TIRHUTA LETTER HA
+ {0x114B0, 0x114B2, prN}, // Mc [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II
+ {0x114B3, 0x114B8, prN}, // Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL
+ {0x114B9, 0x114B9, prN}, // Mc TIRHUTA VOWEL SIGN E
+ {0x114BA, 0x114BA, prN}, // Mn TIRHUTA VOWEL SIGN SHORT E
+ {0x114BB, 0x114BE, prN}, // Mc [4] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN AU
+ {0x114BF, 0x114C0, prN}, // Mn [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA
+ {0x114C1, 0x114C1, prN}, // Mc TIRHUTA SIGN VISARGA
+ {0x114C2, 0x114C3, prN}, // Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA
+ {0x114C4, 0x114C5, prN}, // Lo [2] TIRHUTA SIGN AVAGRAHA..TIRHUTA GVANG
+ {0x114C6, 0x114C6, prN}, // Po TIRHUTA ABBREVIATION SIGN
+ {0x114C7, 0x114C7, prN}, // Lo TIRHUTA OM
+ {0x114D0, 0x114D9, prN}, // Nd [10] TIRHUTA DIGIT ZERO..TIRHUTA DIGIT NINE
+ {0x11580, 0x115AE, prN}, // Lo [47] SIDDHAM LETTER A..SIDDHAM LETTER HA
+ {0x115AF, 0x115B1, prN}, // Mc [3] SIDDHAM VOWEL SIGN AA..SIDDHAM VOWEL SIGN II
+ {0x115B2, 0x115B5, prN}, // Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR
+ {0x115B8, 0x115BB, prN}, // Mc [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU
+ {0x115BC, 0x115BD, prN}, // Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA
+ {0x115BE, 0x115BE, prN}, // Mc SIDDHAM SIGN VISARGA
+ {0x115BF, 0x115C0, prN}, // Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA
+ {0x115C1, 0x115D7, prN}, // Po [23] SIDDHAM SIGN SIDDHAM..SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES
+ {0x115D8, 0x115DB, prN}, // Lo [4] SIDDHAM LETTER THREE-CIRCLE ALTERNATE I..SIDDHAM LETTER ALTERNATE U
+ {0x115DC, 0x115DD, prN}, // Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU
+ {0x11600, 0x1162F, prN}, // Lo [48] MODI LETTER A..MODI LETTER LLA
+ {0x11630, 0x11632, prN}, // Mc [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II
+ {0x11633, 0x1163A, prN}, // Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI
+ {0x1163B, 0x1163C, prN}, // Mc [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU
+ {0x1163D, 0x1163D, prN}, // Mn MODI SIGN ANUSVARA
+ {0x1163E, 0x1163E, prN}, // Mc MODI SIGN VISARGA
+ {0x1163F, 0x11640, prN}, // Mn [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA
+ {0x11641, 0x11643, prN}, // Po [3] MODI DANDA..MODI ABBREVIATION SIGN
+ {0x11644, 0x11644, prN}, // Lo MODI SIGN HUVA
+ {0x11650, 0x11659, prN}, // Nd [10] MODI DIGIT ZERO..MODI DIGIT NINE
+ {0x11660, 0x1166C, prN}, // Po [13] MONGOLIAN BIRGA WITH ORNAMENT..MONGOLIAN TURNED SWIRL BIRGA WITH DOUBLE ORNAMENT
+ {0x11680, 0x116AA, prN}, // Lo [43] TAKRI LETTER A..TAKRI LETTER RRA
+ {0x116AB, 0x116AB, prN}, // Mn TAKRI SIGN ANUSVARA
+ {0x116AC, 0x116AC, prN}, // Mc TAKRI SIGN VISARGA
+ {0x116AD, 0x116AD, prN}, // Mn TAKRI VOWEL SIGN AA
+ {0x116AE, 0x116AF, prN}, // Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II
+ {0x116B0, 0x116B5, prN}, // Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU
+ {0x116B6, 0x116B6, prN}, // Mc TAKRI SIGN VIRAMA
+ {0x116B7, 0x116B7, prN}, // Mn TAKRI SIGN NUKTA
+ {0x116B8, 0x116B8, prN}, // Lo TAKRI LETTER ARCHAIC KHA
+ {0x116B9, 0x116B9, prN}, // Po TAKRI ABBREVIATION SIGN
+ {0x116C0, 0x116C9, prN}, // Nd [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE
+ {0x11700, 0x1171A, prN}, // Lo [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA
+ {0x1171D, 0x1171F, prN}, // Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA
+ {0x11720, 0x11721, prN}, // Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA
+ {0x11722, 0x11725, prN}, // Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU
+ {0x11726, 0x11726, prN}, // Mc AHOM VOWEL SIGN E
+ {0x11727, 0x1172B, prN}, // Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER
+ {0x11730, 0x11739, prN}, // Nd [10] AHOM DIGIT ZERO..AHOM DIGIT NINE
+ {0x1173A, 0x1173B, prN}, // No [2] AHOM NUMBER TEN..AHOM NUMBER TWENTY
+ {0x1173C, 0x1173E, prN}, // Po [3] AHOM SIGN SMALL SECTION..AHOM SIGN RULAI
+ {0x1173F, 0x1173F, prN}, // So AHOM SYMBOL VI
+ {0x11740, 0x11746, prN}, // Lo [7] AHOM LETTER CA..AHOM LETTER LLA
+ {0x11800, 0x1182B, prN}, // Lo [44] DOGRA LETTER A..DOGRA LETTER RRA
+ {0x1182C, 0x1182E, prN}, // Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II
+ {0x1182F, 0x11837, prN}, // Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA
+ {0x11838, 0x11838, prN}, // Mc DOGRA SIGN VISARGA
+ {0x11839, 0x1183A, prN}, // Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA
+ {0x1183B, 0x1183B, prN}, // Po DOGRA ABBREVIATION SIGN
+ {0x118A0, 0x118DF, prN}, // L& [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO
+ {0x118E0, 0x118E9, prN}, // Nd [10] WARANG CITI DIGIT ZERO..WARANG CITI DIGIT NINE
+ {0x118EA, 0x118F2, prN}, // No [9] WARANG CITI NUMBER TEN..WARANG CITI NUMBER NINETY
+ {0x118FF, 0x118FF, prN}, // Lo WARANG CITI OM
+ {0x11900, 0x11906, prN}, // Lo [7] DIVES AKURU LETTER A..DIVES AKURU LETTER E
+ {0x11909, 0x11909, prN}, // Lo DIVES AKURU LETTER O
+ {0x1190C, 0x11913, prN}, // Lo [8] DIVES AKURU LETTER KA..DIVES AKURU LETTER JA
+ {0x11915, 0x11916, prN}, // Lo [2] DIVES AKURU LETTER NYA..DIVES AKURU LETTER TTA
+ {0x11918, 0x1192F, prN}, // Lo [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA
+ {0x11930, 0x11935, prN}, // Mc [6] DIVES AKURU VOWEL SIGN AA..DIVES AKURU VOWEL SIGN E
+ {0x11937, 0x11938, prN}, // Mc [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O
+ {0x1193B, 0x1193C, prN}, // Mn [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU
+ {0x1193D, 0x1193D, prN}, // Mc DIVES AKURU SIGN HALANTA
+ {0x1193E, 0x1193E, prN}, // Mn DIVES AKURU VIRAMA
+ {0x1193F, 0x1193F, prN}, // Lo DIVES AKURU PREFIXED NASAL SIGN
+ {0x11940, 0x11940, prN}, // Mc DIVES AKURU MEDIAL YA
+ {0x11941, 0x11941, prN}, // Lo DIVES AKURU INITIAL RA
+ {0x11942, 0x11942, prN}, // Mc DIVES AKURU MEDIAL RA
+ {0x11943, 0x11943, prN}, // Mn DIVES AKURU SIGN NUKTA
+ {0x11944, 0x11946, prN}, // Po [3] DIVES AKURU DOUBLE DANDA..DIVES AKURU END OF TEXT MARK
+ {0x11950, 0x11959, prN}, // Nd [10] DIVES AKURU DIGIT ZERO..DIVES AKURU DIGIT NINE
+ {0x119A0, 0x119A7, prN}, // Lo [8] NANDINAGARI LETTER A..NANDINAGARI LETTER VOCALIC RR
+ {0x119AA, 0x119D0, prN}, // Lo [39] NANDINAGARI LETTER E..NANDINAGARI LETTER RRA
+ {0x119D1, 0x119D3, prN}, // Mc [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II
+ {0x119D4, 0x119D7, prN}, // Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR
+ {0x119DA, 0x119DB, prN}, // Mn [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI
+ {0x119DC, 0x119DF, prN}, // Mc [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA
+ {0x119E0, 0x119E0, prN}, // Mn NANDINAGARI SIGN VIRAMA
+ {0x119E1, 0x119E1, prN}, // Lo NANDINAGARI SIGN AVAGRAHA
+ {0x119E2, 0x119E2, prN}, // Po NANDINAGARI SIGN SIDDHAM
+ {0x119E3, 0x119E3, prN}, // Lo NANDINAGARI HEADSTROKE
+ {0x119E4, 0x119E4, prN}, // Mc NANDINAGARI VOWEL SIGN PRISHTHAMATRA E
+ {0x11A00, 0x11A00, prN}, // Lo ZANABAZAR SQUARE LETTER A
+ {0x11A01, 0x11A0A, prN}, // Mn [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK
+ {0x11A0B, 0x11A32, prN}, // Lo [40] ZANABAZAR SQUARE LETTER KA..ZANABAZAR SQUARE LETTER KSSA
+ {0x11A33, 0x11A38, prN}, // Mn [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA
+ {0x11A39, 0x11A39, prN}, // Mc ZANABAZAR SQUARE SIGN VISARGA
+ {0x11A3A, 0x11A3A, prN}, // Lo ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA
+ {0x11A3B, 0x11A3E, prN}, // Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA
+ {0x11A3F, 0x11A46, prN}, // Po [8] ZANABAZAR SQUARE INITIAL HEAD MARK..ZANABAZAR SQUARE CLOSING DOUBLE-LINED HEAD MARK
+ {0x11A47, 0x11A47, prN}, // Mn ZANABAZAR SQUARE SUBJOINER
+ {0x11A50, 0x11A50, prN}, // Lo SOYOMBO LETTER A
+ {0x11A51, 0x11A56, prN}, // Mn [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE
+ {0x11A57, 0x11A58, prN}, // Mc [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU
+ {0x11A59, 0x11A5B, prN}, // Mn [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK
+ {0x11A5C, 0x11A89, prN}, // Lo [46] SOYOMBO LETTER KA..SOYOMBO CLUSTER-INITIAL LETTER SA
+ {0x11A8A, 0x11A96, prN}, // Mn [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA
+ {0x11A97, 0x11A97, prN}, // Mc SOYOMBO SIGN VISARGA
+ {0x11A98, 0x11A99, prN}, // Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER
+ {0x11A9A, 0x11A9C, prN}, // Po [3] SOYOMBO MARK TSHEG..SOYOMBO MARK DOUBLE SHAD
+ {0x11A9D, 0x11A9D, prN}, // Lo SOYOMBO MARK PLUTA
+ {0x11A9E, 0x11AA2, prN}, // Po [5] SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME..SOYOMBO TERMINAL MARK-2
+ {0x11AB0, 0x11ABF, prN}, // Lo [16] CANADIAN SYLLABICS NATTILIK HI..CANADIAN SYLLABICS SPA
+ {0x11AC0, 0x11AF8, prN}, // Lo [57] PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL
+ {0x11B00, 0x11B09, prN}, // Po [10] DEVANAGARI HEAD MARK..DEVANAGARI SIGN MINDU
+ {0x11C00, 0x11C08, prN}, // Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L
+ {0x11C0A, 0x11C2E, prN}, // Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA
+ {0x11C2F, 0x11C2F, prN}, // Mc BHAIKSUKI VOWEL SIGN AA
+ {0x11C30, 0x11C36, prN}, // Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L
+ {0x11C38, 0x11C3D, prN}, // Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA
+ {0x11C3E, 0x11C3E, prN}, // Mc BHAIKSUKI SIGN VISARGA
+ {0x11C3F, 0x11C3F, prN}, // Mn BHAIKSUKI SIGN VIRAMA
+ {0x11C40, 0x11C40, prN}, // Lo BHAIKSUKI SIGN AVAGRAHA
+ {0x11C41, 0x11C45, prN}, // Po [5] BHAIKSUKI DANDA..BHAIKSUKI GAP FILLER-2
+ {0x11C50, 0x11C59, prN}, // Nd [10] BHAIKSUKI DIGIT ZERO..BHAIKSUKI DIGIT NINE
+ {0x11C5A, 0x11C6C, prN}, // No [19] BHAIKSUKI NUMBER ONE..BHAIKSUKI HUNDREDS UNIT MARK
+ {0x11C70, 0x11C71, prN}, // Po [2] MARCHEN HEAD MARK..MARCHEN MARK SHAD
+ {0x11C72, 0x11C8F, prN}, // Lo [30] MARCHEN LETTER KA..MARCHEN LETTER A
+ {0x11C92, 0x11CA7, prN}, // Mn [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA
+ {0x11CA9, 0x11CA9, prN}, // Mc MARCHEN SUBJOINED LETTER YA
+ {0x11CAA, 0x11CB0, prN}, // Mn [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA
+ {0x11CB1, 0x11CB1, prN}, // Mc MARCHEN VOWEL SIGN I
+ {0x11CB2, 0x11CB3, prN}, // Mn [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E
+ {0x11CB4, 0x11CB4, prN}, // Mc MARCHEN VOWEL SIGN O
+ {0x11CB5, 0x11CB6, prN}, // Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU
+ {0x11D00, 0x11D06, prN}, // Lo [7] MASARAM GONDI LETTER A..MASARAM GONDI LETTER E
+ {0x11D08, 0x11D09, prN}, // Lo [2] MASARAM GONDI LETTER AI..MASARAM GONDI LETTER O
+ {0x11D0B, 0x11D30, prN}, // Lo [38] MASARAM GONDI LETTER AU..MASARAM GONDI LETTER TRA
+ {0x11D31, 0x11D36, prN}, // Mn [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R
+ {0x11D3A, 0x11D3A, prN}, // Mn MASARAM GONDI VOWEL SIGN E
+ {0x11D3C, 0x11D3D, prN}, // Mn [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O
+ {0x11D3F, 0x11D45, prN}, // Mn [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA
+ {0x11D46, 0x11D46, prN}, // Lo MASARAM GONDI REPHA
+ {0x11D47, 0x11D47, prN}, // Mn MASARAM GONDI RA-KARA
+ {0x11D50, 0x11D59, prN}, // Nd [10] MASARAM GONDI DIGIT ZERO..MASARAM GONDI DIGIT NINE
+ {0x11D60, 0x11D65, prN}, // Lo [6] GUNJALA GONDI LETTER A..GUNJALA GONDI LETTER UU
+ {0x11D67, 0x11D68, prN}, // Lo [2] GUNJALA GONDI LETTER EE..GUNJALA GONDI LETTER AI
+ {0x11D6A, 0x11D89, prN}, // Lo [32] GUNJALA GONDI LETTER OO..GUNJALA GONDI LETTER SA
+ {0x11D8A, 0x11D8E, prN}, // Mc [5] GUNJALA GONDI VOWEL SIGN AA..GUNJALA GONDI VOWEL SIGN UU
+ {0x11D90, 0x11D91, prN}, // Mn [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI
+ {0x11D93, 0x11D94, prN}, // Mc [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU
+ {0x11D95, 0x11D95, prN}, // Mn GUNJALA GONDI SIGN ANUSVARA
+ {0x11D96, 0x11D96, prN}, // Mc GUNJALA GONDI SIGN VISARGA
+ {0x11D97, 0x11D97, prN}, // Mn GUNJALA GONDI VIRAMA
+ {0x11D98, 0x11D98, prN}, // Lo GUNJALA GONDI OM
+ {0x11DA0, 0x11DA9, prN}, // Nd [10] GUNJALA GONDI DIGIT ZERO..GUNJALA GONDI DIGIT NINE
+ {0x11EE0, 0x11EF2, prN}, // Lo [19] MAKASAR LETTER KA..MAKASAR ANGKA
+ {0x11EF3, 0x11EF4, prN}, // Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U
+ {0x11EF5, 0x11EF6, prN}, // Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O
+ {0x11EF7, 0x11EF8, prN}, // Po [2] MAKASAR PASSIMBANG..MAKASAR END OF SECTION
+ {0x11F00, 0x11F01, prN}, // Mn [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA
+ {0x11F02, 0x11F02, prN}, // Lo KAWI SIGN REPHA
+ {0x11F03, 0x11F03, prN}, // Mc KAWI SIGN VISARGA
+ {0x11F04, 0x11F10, prN}, // Lo [13] KAWI LETTER A..KAWI LETTER O
+ {0x11F12, 0x11F33, prN}, // Lo [34] KAWI LETTER KA..KAWI LETTER JNYA
+ {0x11F34, 0x11F35, prN}, // Mc [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA
+ {0x11F36, 0x11F3A, prN}, // Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R
+ {0x11F3E, 0x11F3F, prN}, // Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI
+ {0x11F40, 0x11F40, prN}, // Mn KAWI VOWEL SIGN EU
+ {0x11F41, 0x11F41, prN}, // Mc KAWI SIGN KILLER
+ {0x11F42, 0x11F42, prN}, // Mn KAWI CONJOINER
+ {0x11F43, 0x11F4F, prN}, // Po [13] KAWI DANDA..KAWI PUNCTUATION CLOSING SPIRAL
+ {0x11F50, 0x11F59, prN}, // Nd [10] KAWI DIGIT ZERO..KAWI DIGIT NINE
+ {0x11FB0, 0x11FB0, prN}, // Lo LISU LETTER YHA
+ {0x11FC0, 0x11FD4, prN}, // No [21] TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH..TAMIL FRACTION DOWNSCALING FACTOR KIIZH
+ {0x11FD5, 0x11FDC, prN}, // So [8] TAMIL SIGN NEL..TAMIL SIGN MUKKURUNI
+ {0x11FDD, 0x11FE0, prN}, // Sc [4] TAMIL SIGN KAACU..TAMIL SIGN VARAAKAN
+ {0x11FE1, 0x11FF1, prN}, // So [17] TAMIL SIGN PAARAM..TAMIL SIGN VAKAIYARAA
+ {0x11FFF, 0x11FFF, prN}, // Po TAMIL PUNCTUATION END OF TEXT
+ {0x12000, 0x12399, prN}, // Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U
+ {0x12400, 0x1246E, prN}, // Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM
+ {0x12470, 0x12474, prN}, // Po [5] CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER..CUNEIFORM PUNCTUATION SIGN DIAGONAL QUADCOLON
+ {0x12480, 0x12543, prN}, // Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU
+ {0x12F90, 0x12FF0, prN}, // Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114
+ {0x12FF1, 0x12FF2, prN}, // Po [2] CYPRO-MINOAN SIGN CM301..CYPRO-MINOAN SIGN CM302
+ {0x13000, 0x1342F, prN}, // Lo [1072] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH V011D
+ {0x13430, 0x1343F, prN}, // Cf [16] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE
+ {0x13440, 0x13440, prN}, // Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY
+ {0x13441, 0x13446, prN}, // Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN
+ {0x13447, 0x13455, prN}, // Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED
+ {0x14400, 0x14646, prN}, // Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530
+ {0x16800, 0x16A38, prN}, // Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ
+ {0x16A40, 0x16A5E, prN}, // Lo [31] MRO LETTER TA..MRO LETTER TEK
+ {0x16A60, 0x16A69, prN}, // Nd [10] MRO DIGIT ZERO..MRO DIGIT NINE
+ {0x16A6E, 0x16A6F, prN}, // Po [2] MRO DANDA..MRO DOUBLE DANDA
+ {0x16A70, 0x16ABE, prN}, // Lo [79] TANGSA LETTER OZ..TANGSA LETTER ZA
+ {0x16AC0, 0x16AC9, prN}, // Nd [10] TANGSA DIGIT ZERO..TANGSA DIGIT NINE
+ {0x16AD0, 0x16AED, prN}, // Lo [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I
+ {0x16AF0, 0x16AF4, prN}, // Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE
+ {0x16AF5, 0x16AF5, prN}, // Po BASSA VAH FULL STOP
+ {0x16B00, 0x16B2F, prN}, // Lo [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU
+ {0x16B30, 0x16B36, prN}, // Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM
+ {0x16B37, 0x16B3B, prN}, // Po [5] PAHAWH HMONG SIGN VOS THOM..PAHAWH HMONG SIGN VOS FEEM
+ {0x16B3C, 0x16B3F, prN}, // So [4] PAHAWH HMONG SIGN XYEEM NTXIV..PAHAWH HMONG SIGN XYEEM FAIB
+ {0x16B40, 0x16B43, prN}, // Lm [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM
+ {0x16B44, 0x16B44, prN}, // Po PAHAWH HMONG SIGN XAUS
+ {0x16B45, 0x16B45, prN}, // So PAHAWH HMONG SIGN CIM TSOV ROG
+ {0x16B50, 0x16B59, prN}, // Nd [10] PAHAWH HMONG DIGIT ZERO..PAHAWH HMONG DIGIT NINE
+ {0x16B5B, 0x16B61, prN}, // No [7] PAHAWH HMONG NUMBER TENS..PAHAWH HMONG NUMBER TRILLIONS
+ {0x16B63, 0x16B77, prN}, // Lo [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS
+ {0x16B7D, 0x16B8F, prN}, // Lo [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ
+ {0x16E40, 0x16E7F, prN}, // L& [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y
+ {0x16E80, 0x16E96, prN}, // No [23] MEDEFAIDRIN DIGIT ZERO..MEDEFAIDRIN DIGIT THREE ALTERNATE FORM
+ {0x16E97, 0x16E9A, prN}, // Po [4] MEDEFAIDRIN COMMA..MEDEFAIDRIN EXCLAMATION OH
+ {0x16F00, 0x16F4A, prN}, // Lo [75] MIAO LETTER PA..MIAO LETTER RTE
+ {0x16F4F, 0x16F4F, prN}, // Mn MIAO SIGN CONSONANT MODIFIER BAR
+ {0x16F50, 0x16F50, prN}, // Lo MIAO LETTER NASALIZATION
+ {0x16F51, 0x16F87, prN}, // Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI
+ {0x16F8F, 0x16F92, prN}, // Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW
+ {0x16F93, 0x16F9F, prN}, // Lm [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8
+ {0x16FE0, 0x16FE1, prW}, // Lm [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK
+ {0x16FE2, 0x16FE2, prW}, // Po OLD CHINESE HOOK MARK
+ {0x16FE3, 0x16FE3, prW}, // Lm OLD CHINESE ITERATION MARK
+ {0x16FE4, 0x16FE4, prW}, // Mn KHITAN SMALL SCRIPT FILLER
+ {0x16FF0, 0x16FF1, prW}, // Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY
+ {0x17000, 0x187F7, prW}, // Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7
+ {0x18800, 0x18AFF, prW}, // Lo [768] TANGUT COMPONENT-001..TANGUT COMPONENT-768
+ {0x18B00, 0x18CD5, prW}, // Lo [470] KHITAN SMALL SCRIPT CHARACTER-18B00..KHITAN SMALL SCRIPT CHARACTER-18CD5
+ {0x18D00, 0x18D08, prW}, // Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08
+ {0x1AFF0, 0x1AFF3, prW}, // Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5
+ {0x1AFF5, 0x1AFFB, prW}, // Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5
+ {0x1AFFD, 0x1AFFE, prW}, // Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8
+ {0x1B000, 0x1B0FF, prW}, // Lo [256] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER RE-2
+ {0x1B100, 0x1B122, prW}, // Lo [35] HENTAIGANA LETTER RE-3..KATAKANA LETTER ARCHAIC WU
+ {0x1B132, 0x1B132, prW}, // Lo HIRAGANA LETTER SMALL KO
+ {0x1B150, 0x1B152, prW}, // Lo [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO
+ {0x1B155, 0x1B155, prW}, // Lo KATAKANA LETTER SMALL KO
+ {0x1B164, 0x1B167, prW}, // Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N
+ {0x1B170, 0x1B2FB, prW}, // Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB
+ {0x1BC00, 0x1BC6A, prN}, // Lo [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M
+ {0x1BC70, 0x1BC7C, prN}, // Lo [13] DUPLOYAN AFFIX LEFT HORIZONTAL SECANT..DUPLOYAN AFFIX ATTACHED TANGENT HOOK
+ {0x1BC80, 0x1BC88, prN}, // Lo [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL
+ {0x1BC90, 0x1BC99, prN}, // Lo [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW
+ {0x1BC9C, 0x1BC9C, prN}, // So DUPLOYAN SIGN O WITH CROSS
+ {0x1BC9D, 0x1BC9E, prN}, // Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK
+ {0x1BC9F, 0x1BC9F, prN}, // Po DUPLOYAN PUNCTUATION CHINOOK FULL STOP
+ {0x1BCA0, 0x1BCA3, prN}, // Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP
+ {0x1CF00, 0x1CF2D, prN}, // Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT
+ {0x1CF30, 0x1CF46, prN}, // Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG
+ {0x1CF50, 0x1CFC3, prN}, // So [116] ZNAMENNY NEUME KRYUK..ZNAMENNY NEUME PAUK
+ {0x1D000, 0x1D0F5, prN}, // So [246] BYZANTINE MUSICAL SYMBOL PSILI..BYZANTINE MUSICAL SYMBOL GORGON NEO KATO
+ {0x1D100, 0x1D126, prN}, // So [39] MUSICAL SYMBOL SINGLE BARLINE..MUSICAL SYMBOL DRUM CLEF-2
+ {0x1D129, 0x1D164, prN}, // So [60] MUSICAL SYMBOL MULTIPLE MEASURE REST..MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE
+ {0x1D165, 0x1D166, prN}, // Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM
+ {0x1D167, 0x1D169, prN}, // Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3
+ {0x1D16A, 0x1D16C, prN}, // So [3] MUSICAL SYMBOL FINGERED TREMOLO-1..MUSICAL SYMBOL FINGERED TREMOLO-3
+ {0x1D16D, 0x1D172, prN}, // Mc [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5
+ {0x1D173, 0x1D17A, prN}, // Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE
+ {0x1D17B, 0x1D182, prN}, // Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE
+ {0x1D183, 0x1D184, prN}, // So [2] MUSICAL SYMBOL ARPEGGIATO UP..MUSICAL SYMBOL ARPEGGIATO DOWN
+ {0x1D185, 0x1D18B, prN}, // Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE
+ {0x1D18C, 0x1D1A9, prN}, // So [30] MUSICAL SYMBOL RINFORZANDO..MUSICAL SYMBOL DEGREE SLASH
+ {0x1D1AA, 0x1D1AD, prN}, // Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO
+ {0x1D1AE, 0x1D1EA, prN}, // So [61] MUSICAL SYMBOL PEDAL MARK..MUSICAL SYMBOL KORON
+ {0x1D200, 0x1D241, prN}, // So [66] GREEK VOCAL NOTATION SYMBOL-1..GREEK INSTRUMENTAL NOTATION SYMBOL-54
+ {0x1D242, 0x1D244, prN}, // Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME
+ {0x1D245, 0x1D245, prN}, // So GREEK MUSICAL LEIMMA
+ {0x1D2C0, 0x1D2D3, prN}, // No [20] KAKTOVIK NUMERAL ZERO..KAKTOVIK NUMERAL NINETEEN
+ {0x1D2E0, 0x1D2F3, prN}, // No [20] MAYAN NUMERAL ZERO..MAYAN NUMERAL NINETEEN
+ {0x1D300, 0x1D356, prN}, // So [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING
+ {0x1D360, 0x1D378, prN}, // No [25] COUNTING ROD UNIT DIGIT ONE..TALLY MARK FIVE
+ {0x1D400, 0x1D454, prN}, // L& [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G
+ {0x1D456, 0x1D49C, prN}, // L& [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A
+ {0x1D49E, 0x1D49F, prN}, // Lu [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D
+ {0x1D4A2, 0x1D4A2, prN}, // Lu MATHEMATICAL SCRIPT CAPITAL G
+ {0x1D4A5, 0x1D4A6, prN}, // Lu [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K
+ {0x1D4A9, 0x1D4AC, prN}, // Lu [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q
+ {0x1D4AE, 0x1D4B9, prN}, // L& [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D
+ {0x1D4BB, 0x1D4BB, prN}, // Ll MATHEMATICAL SCRIPT SMALL F
+ {0x1D4BD, 0x1D4C3, prN}, // Ll [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N
+ {0x1D4C5, 0x1D505, prN}, // L& [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B
+ {0x1D507, 0x1D50A, prN}, // Lu [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G
+ {0x1D50D, 0x1D514, prN}, // Lu [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q
+ {0x1D516, 0x1D51C, prN}, // Lu [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y
+ {0x1D51E, 0x1D539, prN}, // L& [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B
+ {0x1D53B, 0x1D53E, prN}, // Lu [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G
+ {0x1D540, 0x1D544, prN}, // Lu [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M
+ {0x1D546, 0x1D546, prN}, // Lu MATHEMATICAL DOUBLE-STRUCK CAPITAL O
+ {0x1D54A, 0x1D550, prN}, // Lu [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y
+ {0x1D552, 0x1D6A5, prN}, // L& [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J
+ {0x1D6A8, 0x1D6C0, prN}, // Lu [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA
+ {0x1D6C1, 0x1D6C1, prN}, // Sm MATHEMATICAL BOLD NABLA
+ {0x1D6C2, 0x1D6DA, prN}, // Ll [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA
+ {0x1D6DB, 0x1D6DB, prN}, // Sm MATHEMATICAL BOLD PARTIAL DIFFERENTIAL
+ {0x1D6DC, 0x1D6FA, prN}, // L& [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA
+ {0x1D6FB, 0x1D6FB, prN}, // Sm MATHEMATICAL ITALIC NABLA
+ {0x1D6FC, 0x1D714, prN}, // Ll [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA
+ {0x1D715, 0x1D715, prN}, // Sm MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL
+ {0x1D716, 0x1D734, prN}, // L& [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA
+ {0x1D735, 0x1D735, prN}, // Sm MATHEMATICAL BOLD ITALIC NABLA
+ {0x1D736, 0x1D74E, prN}, // Ll [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA
+ {0x1D74F, 0x1D74F, prN}, // Sm MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL
+ {0x1D750, 0x1D76E, prN}, // L& [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA
+ {0x1D76F, 0x1D76F, prN}, // Sm MATHEMATICAL SANS-SERIF BOLD NABLA
+ {0x1D770, 0x1D788, prN}, // Ll [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA
+ {0x1D789, 0x1D789, prN}, // Sm MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL
+ {0x1D78A, 0x1D7A8, prN}, // L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA
+ {0x1D7A9, 0x1D7A9, prN}, // Sm MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA
+ {0x1D7AA, 0x1D7C2, prN}, // Ll [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA
+ {0x1D7C3, 0x1D7C3, prN}, // Sm MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL
+ {0x1D7C4, 0x1D7CB, prN}, // L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA
+ {0x1D7CE, 0x1D7FF, prN}, // Nd [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE
+ {0x1D800, 0x1D9FF, prN}, // So [512] SIGNWRITING HAND-FIST INDEX..SIGNWRITING HEAD
+ {0x1DA00, 0x1DA36, prN}, // Mn [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN
+ {0x1DA37, 0x1DA3A, prN}, // So [4] SIGNWRITING AIR BLOW SMALL ROTATIONS..SIGNWRITING BREATH EXHALE
+ {0x1DA3B, 0x1DA6C, prN}, // Mn [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT
+ {0x1DA6D, 0x1DA74, prN}, // So [8] SIGNWRITING SHOULDER HIP SPINE..SIGNWRITING TORSO-FLOORPLANE TWISTING
+ {0x1DA75, 0x1DA75, prN}, // Mn SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS
+ {0x1DA76, 0x1DA83, prN}, // So [14] SIGNWRITING LIMB COMBINATION..SIGNWRITING LOCATION DEPTH
+ {0x1DA84, 0x1DA84, prN}, // Mn SIGNWRITING LOCATION HEAD NECK
+ {0x1DA85, 0x1DA86, prN}, // So [2] SIGNWRITING LOCATION TORSO..SIGNWRITING LOCATION LIMBS DIGITS
+ {0x1DA87, 0x1DA8B, prN}, // Po [5] SIGNWRITING COMMA..SIGNWRITING PARENTHESIS
+ {0x1DA9B, 0x1DA9F, prN}, // Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6
+ {0x1DAA1, 0x1DAAF, prN}, // Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16
+ {0x1DF00, 0x1DF09, prN}, // Ll [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK
+ {0x1DF0A, 0x1DF0A, prN}, // Lo LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK
+ {0x1DF0B, 0x1DF1E, prN}, // Ll [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL
+ {0x1DF25, 0x1DF2A, prN}, // Ll [6] LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK..LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK
+ {0x1E000, 0x1E006, prN}, // Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE
+ {0x1E008, 0x1E018, prN}, // Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU
+ {0x1E01B, 0x1E021, prN}, // Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI
+ {0x1E023, 0x1E024, prN}, // Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS
+ {0x1E026, 0x1E02A, prN}, // Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA
+ {0x1E030, 0x1E06D, prN}, // Lm [62] MODIFIER LETTER CYRILLIC SMALL A..MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE
+ {0x1E08F, 0x1E08F, prN}, // Mn COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+ {0x1E100, 0x1E12C, prN}, // Lo [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W
+ {0x1E130, 0x1E136, prN}, // Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D
+ {0x1E137, 0x1E13D, prN}, // Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER
+ {0x1E140, 0x1E149, prN}, // Nd [10] NYIAKENG PUACHUE HMONG DIGIT ZERO..NYIAKENG PUACHUE HMONG DIGIT NINE
+ {0x1E14E, 0x1E14E, prN}, // Lo NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ
+ {0x1E14F, 0x1E14F, prN}, // So NYIAKENG PUACHUE HMONG CIRCLED CA
+ {0x1E290, 0x1E2AD, prN}, // Lo [30] TOTO LETTER PA..TOTO LETTER A
+ {0x1E2AE, 0x1E2AE, prN}, // Mn TOTO SIGN RISING TONE
+ {0x1E2C0, 0x1E2EB, prN}, // Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH
+ {0x1E2EC, 0x1E2EF, prN}, // Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI
+ {0x1E2F0, 0x1E2F9, prN}, // Nd [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE
+ {0x1E2FF, 0x1E2FF, prN}, // Sc WANCHO NGUN SIGN
+ {0x1E4D0, 0x1E4EA, prN}, // Lo [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL
+ {0x1E4EB, 0x1E4EB, prN}, // Lm NAG MUNDARI SIGN OJOD
+ {0x1E4EC, 0x1E4EF, prN}, // Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH
+ {0x1E4F0, 0x1E4F9, prN}, // Nd [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE
+ {0x1E7E0, 0x1E7E6, prN}, // Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO
+ {0x1E7E8, 0x1E7EB, prN}, // Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE
+ {0x1E7ED, 0x1E7EE, prN}, // Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE
+ {0x1E7F0, 0x1E7FE, prN}, // Lo [15] ETHIOPIC SYLLABLE GURAGE QWI..ETHIOPIC SYLLABLE GURAGE PWEE
+ {0x1E800, 0x1E8C4, prN}, // Lo [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON
+ {0x1E8C7, 0x1E8CF, prN}, // No [9] MENDE KIKAKUI DIGIT ONE..MENDE KIKAKUI DIGIT NINE
+ {0x1E8D0, 0x1E8D6, prN}, // Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS
+ {0x1E900, 0x1E943, prN}, // L& [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA
+ {0x1E944, 0x1E94A, prN}, // Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA
+ {0x1E94B, 0x1E94B, prN}, // Lm ADLAM NASALIZATION MARK
+ {0x1E950, 0x1E959, prN}, // Nd [10] ADLAM DIGIT ZERO..ADLAM DIGIT NINE
+ {0x1E95E, 0x1E95F, prN}, // Po [2] ADLAM INITIAL EXCLAMATION MARK..ADLAM INITIAL QUESTION MARK
+ {0x1EC71, 0x1ECAB, prN}, // No [59] INDIC SIYAQ NUMBER ONE..INDIC SIYAQ NUMBER PREFIXED NINE
+ {0x1ECAC, 0x1ECAC, prN}, // So INDIC SIYAQ PLACEHOLDER
+ {0x1ECAD, 0x1ECAF, prN}, // No [3] INDIC SIYAQ FRACTION ONE QUARTER..INDIC SIYAQ FRACTION THREE QUARTERS
+ {0x1ECB0, 0x1ECB0, prN}, // Sc INDIC SIYAQ RUPEE MARK
+ {0x1ECB1, 0x1ECB4, prN}, // No [4] INDIC SIYAQ NUMBER ALTERNATE ONE..INDIC SIYAQ ALTERNATE LAKH MARK
+ {0x1ED01, 0x1ED2D, prN}, // No [45] OTTOMAN SIYAQ NUMBER ONE..OTTOMAN SIYAQ NUMBER NINETY THOUSAND
+ {0x1ED2E, 0x1ED2E, prN}, // So OTTOMAN SIYAQ MARRATAN
+ {0x1ED2F, 0x1ED3D, prN}, // No [15] OTTOMAN SIYAQ ALTERNATE NUMBER TWO..OTTOMAN SIYAQ FRACTION ONE SIXTH
+ {0x1EE00, 0x1EE03, prN}, // Lo [4] ARABIC MATHEMATICAL ALEF..ARABIC MATHEMATICAL DAL
+ {0x1EE05, 0x1EE1F, prN}, // Lo [27] ARABIC MATHEMATICAL WAW..ARABIC MATHEMATICAL DOTLESS QAF
+ {0x1EE21, 0x1EE22, prN}, // Lo [2] ARABIC MATHEMATICAL INITIAL BEH..ARABIC MATHEMATICAL INITIAL JEEM
+ {0x1EE24, 0x1EE24, prN}, // Lo ARABIC MATHEMATICAL INITIAL HEH
+ {0x1EE27, 0x1EE27, prN}, // Lo ARABIC MATHEMATICAL INITIAL HAH
+ {0x1EE29, 0x1EE32, prN}, // Lo [10] ARABIC MATHEMATICAL INITIAL YEH..ARABIC MATHEMATICAL INITIAL QAF
+ {0x1EE34, 0x1EE37, prN}, // Lo [4] ARABIC MATHEMATICAL INITIAL SHEEN..ARABIC MATHEMATICAL INITIAL KHAH
+ {0x1EE39, 0x1EE39, prN}, // Lo ARABIC MATHEMATICAL INITIAL DAD
+ {0x1EE3B, 0x1EE3B, prN}, // Lo ARABIC MATHEMATICAL INITIAL GHAIN
+ {0x1EE42, 0x1EE42, prN}, // Lo ARABIC MATHEMATICAL TAILED JEEM
+ {0x1EE47, 0x1EE47, prN}, // Lo ARABIC MATHEMATICAL TAILED HAH
+ {0x1EE49, 0x1EE49, prN}, // Lo ARABIC MATHEMATICAL TAILED YEH
+ {0x1EE4B, 0x1EE4B, prN}, // Lo ARABIC MATHEMATICAL TAILED LAM
+ {0x1EE4D, 0x1EE4F, prN}, // Lo [3] ARABIC MATHEMATICAL TAILED NOON..ARABIC MATHEMATICAL TAILED AIN
+ {0x1EE51, 0x1EE52, prN}, // Lo [2] ARABIC MATHEMATICAL TAILED SAD..ARABIC MATHEMATICAL TAILED QAF
+ {0x1EE54, 0x1EE54, prN}, // Lo ARABIC MATHEMATICAL TAILED SHEEN
+ {0x1EE57, 0x1EE57, prN}, // Lo ARABIC MATHEMATICAL TAILED KHAH
+ {0x1EE59, 0x1EE59, prN}, // Lo ARABIC MATHEMATICAL TAILED DAD
+ {0x1EE5B, 0x1EE5B, prN}, // Lo ARABIC MATHEMATICAL TAILED GHAIN
+ {0x1EE5D, 0x1EE5D, prN}, // Lo ARABIC MATHEMATICAL TAILED DOTLESS NOON
+ {0x1EE5F, 0x1EE5F, prN}, // Lo ARABIC MATHEMATICAL TAILED DOTLESS QAF
+ {0x1EE61, 0x1EE62, prN}, // Lo [2] ARABIC MATHEMATICAL STRETCHED BEH..ARABIC MATHEMATICAL STRETCHED JEEM
+ {0x1EE64, 0x1EE64, prN}, // Lo ARABIC MATHEMATICAL STRETCHED HEH
+ {0x1EE67, 0x1EE6A, prN}, // Lo [4] ARABIC MATHEMATICAL STRETCHED HAH..ARABIC MATHEMATICAL STRETCHED KAF
+ {0x1EE6C, 0x1EE72, prN}, // Lo [7] ARABIC MATHEMATICAL STRETCHED MEEM..ARABIC MATHEMATICAL STRETCHED QAF
+ {0x1EE74, 0x1EE77, prN}, // Lo [4] ARABIC MATHEMATICAL STRETCHED SHEEN..ARABIC MATHEMATICAL STRETCHED KHAH
+ {0x1EE79, 0x1EE7C, prN}, // Lo [4] ARABIC MATHEMATICAL STRETCHED DAD..ARABIC MATHEMATICAL STRETCHED DOTLESS BEH
+ {0x1EE7E, 0x1EE7E, prN}, // Lo ARABIC MATHEMATICAL STRETCHED DOTLESS FEH
+ {0x1EE80, 0x1EE89, prN}, // Lo [10] ARABIC MATHEMATICAL LOOPED ALEF..ARABIC MATHEMATICAL LOOPED YEH
+ {0x1EE8B, 0x1EE9B, prN}, // Lo [17] ARABIC MATHEMATICAL LOOPED LAM..ARABIC MATHEMATICAL LOOPED GHAIN
+ {0x1EEA1, 0x1EEA3, prN}, // Lo [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL
+ {0x1EEA5, 0x1EEA9, prN}, // Lo [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH
+ {0x1EEAB, 0x1EEBB, prN}, // Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN
+ {0x1EEF0, 0x1EEF1, prN}, // Sm [2] ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL..ARABIC MATHEMATICAL OPERATOR HAH WITH DAL
+ {0x1F000, 0x1F003, prN}, // So [4] MAHJONG TILE EAST WIND..MAHJONG TILE NORTH WIND
+ {0x1F004, 0x1F004, prW}, // So MAHJONG TILE RED DRAGON
+ {0x1F005, 0x1F02B, prN}, // So [39] MAHJONG TILE GREEN DRAGON..MAHJONG TILE BACK
+ {0x1F030, 0x1F093, prN}, // So [100] DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06
+ {0x1F0A0, 0x1F0AE, prN}, // So [15] PLAYING CARD BACK..PLAYING CARD KING OF SPADES
+ {0x1F0B1, 0x1F0BF, prN}, // So [15] PLAYING CARD ACE OF HEARTS..PLAYING CARD RED JOKER
+ {0x1F0C1, 0x1F0CE, prN}, // So [14] PLAYING CARD ACE OF DIAMONDS..PLAYING CARD KING OF DIAMONDS
+ {0x1F0CF, 0x1F0CF, prW}, // So PLAYING CARD BLACK JOKER
+ {0x1F0D1, 0x1F0F5, prN}, // So [37] PLAYING CARD ACE OF CLUBS..PLAYING CARD TRUMP-21
+ {0x1F100, 0x1F10A, prA}, // No [11] DIGIT ZERO FULL STOP..DIGIT NINE COMMA
+ {0x1F10B, 0x1F10C, prN}, // No [2] DINGBAT CIRCLED SANS-SERIF DIGIT ZERO..DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO
+ {0x1F10D, 0x1F10F, prN}, // So [3] CIRCLED ZERO WITH SLASH..CIRCLED DOLLAR SIGN WITH OVERLAID BACKSLASH
+ {0x1F110, 0x1F12D, prA}, // So [30] PARENTHESIZED LATIN CAPITAL LETTER A..CIRCLED CD
+ {0x1F12E, 0x1F12F, prN}, // So [2] CIRCLED WZ..COPYLEFT SYMBOL
+ {0x1F130, 0x1F169, prA}, // So [58] SQUARED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z
+ {0x1F16A, 0x1F16F, prN}, // So [6] RAISED MC SIGN..CIRCLED HUMAN FIGURE
+ {0x1F170, 0x1F18D, prA}, // So [30] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED SA
+ {0x1F18E, 0x1F18E, prW}, // So NEGATIVE SQUARED AB
+ {0x1F18F, 0x1F190, prA}, // So [2] NEGATIVE SQUARED WC..SQUARE DJ
+ {0x1F191, 0x1F19A, prW}, // So [10] SQUARED CL..SQUARED VS
+ {0x1F19B, 0x1F1AC, prA}, // So [18] SQUARED THREE D..SQUARED VOD
+ {0x1F1AD, 0x1F1AD, prN}, // So MASK WORK SYMBOL
+ {0x1F1E6, 0x1F1FF, prN}, // So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z
+ {0x1F200, 0x1F202, prW}, // So [3] SQUARE HIRAGANA HOKA..SQUARED KATAKANA SA
+ {0x1F210, 0x1F23B, prW}, // So [44] SQUARED CJK UNIFIED IDEOGRAPH-624B..SQUARED CJK UNIFIED IDEOGRAPH-914D
+ {0x1F240, 0x1F248, prW}, // So [9] TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C..TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557
+ {0x1F250, 0x1F251, prW}, // So [2] CIRCLED IDEOGRAPH ADVANTAGE..CIRCLED IDEOGRAPH ACCEPT
+ {0x1F260, 0x1F265, prW}, // So [6] ROUNDED SYMBOL FOR FU..ROUNDED SYMBOL FOR CAI
+ {0x1F300, 0x1F320, prW}, // So [33] CYCLONE..SHOOTING STAR
+ {0x1F321, 0x1F32C, prN}, // So [12] THERMOMETER..WIND BLOWING FACE
+ {0x1F32D, 0x1F335, prW}, // So [9] HOT DOG..CACTUS
+ {0x1F336, 0x1F336, prN}, // So HOT PEPPER
+ {0x1F337, 0x1F37C, prW}, // So [70] TULIP..BABY BOTTLE
+ {0x1F37D, 0x1F37D, prN}, // So FORK AND KNIFE WITH PLATE
+ {0x1F37E, 0x1F393, prW}, // So [22] BOTTLE WITH POPPING CORK..GRADUATION CAP
+ {0x1F394, 0x1F39F, prN}, // So [12] HEART WITH TIP ON THE LEFT..ADMISSION TICKETS
+ {0x1F3A0, 0x1F3CA, prW}, // So [43] CAROUSEL HORSE..SWIMMER
+ {0x1F3CB, 0x1F3CE, prN}, // So [4] WEIGHT LIFTER..RACING CAR
+ {0x1F3CF, 0x1F3D3, prW}, // So [5] CRICKET BAT AND BALL..TABLE TENNIS PADDLE AND BALL
+ {0x1F3D4, 0x1F3DF, prN}, // So [12] SNOW CAPPED MOUNTAIN..STADIUM
+ {0x1F3E0, 0x1F3F0, prW}, // So [17] HOUSE BUILDING..EUROPEAN CASTLE
+ {0x1F3F1, 0x1F3F3, prN}, // So [3] WHITE PENNANT..WAVING WHITE FLAG
+ {0x1F3F4, 0x1F3F4, prW}, // So WAVING BLACK FLAG
+ {0x1F3F5, 0x1F3F7, prN}, // So [3] ROSETTE..LABEL
+ {0x1F3F8, 0x1F3FA, prW}, // So [3] BADMINTON RACQUET AND SHUTTLECOCK..AMPHORA
+ {0x1F3FB, 0x1F3FF, prW}, // Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6
+ {0x1F400, 0x1F43E, prW}, // So [63] RAT..PAW PRINTS
+ {0x1F43F, 0x1F43F, prN}, // So CHIPMUNK
+ {0x1F440, 0x1F440, prW}, // So EYES
+ {0x1F441, 0x1F441, prN}, // So EYE
+ {0x1F442, 0x1F4FC, prW}, // So [187] EAR..VIDEOCASSETTE
+ {0x1F4FD, 0x1F4FE, prN}, // So [2] FILM PROJECTOR..PORTABLE STEREO
+ {0x1F4FF, 0x1F53D, prW}, // So [63] PRAYER BEADS..DOWN-POINTING SMALL RED TRIANGLE
+ {0x1F53E, 0x1F54A, prN}, // So [13] LOWER RIGHT SHADOWED WHITE CIRCLE..DOVE OF PEACE
+ {0x1F54B, 0x1F54E, prW}, // So [4] KAABA..MENORAH WITH NINE BRANCHES
+ {0x1F54F, 0x1F54F, prN}, // So BOWL OF HYGIEIA
+ {0x1F550, 0x1F567, prW}, // So [24] CLOCK FACE ONE OCLOCK..CLOCK FACE TWELVE-THIRTY
+ {0x1F568, 0x1F579, prN}, // So [18] RIGHT SPEAKER..JOYSTICK
+ {0x1F57A, 0x1F57A, prW}, // So MAN DANCING
+ {0x1F57B, 0x1F594, prN}, // So [26] LEFT HAND TELEPHONE RECEIVER..REVERSED VICTORY HAND
+ {0x1F595, 0x1F596, prW}, // So [2] REVERSED HAND WITH MIDDLE FINGER EXTENDED..RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS
+ {0x1F597, 0x1F5A3, prN}, // So [13] WHITE DOWN POINTING LEFT HAND INDEX..BLACK DOWN POINTING BACKHAND INDEX
+ {0x1F5A4, 0x1F5A4, prW}, // So BLACK HEART
+ {0x1F5A5, 0x1F5FA, prN}, // So [86] DESKTOP COMPUTER..WORLD MAP
+ {0x1F5FB, 0x1F5FF, prW}, // So [5] MOUNT FUJI..MOYAI
+ {0x1F600, 0x1F64F, prW}, // So [80] GRINNING FACE..PERSON WITH FOLDED HANDS
+ {0x1F650, 0x1F67F, prN}, // So [48] NORTH WEST POINTING LEAF..REVERSE CHECKER BOARD
+ {0x1F680, 0x1F6C5, prW}, // So [70] ROCKET..LEFT LUGGAGE
+ {0x1F6C6, 0x1F6CB, prN}, // So [6] TRIANGLE WITH ROUNDED CORNERS..COUCH AND LAMP
+ {0x1F6CC, 0x1F6CC, prW}, // So SLEEPING ACCOMMODATION
+ {0x1F6CD, 0x1F6CF, prN}, // So [3] SHOPPING BAGS..BED
+ {0x1F6D0, 0x1F6D2, prW}, // So [3] PLACE OF WORSHIP..SHOPPING TROLLEY
+ {0x1F6D3, 0x1F6D4, prN}, // So [2] STUPA..PAGODA
+ {0x1F6D5, 0x1F6D7, prW}, // So [3] HINDU TEMPLE..ELEVATOR
+ {0x1F6DC, 0x1F6DF, prW}, // So [4] WIRELESS..RING BUOY
+ {0x1F6E0, 0x1F6EA, prN}, // So [11] HAMMER AND WRENCH..NORTHEAST-POINTING AIRPLANE
+ {0x1F6EB, 0x1F6EC, prW}, // So [2] AIRPLANE DEPARTURE..AIRPLANE ARRIVING
+ {0x1F6F0, 0x1F6F3, prN}, // So [4] SATELLITE..PASSENGER SHIP
+ {0x1F6F4, 0x1F6FC, prW}, // So [9] SCOOTER..ROLLER SKATE
+ {0x1F700, 0x1F776, prN}, // So [119] ALCHEMICAL SYMBOL FOR QUINTESSENCE..LUNAR ECLIPSE
+ {0x1F77B, 0x1F77F, prN}, // So [5] HAUMEA..ORCUS
+ {0x1F780, 0x1F7D9, prN}, // So [90] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..NINE POINTED WHITE STAR
+ {0x1F7E0, 0x1F7EB, prW}, // So [12] LARGE ORANGE CIRCLE..LARGE BROWN SQUARE
+ {0x1F7F0, 0x1F7F0, prW}, // So HEAVY EQUALS SIGN
+ {0x1F800, 0x1F80B, prN}, // So [12] LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD..DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD
+ {0x1F810, 0x1F847, prN}, // So [56] LEFTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD..DOWNWARDS HEAVY ARROW
+ {0x1F850, 0x1F859, prN}, // So [10] LEFTWARDS SANS-SERIF ARROW..UP DOWN SANS-SERIF ARROW
+ {0x1F860, 0x1F887, prN}, // So [40] WIDE-HEADED LEFTWARDS LIGHT BARB ARROW..WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW
+ {0x1F890, 0x1F8AD, prN}, // So [30] LEFTWARDS TRIANGLE ARROWHEAD..WHITE ARROW SHAFT WIDTH TWO THIRDS
+ {0x1F8B0, 0x1F8B1, prN}, // So [2] ARROW POINTING UPWARDS THEN NORTH WEST..ARROW POINTING RIGHTWARDS THEN CURVING SOUTH WEST
+ {0x1F900, 0x1F90B, prN}, // So [12] CIRCLED CROSS FORMEE WITH FOUR DOTS..DOWNWARD FACING NOTCHED HOOK WITH DOT
+ {0x1F90C, 0x1F93A, prW}, // So [47] PINCHED FINGERS..FENCER
+ {0x1F93B, 0x1F93B, prN}, // So MODERN PENTATHLON
+ {0x1F93C, 0x1F945, prW}, // So [10] WRESTLERS..GOAL NET
+ {0x1F946, 0x1F946, prN}, // So RIFLE
+ {0x1F947, 0x1F9FF, prW}, // So [185] FIRST PLACE MEDAL..NAZAR AMULET
+ {0x1FA00, 0x1FA53, prN}, // So [84] NEUTRAL CHESS KING..BLACK CHESS KNIGHT-BISHOP
+ {0x1FA60, 0x1FA6D, prN}, // So [14] XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER
+ {0x1FA70, 0x1FA7C, prW}, // So [13] BALLET SHOES..CRUTCH
+ {0x1FA80, 0x1FA88, prW}, // So [9] YO-YO..FLUTE
+ {0x1FA90, 0x1FABD, prW}, // So [46] RINGED PLANET..WING
+ {0x1FABF, 0x1FAC5, prW}, // So [7] GOOSE..PERSON WITH CROWN
+ {0x1FACE, 0x1FADB, prW}, // So [14] MOOSE..PEA POD
+ {0x1FAE0, 0x1FAE8, prW}, // So [9] MELTING FACE..SHAKING FACE
+ {0x1FAF0, 0x1FAF8, prW}, // So [9] HAND WITH INDEX FINGER AND THUMB CROSSED..RIGHTWARDS PUSHING HAND
+ {0x1FB00, 0x1FB92, prN}, // So [147] BLOCK SEXTANT-1..UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK
+ {0x1FB94, 0x1FBCA, prN}, // So [55] LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK..WHITE UP-POINTING CHEVRON
+ {0x1FBF0, 0x1FBF9, prN}, // Nd [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE
+ {0x20000, 0x2A6DF, prW}, // Lo [42720] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF
+ {0x2A6E0, 0x2A6FF, prW}, // Cn [32] ..
+ {0x2A700, 0x2B739, prW}, // Lo [4154] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B739
+ {0x2B73A, 0x2B73F, prW}, // Cn [6] ..
+ {0x2B740, 0x2B81D, prW}, // Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D
+ {0x2B81E, 0x2B81F, prW}, // Cn [2] ..
+ {0x2B820, 0x2CEA1, prW}, // Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1
+ {0x2CEA2, 0x2CEAF, prW}, // Cn [14] ..