Revision: 8002534b7e82
Branch: default
Author: Rob Pike <
r...@golang.org>
Date: Sat Mar 2 11:13:24 2013
Log: exp: delete all packages except norm
They are moving to
code.google.com/p/go.exp.
See also
https://codereview.appspot.com/7463043
R=golang-dev,
minux.ma
CC=golang-dev
https://codereview.appspot.com/7456047
http://code.google.com/p/go/source/detail?r=8002534b7e82
Deleted:
/src/pkg/exp/README
/src/pkg/exp/ebnf/ebnf.go
/src/pkg/exp/ebnf/ebnf_test.go
/src/pkg/exp/ebnf/parser.go
/src/pkg/exp/ebnflint/doc.go
/src/pkg/exp/ebnflint/ebnflint.go
/src/pkg/exp/ebnflint/ebnflint_test.go
/src/pkg/exp/gotype/doc.go
/src/pkg/exp/gotype/gotype.go
/src/pkg/exp/gotype/gotype_test.go
/src/pkg/exp/gotype/testdata/test1.go
/src/pkg/exp/inotify/inotify_linux.go
/src/pkg/exp/inotify/inotify_linux_test.go
/src/pkg/exp/locale/collate/Makefile
/src/pkg/exp/locale/collate/build/builder.go
/src/pkg/exp/locale/collate/build/builder_test.go
/src/pkg/exp/locale/collate/build/colelem.go
/src/pkg/exp/locale/collate/build/colelem_test.go
/src/pkg/exp/locale/collate/build/contract.go
/src/pkg/exp/locale/collate/build/contract_test.go
/src/pkg/exp/locale/collate/build/order.go
/src/pkg/exp/locale/collate/build/order_test.go
/src/pkg/exp/locale/collate/build/table.go
/src/pkg/exp/locale/collate/build/trie.go
/src/pkg/exp/locale/collate/build/trie_test.go
/src/pkg/exp/locale/collate/collate.go
/src/pkg/exp/locale/collate/collate_test.go
/src/pkg/exp/locale/collate/colltab/colelem.go
/src/pkg/exp/locale/collate/colltab/colelem_test.go
/src/pkg/exp/locale/collate/colltab/colltab.go
/src/pkg/exp/locale/collate/colltab/contract.go
/src/pkg/exp/locale/collate/colltab/contract_test.go
/src/pkg/exp/locale/collate/colltab/export.go
/src/pkg/exp/locale/collate/colltab/table.go
/src/pkg/exp/locale/collate/colltab/trie.go
/src/pkg/exp/locale/collate/colltab/trie_test.go
/src/pkg/exp/locale/collate/export_test.go
/src/pkg/exp/locale/collate/index.go
/src/pkg/exp/locale/collate/maketables.go
/src/pkg/exp/locale/collate/regtest.go
/src/pkg/exp/locale/collate/sort.go
/src/pkg/exp/locale/collate/sort_test.go
/src/pkg/exp/locale/collate/table_test.go
/src/pkg/exp/locale/collate/tables.go
/src/pkg/exp/locale/collate/tools/colcmp/Makefile
/src/pkg/exp/locale/collate/tools/colcmp/chars.go
/src/pkg/exp/locale/collate/tools/colcmp/col.go
/src/pkg/exp/locale/collate/tools/colcmp/colcmp.go
/src/pkg/exp/locale/collate/tools/colcmp/darwin.go
/src/pkg/exp/locale/collate/tools/colcmp/gen.go
/src/pkg/exp/locale/collate/tools/colcmp/icu.go
/src/pkg/exp/ssa/blockopt.go
/src/pkg/exp/ssa/builder.go
/src/pkg/exp/ssa/doc.go
/src/pkg/exp/ssa/dom.go
/src/pkg/exp/ssa/emit.go
/src/pkg/exp/ssa/func.go
/src/pkg/exp/ssa/importer.go
/src/pkg/exp/ssa/interp/external.go
/src/pkg/exp/ssa/interp/external_plan9.go
/src/pkg/exp/ssa/interp/external_unix.go
/src/pkg/exp/ssa/interp/external_windows.go
/src/pkg/exp/ssa/interp/interp.go
/src/pkg/exp/ssa/interp/interp_test.go
/src/pkg/exp/ssa/interp/map.go
/src/pkg/exp/ssa/interp/ops.go
/src/pkg/exp/ssa/interp/reflect.go
/src/pkg/exp/ssa/interp/testdata/coverage.go
/src/pkg/exp/ssa/interp/value.go
/src/pkg/exp/ssa/lift.go
/src/pkg/exp/ssa/literal.go
/src/pkg/exp/ssa/lvalue.go
/src/pkg/exp/ssa/print.go
/src/pkg/exp/ssa/promote.go
/src/pkg/exp/ssa/sanity.go
/src/pkg/exp/ssa/ssa.go
/src/pkg/exp/ssa/ssadump.go
/src/pkg/exp/ssa/util.go
/src/pkg/exp/utf8string/string.go
/src/pkg/exp/utf8string/string_test.go
/src/pkg/exp/winfsnotify/winfsnotify.go
/src/pkg/exp/winfsnotify/winfsnotify_test.go
=======================================
--- /src/pkg/exp/README Tue Feb 19 11:21:18 2013
+++ /dev/null
@@ -1,3 +0,0 @@
-This directory tree contains experimental packages and
-unfinished code that is subject to change. It does not
-have stable APIs, and is not present in stable releases.
=======================================
--- /src/pkg/exp/ebnf/ebnf.go Tue Nov 8 15:40:58 2011
+++ /dev/null
@@ -1,269 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package ebnf is a library for EBNF grammars. The input is text ([]byte)
-// satisfying the following grammar (represented itself in EBNF):
-//
-// Production = name "=" [ Expression ] "." .
-// Expression = Alternative { "|" Alternative } .
-// Alternative = Term { Term } .
-// Term = name | token [ "…" token ] | Group | Option | Repetition .
-// Group = "(" Expression ")" .
-// Option = "[" Expression "]" .
-// Repetition = "{" Expression "}" .
-//
-// A name is a Go identifier, a token is a Go string, and comments
-// and white space follow the same rules as for the Go language.
-// Production names starting with an uppercase Unicode letter denote
-// non-terminal productions (i.e., productions which allow white-space
-// and comments between tokens); all other production names denote
-// lexical productions.
-//
-package ebnf
-
-import (
- "errors"
- "fmt"
- "text/scanner"
- "unicode"
- "unicode/utf8"
-)
-
-//
----------------------------------------------------------------------------
-// Error handling
-
-type errorList []error
-
-func (list errorList) Err() error {
- if len(list) == 0 {
- return nil
- }
- return list
-}
-
-func (list errorList) Error() string {
- switch len(list) {
- case 0:
- return "no errors"
- case 1:
- return list[0].Error()
- }
- return fmt.Sprintf("%s (and %d more errors)", list[0], len(list)-1)
-}
-
-func newError(pos scanner.Position, msg string) error {
- return errors.New(fmt.Sprintf("%s: %s", pos, msg))
-}
-
-//
----------------------------------------------------------------------------
-// Internal representation
-
-type (
- // An Expression node represents a production expression.
- Expression interface {
- // Pos is the position of the first character of the syntactic construct
- Pos() scanner.Position
- }
-
- // An Alternative node represents a non-empty list of alternative
expressions.
- Alternative []Expression // x | y | z
-
- // A Sequence node represents a non-empty list of sequential expressions.
- Sequence []Expression // x y z
-
- // A Name node represents a production name.
- Name struct {
- StringPos scanner.Position
- String string
- }
-
- // A Token node represents a literal.
- Token struct {
- StringPos scanner.Position
- String string
- }
-
- // A List node represents a range of characters.
- Range struct {
- Begin, End *Token // begin ... end
- }
-
- // A Group node represents a grouped expression.
- Group struct {
- Lparen scanner.Position
- Body Expression // (body)
- }
-
- // An Option node represents an optional expression.
- Option struct {
- Lbrack scanner.Position
- Body Expression // [body]
- }
-
- // A Repetition node represents a repeated expression.
- Repetition struct {
- Lbrace scanner.Position
- Body Expression // {body}
- }
-
- // A Production node represents an EBNF production.
- Production struct {
- Name *Name
- Expr Expression
- }
-
- // A Bad node stands for pieces of source code that lead to a parse error.
- Bad struct {
- TokPos scanner.Position
- Error string // parser error message
- }
-
- // A Grammar is a set of EBNF productions. The map
- // is indexed by production name.
- //
- Grammar map[string]*Production
-)
-
-func (x Alternative) Pos() scanner.Position { return x[0].Pos() } // the
parser always generates non-empty Alternative
-func (x Sequence) Pos() scanner.Position { return x[0].Pos() } // the
parser always generates non-empty Sequences
-func (x *Name) Pos() scanner.Position { return x.StringPos }
-func (x *Token) Pos() scanner.Position { return x.StringPos }
-func (x *Range) Pos() scanner.Position { return x.Begin.Pos() }
-func (x *Group) Pos() scanner.Position { return x.Lparen }
-func (x *Option) Pos() scanner.Position { return x.Lbrack }
-func (x *Repetition) Pos() scanner.Position { return x.Lbrace }
-func (x *Production) Pos() scanner.Position { return x.Name.Pos() }
-func (x *Bad) Pos() scanner.Position { return x.TokPos }
-
-//
----------------------------------------------------------------------------
-// Grammar verification
-
-func isLexical(name string) bool {
- ch, _ := utf8.DecodeRuneInString(name)
- return !unicode.IsUpper(ch)
-}
-
-type verifier struct {
- errors errorList
- worklist []*Production
- reached Grammar // set of productions reached from (and including) the
root production
- grammar Grammar
-}
-
-func (v *verifier) error(pos scanner.Position, msg string) {
- v.errors = append(v.errors, newError(pos, msg))
-}
-
-func (v *verifier) push(prod *Production) {
- name := prod.Name.String
- if _, found := v.reached[name]; !found {
- v.worklist = append(v.worklist, prod)
- v.reached[name] = prod
- }
-}
-
-func (v *verifier) verifyChar(x *Token) rune {
- s := x.String
- if utf8.RuneCountInString(s) != 1 {
- v.error(x.Pos(), "single char expected, found "+s)
- return 0
- }
- ch, _ := utf8.DecodeRuneInString(s)
- return ch
-}
-
-func (v *verifier) verifyExpr(expr Expression, lexical bool) {
- switch x := expr.(type) {
- case nil:
- // empty expression
- case Alternative:
- for _, e := range x {
- v.verifyExpr(e, lexical)
- }
- case Sequence:
- for _, e := range x {
- v.verifyExpr(e, lexical)
- }
- case *Name:
- // a production with this name must exist;
- // add it to the worklist if not yet processed
- if prod, found := v.grammar[x.String]; found {
- v.push(prod)
- } else {
- v.error(x.Pos(), "missing production "+x.String)
- }
- // within a lexical production references
- // to non-lexical productions are invalid
- if lexical && !isLexical(x.String) {
- v.error(x.Pos(), "reference to non-lexical production "+x.String)
- }
- case *Token:
- // nothing to do for now
- case *Range:
- i := v.verifyChar(x.Begin)
- j := v.verifyChar(x.End)
- if i >= j {
- v.error(x.Pos(), "decreasing character range")
- }
- case *Group:
- v.verifyExpr(x.Body, lexical)
- case *Option:
- v.verifyExpr(x.Body, lexical)
- case *Repetition:
- v.verifyExpr(x.Body, lexical)
- case *Bad:
- v.error(x.Pos(), x.Error)
- default:
- panic(fmt.Sprintf("internal error: unexpected type %T", expr))
- }
-}
-
-func (v *verifier) verify(grammar Grammar, start string) {
- // find root production
- root, found := grammar[start]
- if !found {
- var noPos scanner.Position
- v.error(noPos, "no start production "+start)
- return
- }
-
- // initialize verifier
- v.worklist = v.worklist[0:0]
- v.reached = make(Grammar)
- v.grammar = grammar
-
- // work through the worklist
- v.push(root)
- for {
- n := len(v.worklist) - 1
- if n < 0 {
- break
- }
- prod := v.worklist[n]
- v.worklist = v.worklist[0:n]
- v.verifyExpr(prod.Expr, isLexical(prod.Name.String))
- }
-
- // check if all productions were reached
- if len(v.reached) < len(v.grammar) {
- for name, prod := range v.grammar {
- if _, found := v.reached[name]; !found {
- v.error(prod.Pos(), name+" is unreachable")
- }
- }
- }
-}
-
-// Verify checks that:
-// - all productions used are defined
-// - all productions defined are used when beginning at start
-// - lexical productions refer only to other lexical productions
-//
-// Position information is interpreted relative to the file set fset.
-//
-func Verify(grammar Grammar, start string) error {
- var v verifier
- v.verify(grammar, start)
- return v.errors.Err()
-}
=======================================
--- /src/pkg/exp/ebnf/ebnf_test.go Tue Oct 11 17:43:10 2011
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ebnf
-
-import (
- "bytes"
- "testing"
-)
-
-var goodGrammars = []string{
- `Program = .`,
-
- `Program = foo .
- foo = "foo" .`,
-
- `Program = "a" | "b" "c" .`,
-
- `Program = "a" … "z" .`,
-
- `Program = Song .
- Song = { Note } .
- Note = Do | (Re | Mi | Fa | So | La) | Ti .
- Do = "c" .
- Re = "d" .
- Mi = "e" .
- Fa = "f" .
- So = "g" .
- La = "a" .
- Ti = ti .
- ti = "b" .`,
-}
-
-var badGrammars = []string{
- `Program = | .`,
- `Program = | b .`,
- `Program = a … b .`,
- `Program = "a" … .`,
- `Program = … "b" .`,
- `Program = () .`,
- `Program = [] .`,
- `Program = {} .`,
-}
-
-func checkGood(t *testing.T, src string) {
- grammar, err := Parse("", bytes.NewBuffer([]byte(src)))
- if err != nil {
- t.Errorf("Parse(%s) failed: %v", src, err)
- return
- }
- if err = Verify(grammar, "Program"); err != nil {
- t.Errorf("Verify(%s) failed: %v", src, err)
- }
-}
-
-func checkBad(t *testing.T, src string) {
- _, err := Parse("", bytes.NewBuffer([]byte(src)))
- if err == nil {
- t.Errorf("Parse(%s) should have failed", src)
- }
-}
-
-func TestGrammars(t *testing.T) {
- for _, src := range goodGrammars {
- checkGood(t, src)
- }
- for _, src := range badGrammars {
- checkBad(t, src)
- }
-}
=======================================
--- /src/pkg/exp/ebnf/parser.go Tue Nov 8 15:40:58 2011
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ebnf
-
-import (
- "io"
- "strconv"
- "text/scanner"
-)
-
-type parser struct {
- errors errorList
- scanner scanner.Scanner
- pos scanner.Position // token position
- tok rune // one token look-ahead
- lit string // token literal
-}
-
-func (p *parser) next() {
- p.tok = p.scanner.Scan()
- p.pos = p.scanner.Position
- p.lit = p.scanner.TokenText()
-}
-
-func (p *parser) error(pos scanner.Position, msg string) {
- p.errors = append(p.errors, newError(pos, msg))
-}
-
-func (p *parser) errorExpected(pos scanner.Position, msg string) {
- msg = `expected "` + msg + `"`
- if pos.Offset == p.pos.Offset {
- // the error happened at the current position;
- // make the error message more specific
- msg += ", found " + scanner.TokenString(p.tok)
- if p.tok < 0 {
- msg += " " + p.lit
- }
- }
- p.error(pos, msg)
-}
-
-func (p *parser) expect(tok rune) scanner.Position {
- pos := p.pos
- if p.tok != tok {
- p.errorExpected(pos, scanner.TokenString(tok))
- }
- p.next() // make progress in any case
- return pos
-}
-
-func (p *parser) parseIdentifier() *Name {
- pos := p.pos
- name := p.lit
- p.expect(scanner.Ident)
- return &Name{pos, name}
-}
-
-func (p *parser) parseToken() *Token {
- pos := p.pos
- value := ""
- if p.tok == scanner.String {
- value, _ = strconv.Unquote(p.lit)
- // Unquote may fail with an error, but only if the scanner found
- // an illegal string in the first place. In this case the error
- // has already been reported.
- p.next()
- } else {
- p.expect(scanner.String)
- }
- return &Token{pos, value}
-}
-
-// ParseTerm returns nil if no term was found.
-func (p *parser) parseTerm() (x Expression) {
- pos := p.pos
-
- switch p.tok {
- case scanner.Ident:
- x = p.parseIdentifier()
-
- case scanner.String:
- tok := p.parseToken()
- x = tok
- const ellipsis = '…' // U+2026, the horizontal ellipsis character
- if p.tok == ellipsis {
- p.next()
- x = &Range{tok, p.parseToken()}
- }
-
- case '(':
- p.next()
- x = &Group{pos, p.parseExpression()}
- p.expect(')')
-
- case '[':
- p.next()
- x = &Option{pos, p.parseExpression()}
- p.expect(']')
-
- case '{':
- p.next()
- x = &Repetition{pos, p.parseExpression()}
- p.expect('}')
- }
-
- return x
-}
-
-func (p *parser) parseSequence() Expression {
- var list Sequence
-
- for x := p.parseTerm(); x != nil; x = p.parseTerm() {
- list = append(list, x)
- }
-
- // no need for a sequence if list.Len() < 2
- switch len(list) {
- case 0:
- p.errorExpected(p.pos, "term")
- return &Bad{p.pos, "term expected"}
- case 1:
- return list[0]
- }
-
- return list
-}
-
-func (p *parser) parseExpression() Expression {
- var list Alternative
-
- for {
- list = append(list, p.parseSequence())
- if p.tok != '|' {
- break
- }
- p.next()
- }
- // len(list) > 0
-
- // no need for an Alternative node if list.Len() < 2
- if len(list) == 1 {
- return list[0]
- }
-
- return list
-}
-
-func (p *parser) parseProduction() *Production {
- name := p.parseIdentifier()
- p.expect('=')
- var expr Expression
- if p.tok != '.' {
- expr = p.parseExpression()
- }
- p.expect('.')
- return &Production{name, expr}
-}
-
-func (p *parser) parse(filename string, src io.Reader) Grammar {
- p.scanner.Init(src)
- p.scanner.Filename = filename
- p.next() // initializes pos, tok, lit
-
- grammar := make(Grammar)
- for p.tok != scanner.EOF {
- prod := p.parseProduction()
- name := prod.Name.String
- if _, found := grammar[name]; !found {
- grammar[name] = prod
- } else {
- p.error(prod.Pos(), name+" declared already")
- }
- }
-
- return grammar
-}
-
-// Parse parses a set of EBNF productions from source src.
-// It returns a set of productions. Errors are reported
-// for incorrect syntax and if a production is declared
-// more than once; the filename is used only for error
-// positions.
-//
-func Parse(filename string, src io.Reader) (Grammar, error) {
- var p parser
- grammar := p.parse(filename, src)
- return grammar, p.errors.Err()
-}
=======================================
--- /src/pkg/exp/ebnflint/doc.go Tue Feb 19 11:19:58 2013
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-
-Ebnflint verifies that EBNF productions are consistent and grammatically
correct.
-It reads them from an HTML document such as the Go specification.
-
-Grammar productions are grouped in boxes demarcated by the HTML elements
- <pre class="ebnf">
- </pre>
-
-
-Usage:
- go tool ebnflint [--start production] [file]
-
-The --start flag specifies the name of the start production for
-the grammar; it defaults to "Start".
-
-*/
-package main
=======================================
--- /src/pkg/exp/ebnflint/ebnflint.go Fri Feb 3 12:03:20 2012
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "bytes"
- "exp/ebnf"
- "flag"
- "fmt"
- "go/scanner"
- "go/token"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
-)
-
-var fset = token.NewFileSet()
-var start = flag.String("start", "Start", "name of start production")
-
-func usage() {
- fmt.Fprintf(os.Stderr, "usage: go tool ebnflint [flags] [filename]\n")
- flag.PrintDefaults()
- os.Exit(1)
-}
-
-// Markers around EBNF sections in .html files
-var (
- open = []byte(`<pre class="ebnf">`)
- close = []byte(`</pre>`)
-)
-
-func report(err error) {
- scanner.PrintError(os.Stderr, err)
- os.Exit(1)
-}
-
-func extractEBNF(src []byte) []byte {
- var buf bytes.Buffer
-
- for {
- // i = beginning of EBNF text
- i := bytes.Index(src, open)
- if i < 0 {
- break // no EBNF found - we are done
- }
- i += len(open)
-
- // write as many newlines as found in the excluded text
- // to maintain correct line numbers in error messages
- for _, ch := range src[0:i] {
- if ch == '\n' {
- buf.WriteByte('\n')
- }
- }
-
- // j = end of EBNF text (or end of source)
- j := bytes.Index(src[i:], close) // close marker
- if j < 0 {
- j = len(src) - i
- }
- j += i
-
- // copy EBNF text
- buf.Write(src[i:j])
-
- // advance
- src = src[j:]
- }
-
- return buf.Bytes()
-}
-
-func main() {
- flag.Parse()
-
- var (
- name string
- r io.Reader
- )
- switch flag.NArg() {
- case 0:
- name, r = "<stdin>", os.Stdin
- case 1:
- name = flag.Arg(0)
- default:
- usage()
- }
-
- if err := verify(name, *start, r); err != nil {
- report(err)
- }
-}
-
-func verify(name, start string, r io.Reader) error {
- if r == nil {
- f, err := os.Open(name)
- if err != nil {
- return err
- }
- defer f.Close()
- r = f
- }
-
- src, err := ioutil.ReadAll(r)
- if err != nil {
- return err
- }
-
- if filepath.Ext(name) == ".html" || bytes.Index(src, open) >= 0 {
- src = extractEBNF(src)
- }
-
- grammar, err := ebnf.Parse(name, bytes.NewBuffer(src))
- if err != nil {
- return err
- }
-
- return ebnf.Verify(grammar, start)
-}
=======================================
--- /src/pkg/exp/ebnflint/ebnflint_test.go Mon Jan 23 13:35:25 2012
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "runtime"
- "testing"
-)
-
-func TestSpec(t *testing.T) {
- if err := verify(runtime.GOROOT()+"/doc/go_spec.html", "SourceFile",
nil); err != nil {
- t.Fatal(err)
- }
-}
=======================================
--- /src/pkg/exp/gotype/doc.go Tue Feb 19 11:19:58 2013
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-The gotype command does syntactic and semantic analysis of Go files
-and packages similar to the analysis performed by the front-end of
-a Go compiler. Errors are reported if the analysis fails; otherwise
-gotype is quiet (unless -v is set).
-
-Without a list of paths, gotype processes the standard input, which must
-be the source of a single package file.
-
-Given a list of file names, each file must be a source file belonging to
-the same package unless the package name is explicitly specified with the
--p flag.
-
-Given a directory name, gotype collects all .go files in the directory
-and processes them as if they were provided as an explicit list of file
-names. Each directory is processed independently. Files starting with .
-or not ending in .go are ignored.
-
-Usage:
- gotype [flags] [path ...]
-
-The flags are:
- -e
- Print all (including spurious) errors.
- -p pkgName
- Process only those files in package pkgName.
- -r
- Recursively process subdirectories.
- -v
- Verbose mode.
-
-Debugging flags:
- -comments
- Parse comments (ignored if -ast not set).
- -ast
- Print AST (disables concurrent parsing).
- -trace
- Print parse trace (disables concurrent parsing).
-
-
-Examples
-
-To check the files file.go, old.saved, and .ignored:
-
- gotype file.go old.saved .ignored
-
-To check all .go files belonging to package main in the current directory
-and recursively in all subdirectories:
-
- gotype -p main -r .
-
-To verify the output of a pipe:
-
- echo "package foo" | gotype
-
-*/
-package main
-
-// BUG(gri): At the moment, only single-file scope analysis is performed.
=======================================
--- /src/pkg/exp/gotype/gotype.go Tue Feb 26 14:33:24 2013
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "flag"
- "fmt"
- "go/ast"
- "go/parser"
- "go/scanner"
- "go/token"
- "go/types"
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
-)
-
-var (
- // main operation modes
- pkgName = flag.String("p", "", "process only those files in package
pkgName")
- recursive = flag.Bool("r", false, "recursively process subdirectories")
- verbose = flag.Bool("v", false, "verbose mode")
- allErrors = flag.Bool("e", false, "report all errors (not just the first
10 on different lines)")
-
- // debugging support
- parseComments = flag.Bool("comments", false, "parse comments (ignored if
-ast not set)")
- printTrace = flag.Bool("trace", false, "print parse trace")
- printAST = flag.Bool("ast", false, "print AST")
-)
-
-var errorCount int
-
-func usage() {
- fmt.Fprintf(os.Stderr, "usage: gotype [flags] [path ...]\n")
- flag.PrintDefaults()
- os.Exit(2)
-}
-
-func report(err error) {
- scanner.PrintError(os.Stderr, err)
- if list, ok := err.(scanner.ErrorList); ok {
- errorCount += len(list)
- return
- }
- errorCount++
-}
-
-// parse returns the AST for the Go source src.
-// The filename is for error reporting only.
-// The result is nil if there were errors or if
-// the file does not belong to the -p package.
-func parse(fset *token.FileSet, filename string, src []byte) *ast.File {
- if *verbose {
- fmt.Println(filename)
- }
-
- // ignore files with different package name
- if *pkgName != "" {
- file, err := parser.ParseFile(fset, filename, src,
parser.PackageClauseOnly)
- if err != nil {
- report(err)
- return nil
- }
- if
file.Name.Name != *pkgName {
- if *verbose {
- fmt.Printf("\tignored (package %s)\n",
file.Name.Name)
- }
- return nil
- }
- }
-
- // parse entire file
- mode := parser.DeclarationErrors
- if *allErrors {
- mode |= parser.AllErrors
- }
- if *parseComments && *printAST {
- mode |= parser.ParseComments
- }
- if *printTrace {
- mode |= parser.Trace
- }
- file, err := parser.ParseFile(fset, filename, src, mode)
- if err != nil {
- report(err)
- return nil
- }
- if *printAST {
- ast.Print(fset, file)
- }
-
- return file
-}
-
-func parseStdin(fset *token.FileSet) (files []*ast.File) {
- src, err := ioutil.ReadAll(os.Stdin)
- if err != nil {
- report(err)
- return
- }
- const filename = "<standard input>"
- if file := parse(fset, filename, src); file != nil {
- files = []*ast.File{file}
- }
- return
-}
-
-func parseFiles(fset *token.FileSet, filenames []string) (files
[]*ast.File) {
- for _, filename := range filenames {
- src, err := ioutil.ReadFile(filename)
- if err != nil {
- report(err)
- continue
- }
- if file := parse(fset, filename, src); file != nil {
- files = append(files, file)
- }
- }
- return
-}
-
-func isGoFilename(filename string) bool {
- // ignore non-Go files
- return !strings.HasPrefix(filename, ".") &&
strings.HasSuffix(filename, ".go")
-}
-
-func processDirectory(dirname string) {
- f, err := os.Open(dirname)
- if err != nil {
- report(err)
- return
- }
- filenames, err := f.Readdirnames(-1)
- f.Close()
- if err != nil {
- report(err)
- // continue since filenames may not be empty
- }
- for i, filename := range filenames {
- filenames[i] = filepath.Join(dirname, filename)
- }
- processFiles(filenames, false)
-}
-
-func processFiles(filenames []string, allFiles bool) {
- i := 0
- for _, filename := range filenames {
- switch info, err := os.Stat(filename); {
- case err != nil:
- report(err)
- case info.IsDir():
- if allFiles || *recursive {
- processDirectory(filename)
- }
- default:
- if allFiles || isGoFilename(info.Name()) {
- filenames[i] = filename
- i++
- }
- }
- }
- fset := token.NewFileSet()
- processPackage(fset, parseFiles(fset, filenames[0:i]))
-}
-
-func processPackage(fset *token.FileSet, files []*ast.File) {
- type bailout struct{}
- ctxt := types.Context{
- Error: func(err error) {
- if !*allErrors && errorCount >= 10 {
- panic(bailout{})
- }
- report(err)
- },
- }
-
- defer func() {
- switch err := recover().(type) {
- case nil, bailout:
- default:
- panic(err)
- }
- }()
-
- ctxt.Check(fset, files)
-}
-
-func main() {
- flag.Usage = usage
- flag.Parse()
-
- if flag.NArg() == 0 {
- fset := token.NewFileSet()
- processPackage(fset, parseStdin(fset))
- } else {
- processFiles(flag.Args(), true)
- }
-
- if errorCount > 0 {
- os.Exit(2)
- }
-}
=======================================
--- /src/pkg/exp/gotype/gotype_test.go Thu Feb 28 15:27:52 2013
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "go/build"
- "path/filepath"
- "runtime"
- "strings"
- "testing"
-)
-
-func runTest(t *testing.T, path string) {
- errorCount = 0
-
- *recursive = false
- *allErrors = true
- if suffix := ".go"; strings.HasSuffix(path, suffix) {
- // single file
- path = filepath.Join(runtime.GOROOT(), "src/pkg", path)
- path, file := filepath.Split(path)
- *pkgName = file[:len(file)-len(suffix)]
- processFiles([]string{path}, true)
- } else {
- // package directory
- // TODO(gri) gotype should use the build package instead
- ctxt := build.Default
- ctxt.CgoEnabled = false
- pkg, err := ctxt.Import(path, "", 0)
- if err != nil {
- t.Errorf("build.Import error for path = %s: %s", path, err)
- return
- }
- // TODO(gri) there ought to be a more direct way using the build
package...
- files := make([]string, len(pkg.GoFiles))
- for i, file := range pkg.GoFiles {
- files[i] = filepath.Join(pkg.Dir, file)
- }
- *pkgName = pkg.Name
- processFiles(files, true)
- }
-
- if errorCount > 0 {
- t.Errorf("processing %s failed: %d errors", path, errorCount)
- }
-}
-
-var tests = []string{
- // individual files
- "exp/gotype/testdata/test1.go",
-
- // directories
- // Note: Packages that don't typecheck yet are commented out.
- // Unless there is a comment next to the commented out packages,
- // the package doesn't typecheck due to errors in the shift
- // expression checker.
- "archive/tar",
- "archive/zip",
-
- "bufio",
- "bytes",
-
- "compress/bzip2",
- "compress/flate",
- "compress/gzip",
- "compress/lzw",
- "compress/zlib",
-
- "container/heap",
- "container/list",
- "container/ring",
-
- "crypto",
- "crypto/aes",
- "crypto/cipher",
- "crypto/des",
- "crypto/dsa",
- "crypto/ecdsa",
- "crypto/elliptic",
- "crypto/hmac",
- "crypto/md5",
- "crypto/rand",
- "crypto/rc4",
- "crypto/rsa",
- "crypto/sha1",
- "crypto/sha256",
- "crypto/sha512",
- "crypto/subtle",
- "crypto/tls",
- "crypto/x509",
- "crypto/x509/pkix",
-
- "database/sql",
- "database/sql/driver",
-
- "debug/dwarf",
- "debug/elf",
- "debug/gosym",
- "debug/macho",
- "debug/pe",
-
- "encoding/ascii85",
- "encoding/asn1",
- "encoding/base32",
- "encoding/base64",
- "encoding/binary",
- "encoding/csv",
- "encoding/gob",
- "encoding/hex",
- "encoding/json",
- "encoding/pem",
- "encoding/xml",
-
- "errors",
- "expvar",
- "flag",
- "fmt",
-
- "exp/gotype",
-
- "go/ast",
- "go/build",
- "go/doc",
- "go/format",
- "go/parser",
- "go/printer",
- "go/scanner",
- "go/token",
- "go/types",
-
- "hash/adler32",
- "hash/crc32",
- "hash/crc64",
- "hash/fnv",
-
- "image",
- "image/color",
- "image/draw",
- "image/gif",
- "image/jpeg",
- "image/png",
-
- "index/suffixarray",
-
- "io",
- "io/ioutil",
-
- "log",
- "log/syslog",
-
- "math",
- "math/big",
- "math/cmplx",
- "math/rand",
-
- "mime",
- "mime/multipart",
-
- "net",
- "net/http",
- "net/http/cgi",
- "net/http/fcgi",
- "net/http/httptest",
- "net/http/httputil",
- "net/http/pprof",
- "net/mail",
- "net/rpc",
- "net/rpc/jsonrpc",
- "net/smtp",
- "net/textproto",
- "net/url",
-
- "path",
- "path/filepath",
-
- "reflect",
-
- "regexp",
- "regexp/syntax",
-
- "runtime",
- "runtime/cgo",
- "runtime/debug",
- "runtime/pprof",
-
- "sort",
- "strconv",
- "strings",
-
- "sync",
- "sync/atomic",
-
- "syscall",
-
- "testing",
- "testing/iotest",
- "testing/quick",
-
- "text/scanner",
- "text/tabwriter",
- "text/template",
- "text/template/parse",
-
- "time",
- "unicode",
- "unicode/utf16",
- "unicode/utf8",
-}
-
-func Test(t *testing.T) {
- for _, test := range tests {
- runTest(t, test)
- }
-}
=======================================
--- /src/pkg/exp/gotype/testdata/test1.go Thu Dec 6 09:23:13 2012
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package test1
-
-func _() {
- // the scope of a local type declaration starts immediately after the
type name
- type T struct{ _ *T }
-}
-
-func _(x interface{}) {
- // the variable defined by a TypeSwitchGuard is declared in each
TypeCaseClause
- switch t := x.(type) {
- case int:
- _ = t
- case float32:
- _ = t
- default:
- _ = t
- }
-
- // the variable defined by a TypeSwitchGuard must not conflict with other
- // variables declared in the initial simple statement
- switch t := 0; t := x.(type) {
- }
-}
=======================================
--- /src/pkg/exp/inotify/inotify_linux.go Tue Feb 5 06:11:10 2013
+++ /dev/null
@@ -1,300 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-Package inotify implements a wrapper for the Linux inotify system.
-
-Example:
- watcher, err := inotify.NewWatcher()
- if err != nil {
- log.Fatal(err)
- }
- err = watcher.Watch("/tmp")
- if err != nil {
- log.Fatal(err)
- }
- for {
- select {
- case ev := <-watcher.Event:
- log.Println("event:", ev)
- case err := <-watcher.Error:
- log.Println("error:", err)
- }
- }
-
-*/
-package inotify
-
-import (
- "errors"
- "fmt"
- "os"
- "strings"
- "sync"
- "syscall"
- "unsafe"
-)
-
-type Event struct {
- Mask uint32 // Mask of events
- Cookie uint32 // Unique cookie associating related events (for rename(2))
- Name string // File name (optional)
-}
-
-type watch struct {
- wd uint32 // Watch descriptor (as returned by the inotify_add_watch()
syscall)
- flags uint32 // inotify flags of this watch (see inotify(7) for the list
of valid flags)
-}
-
-type Watcher struct {
- mu sync.Mutex
- fd int // File descriptor (as returned by the
inotify_init() syscall)
- watches map[string]*watch // Map of inotify watches (key: path)
- paths map[int]string // Map of watched paths (key: watch descriptor)
- Error chan error // Errors are sent on this channel
- Event chan *Event // Events are returned on this channel
- done chan bool // Channel for sending a "quit message" to the
reader goroutine
- isClosed bool // Set to true when Close() is first called
-}
-
-// NewWatcher creates and returns a new inotify instance using
inotify_init(2)
-func NewWatcher() (*Watcher, error) {
- fd, errno := syscall.InotifyInit()
- if fd == -1 {
- return nil, os.NewSyscallError("inotify_init", errno)
- }
- w := &Watcher{
- fd: fd,
- watches: make(map[string]*watch),
- paths: make(map[int]string),
- Event: make(chan *Event),
- Error: make(chan error),
- done: make(chan bool, 1),
- }
-
- go w.readEvents()
- return w, nil
-}
-
-// Close closes an inotify watcher instance
-// It sends a message to the reader goroutine to quit and removes all
watches
-// associated with the inotify instance
-func (w *Watcher) Close() error {
- if w.isClosed {
- return nil
- }
- w.isClosed = true
-
- // Send "quit" message to the reader goroutine
- w.done <- true
- for path := range w.watches {
- w.RemoveWatch(path)
- }
-
- return nil
-}
-
-// AddWatch adds path to the watched file set.
-// The flags are interpreted as described in inotify_add_watch(2).
-func (w *Watcher) AddWatch(path string, flags uint32) error {
- if w.isClosed {
- return errors.New("inotify instance already closed")
- }
-
- watchEntry, found := w.watches[path]
- if found {
- watchEntry.flags |= flags
- flags |= syscall.IN_MASK_ADD
- }
-
- w.mu.Lock() // synchronize with readEvents goroutine
-
- wd, err := syscall.InotifyAddWatch(w.fd, path, flags)
- if err != nil {
- w.mu.Unlock()
- return &os.PathError{
- Op: "inotify_add_watch",
- Path: path,
- Err: err,
- }
- }
-
- if !found {
- w.watches[path] = &watch{wd: uint32(wd), flags: flags}
- w.paths[wd] = path
- }
- w.mu.Unlock()
- return nil
-}
-
-// Watch adds path to the watched file set, watching all events.
-func (w *Watcher) Watch(path string) error {
- return w.AddWatch(path, IN_ALL_EVENTS)
-}
-
-// RemoveWatch removes path from the watched file set.
-func (w *Watcher) RemoveWatch(path string) error {
- watch, ok := w.watches[path]
- if !ok {
- return errors.New(fmt.Sprintf("can't remove non-existent inotify watch
for: %s", path))
- }
- success, errno := syscall.InotifyRmWatch(w.fd, watch.wd)
- if success == -1 {
- return os.NewSyscallError("inotify_rm_watch", errno)
- }
- delete(w.watches, path)
- return nil
-}
-
-// readEvents reads from the inotify file descriptor, converts the
-// received events into Event objects and sends them via the Event channel
-func (w *Watcher) readEvents() {
- var buf [syscall.SizeofInotifyEvent * 4096]byte
-
- for {
- n, err := syscall.Read(w.fd, buf[:])
- // See if there is a message on the "done" channel
- var done bool
- select {
- case done = <-w.done:
- default:
- }
-
- // If EOF or a "done" message is received
- if n == 0 || done {
- // The syscall.Close can be slow. Close
- // w.Event first.
- close(w.Event)
- err := syscall.Close(w.fd)
- if err != nil {
- w.Error <- os.NewSyscallError("close", err)
- }
- close(w.Error)
- return
- }
- if n < 0 {
- w.Error <- os.NewSyscallError("read", err)
- continue
- }
- if n < syscall.SizeofInotifyEvent {
- w.Error <- errors.New("inotify: short read in readEvents()")
- continue
- }
-
- var offset uint32 = 0
- // We don't know how many events we just read into the buffer
- // While the offset points to at least one whole event...
- for offset <= uint32(n-syscall.SizeofInotifyEvent) {
- // Point "raw" to the event in the buffer
- raw := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset]))
- event := new(Event)
- event.Mask = uint32(raw.Mask)
- event.Cookie = uint32(raw.Cookie)
- nameLen := uint32(raw.Len)
- // If the event happened to the watched directory or the watched file,
the kernel
- // doesn't append the filename to the event, but we would like to
always fill the
- // the "Name" field with a valid filename. We retrieve the path of the
watch from
- // the "paths" map.
- w.mu.Lock()
- event.Name = w.paths[int(raw.Wd)]
- w.mu.Unlock()
- if nameLen > 0 {
- // Point "bytes" at the first byte of the filename
- bytes :=
(*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent]))
- // The filename is padded with NUL bytes. TrimRight() gets rid of
those.
- event.Name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000")
- }
- // Send the event on the events channel
- w.Event <- event
-
- // Move to the next event in the buffer
- offset += syscall.SizeofInotifyEvent + nameLen
- }
- }
-}
-
-// String formats the event e in the form
-// "filename: 0xEventMask = IN_ACCESS|IN_ATTRIB_|..."
-func (e *Event) String() string {
- var events string = ""
-
- m := e.Mask
- for _, b := range eventBits {
- if m&b.Value != 0 {
- m &^= b.Value
- events += "|" + b.Name
- }
- }
-
- if m != 0 {
- events += fmt.Sprintf("|%#x", m)
- }
- if len(events) > 0 {
- events = " == " + events[1:]
- }
-
- return fmt.Sprintf("%q: %#x%s", e.Name, e.Mask, events)
-}
-
-const (
- // Options for inotify_init() are not exported
- // IN_CLOEXEC uint32 = syscall.IN_CLOEXEC
- // IN_NONBLOCK uint32 = syscall.IN_NONBLOCK
-
- // Options for AddWatch
- IN_DONT_FOLLOW uint32 = syscall.IN_DONT_FOLLOW
- IN_ONESHOT uint32 = syscall.IN_ONESHOT
- IN_ONLYDIR uint32 = syscall.IN_ONLYDIR
-
- // The "IN_MASK_ADD" option is not exported, as AddWatch
- // adds it automatically, if there is already a watch for the given path
- // IN_MASK_ADD uint32 = syscall.IN_MASK_ADD
-
- // Events
- IN_ACCESS uint32 = syscall.IN_ACCESS
- IN_ALL_EVENTS uint32 = syscall.IN_ALL_EVENTS
- IN_ATTRIB uint32 = syscall.IN_ATTRIB
- IN_CLOSE uint32 = syscall.IN_CLOSE
- IN_CLOSE_NOWRITE uint32 = syscall.IN_CLOSE_NOWRITE
- IN_CLOSE_WRITE uint32 = syscall.IN_CLOSE_WRITE
- IN_CREATE uint32 = syscall.IN_CREATE
- IN_DELETE uint32 = syscall.IN_DELETE
- IN_DELETE_SELF uint32 = syscall.IN_DELETE_SELF
- IN_MODIFY uint32 = syscall.IN_MODIFY
- IN_MOVE uint32 = syscall.IN_MOVE
- IN_MOVED_FROM uint32 = syscall.IN_MOVED_FROM
- IN_MOVED_TO uint32 = syscall.IN_MOVED_TO
- IN_MOVE_SELF uint32 = syscall.IN_MOVE_SELF
- IN_OPEN uint32 = syscall.IN_OPEN
-
- // Special events
- IN_ISDIR uint32 = syscall.IN_ISDIR
- IN_IGNORED uint32 = syscall.IN_IGNORED
- IN_Q_OVERFLOW uint32 = syscall.IN_Q_OVERFLOW
- IN_UNMOUNT uint32 = syscall.IN_UNMOUNT
-)
-
-var eventBits = []struct {
- Value uint32
- Name string
-}{
- {IN_ACCESS, "IN_ACCESS"},
- {IN_ATTRIB, "IN_ATTRIB"},
- {IN_CLOSE, "IN_CLOSE"},
- {IN_CLOSE_NOWRITE, "IN_CLOSE_NOWRITE"},
- {IN_CLOSE_WRITE, "IN_CLOSE_WRITE"},
- {IN_CREATE, "IN_CREATE"},
- {IN_DELETE, "IN_DELETE"},
- {IN_DELETE_SELF, "IN_DELETE_SELF"},
- {IN_MODIFY, "IN_MODIFY"},
- {IN_MOVE, "IN_MOVE"},
- {IN_MOVED_FROM, "IN_MOVED_FROM"},
- {IN_MOVED_TO, "IN_MOVED_TO"},
- {IN_MOVE_SELF, "IN_MOVE_SELF"},
- {IN_OPEN, "IN_OPEN"},
- {IN_ISDIR, "IN_ISDIR"},
- {IN_IGNORED, "IN_IGNORED"},
- {IN_Q_OVERFLOW, "IN_Q_OVERFLOW"},
- {IN_UNMOUNT, "IN_UNMOUNT"},
-}
=======================================
--- /src/pkg/exp/inotify/inotify_linux_test.go Sun Jun 24 16:22:48 2012
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build linux
-
-package inotify
-
-import (
- "io/ioutil"
- "os"
- "sync/atomic"
- "testing"
- "time"
-)
-
-func TestInotifyEvents(t *testing.T) {
- // Create an inotify watcher instance and initialize it
- watcher, err := NewWatcher()
- if err != nil {
- t.Fatalf("NewWatcher failed: %s", err)
- }
-
- dir, err := ioutil.TempDir("", "inotify")
- if err != nil {
- t.Fatalf("TempDir failed: %s", err)
- }
- defer os.RemoveAll(dir)
-
- // Add a watch for "_test"
- err = watcher.Watch(dir)
- if err != nil {
- t.Fatalf("Watch failed: %s", err)
- }
-
- // Receive errors on the error channel on a separate goroutine
- go func() {
- for err := range watcher.Error {
- t.Fatalf("error received: %s", err)
- }
- }()
-
- testFile := dir + "/TestInotifyEvents.testfile"
-
- // Receive events on the event channel on a separate goroutine
- eventstream := watcher.Event
- var eventsReceived int32 = 0
- done := make(chan bool)
- go func() {
- for event := range eventstream {
- // Only count relevant events
- if event.Name == testFile {
- atomic.AddInt32(&eventsReceived, 1)
- t.Logf("event received: %s", event)
- } else {
- t.Logf("unexpected event received: %s", event)
- }
- }
- done <- true
- }()
-
- // Create a file
- // This should add at least one event to the inotify event queue
- _, err = os.OpenFile(testFile, os.O_WRONLY|os.O_CREATE, 0666)
- if err != nil {
- t.Fatalf("creating test file: %s", err)
- }
-
- // We expect this event to be received almost immediately, but let's wait
1 s to be sure
- time.Sleep(1 * time.Second)
- if atomic.AddInt32(&eventsReceived, 0) == 0 {
- t.Fatal("inotify event hasn't been received after 1 second")
- }
-
- // Try closing the inotify instance
- t.Log("calling Close()")
- watcher.Close()
- t.Log("waiting for the event channel to become closed...")
- select {
- case <-done:
- t.Log("event channel closed")
- case <-time.After(1 * time.Second):
- t.Fatal("event stream was not closed after 1 second")
- }
-}
-
-func TestInotifyClose(t *testing.T) {
- watcher, _ := NewWatcher()
- watcher.Close()
-
- done := make(chan bool)
- go func() {
- watcher.Close()
- done <- true
- }()
-
- select {
- case <-done:
- case <-time.After(50 * time.Millisecond):
- t.Fatal("double Close() test failed: second Close() call didn't return")
- }
-
- err := watcher.Watch(os.TempDir())
- if err == nil {
- t.Fatal("expected error on Watch() after Close(), got nil")
- }
-}
=======================================
--- /src/pkg/exp/locale/collate/Makefile Sun Oct 7 17:59:33 2012
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2012 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-CLEANFILES+=maketables
-
-maketables: maketables.go
- go build $^
-
-tables: maketables
- ./maketables > tables.go
- gofmt -w -s tables.go
-
-# Build (but do not run) maketables during testing,
-# just to make sure it still compiles.
-testshort: maketables
=======================================
--- /src/pkg/exp/locale/collate/build/builder.go Tue Feb 12 06:59:55 2013
+++ /dev/null
@@ -1,690 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package build
-
-import (
- "exp/locale/collate/colltab"
- "exp/norm"
- "fmt"
- "io"
- "log"
- "sort"
- "strings"
- "unicode/utf8"
-)
-
-// TODO: optimizations:
-// - expandElem is currently 20K. By putting unique colElems in a separate
-// table and having a byte array of indexes into this table, we can
reduce
-// the total size to about 7K. By also factoring out the length bytes, we
-// can reduce this to about 6K.
-// - trie valueBlocks are currently 100K. There are a lot of sparse blocks
-// and many consecutive values with the same stride. This can be further
-// compacted.
-// - Compress secondary weights into 8 bits.
-// - Some LDML specs specify a context element. Currently we simply
concatenate
-// those. Context can be implemented using the contraction trie. If
Builder
-// could analyze and detect when using a context makes sense, there is no
-// need to expose this construct in the API.
-
-// A Builder builds a root collation table. The user must specify the
-// collation elements for each entry. A common use will be to base the
weights
-// on those specified in the allkeys* file as provided by the UCA or CLDR.
-type Builder struct {
- index *trieBuilder
- root ordering
- locale []*Tailoring
- t *table
- err error
- built bool
-
- minNonVar int // lowest primary recorded for a variable
- varTop int // highest primary recorded for a non-variable
-
- // indexes used for reusing expansions and contractions
- expIndex map[string]int // positions of expansions keyed by their
string representation
- ctHandle map[string]ctHandle // contraction handles keyed by a
concatenation of the suffixes
- ctElem map[string]int // contraction elements keyed by their
string representation
-}
-
-// A Tailoring builds a collation table based on another collation table.
-// The table is defined by specifying tailorings to the underlying table.
-// See
http://unicode.org/reports/tr35/ for an overview of tailoring
-// collation tables. The CLDR contains pre-defined tailorings for a
variety
-// of languages (See
http://www.unicode.org/Public/cldr/2.0.1/core.zip.)
-type Tailoring struct {
- id string
- builder *Builder
- index *ordering
-
- anchor *entry
- before bool
-}
-
-// NewBuilder returns a new Builder.
-func NewBuilder() *Builder {
- return &Builder{
- index: newTrieBuilder(),
- root: makeRootOrdering(),
- expIndex: make(map[string]int),
- ctHandle: make(map[string]ctHandle),
- ctElem: make(map[string]int),
- }
-}
-
-// Tailoring returns a Tailoring for the given locale. One should
-// have completed all calls to Add before calling Tailoring.
-func (b *Builder) Tailoring(locale string) *Tailoring {
- t := &Tailoring{
- id: locale,
- builder: b,
- index: b.root.clone(),
- }
-
t.index.id =
t.id
- b.locale = append(b.locale, t)
- return t
-}
-
-// Add adds an entry to the collation element table, mapping
-// a slice of runes to a sequence of collation elements.
-// A collation element is specified as list of weights: []int{primary,
secondary, ...}.
-// The entries are typically obtained from a collation element table
-// as defined in
http://www.unicode.org/reports/tr10/#Data_Table_Format.
-// Note that the collation elements specified by colelems are only used
-// as a guide. The actual weights generated by Builder may differ.
-// The argument variables is a list of indices into colelems that should
contain
-// a value for each colelem that is a variable. (See the reference above.)
-func (b *Builder) Add(runes []rune, colelems [][]int, variables []int)
error {
- str := string(runes)
- elems := make([]rawCE, len(colelems))
- for i, ce := range colelems {
- if len(ce) == 0 {
- break
- }
- elems[i] = makeRawCE(ce, 0)
- if len(ce) == 1 {
- elems[i].w[1] = defaultSecondary
- }
- if len(ce) <= 2 {
- elems[i].w[2] = defaultTertiary
- }
- if len(ce) <= 3 {
- elems[i].w[3] = ce[0]
- }
- }
- for i, ce := range elems {
- p := ce.w[0]
- isvar := false
- for _, j := range variables {
- if i == j {
- isvar = true
- }
- }
- if isvar {
- if p >= b.minNonVar && b.minNonVar > 0 {
- return fmt.Errorf("primary value %X of variable is larger than the
smallest non-variable %X", p, b.minNonVar)
- }
- if p > b.varTop {
- b.varTop = p
- }
- } else if p > 1 { // 1 is a special primary value reserved for FFFE
- if p <= b.varTop {
- return fmt.Errorf("primary value %X of non-variable is smaller than
the highest variable %X", p, b.varTop)
- }
- if b.minNonVar == 0 || p < b.minNonVar {
- b.minNonVar = p
- }
- }
- }
- elems, err := convertLargeWeights(elems)
- if err != nil {
- return err
- }
- cccs := []uint8{}
- nfd := norm.NFD.String(str)
- for i := range nfd {
- cccs = append(cccs, norm.NFD.PropertiesString(nfd[i:]).CCC())
- }
- if len(cccs) < len(elems) {
- if len(cccs) > 2 {
- return fmt.Errorf("number of decomposed characters should be greater or
equal to the number of collation elements for len(colelems) > 3 (%d < %d)",
len(cccs), len(elems))
- }
- p := len(elems) - 1
- for ; p > 0 && elems[p].w[0] == 0; p-- {
- elems[p].ccc = cccs[len(cccs)-1]
- }
- for ; p >= 0; p-- {
- elems[p].ccc = cccs[0]
- }
- } else {
- for i := range elems {
- elems[i].ccc = cccs[i]
- }
- }
- // doNorm in collate.go assumes that the following conditions hold.
- if len(elems) > 1 && len(cccs) > 1 && cccs[0] != 0 && cccs[0] !=
cccs[len(cccs)-1] {
- return fmt.Errorf("incompatible CCC values for expansion %X (%d)",
runes, cccs)
- }
- b.root.newEntry(str, elems)
- return nil
-}
-
-func (t *Tailoring) setAnchor(anchor string) error {
- anchor = norm.NFC.String(anchor)
- a := t.index.find(anchor)
- if a == nil {
- a = t.index.newEntry(anchor, nil)
- a.implicit = true
- a.modified = true
- for _, r := range []rune(anchor) {
- e := t.index.find(string(r))
- e.lock = true
- }
- }
- t.anchor = a
- return nil
-}
-
-// SetAnchor sets the point after which elements passed in subsequent
calls to
-// Insert will be inserted. It is equivalent to the reset directive in an
LDML
-// specification. See Insert for an example.
-// SetAnchor supports the following logical reset positions:
-// <first_tertiary_ignorable/>, <last_teriary_ignorable/>,
<first_primary_ignorable/>,
-// and <last_non_ignorable/>.
-func (t *Tailoring) SetAnchor(anchor string) error {
- if err := t.setAnchor(anchor); err != nil {
- return err
- }
- t.before = false
- return nil
-}
-
-// SetAnchorBefore is similar to SetAnchor, except that subsequent calls to
-// Insert will insert entries before the anchor.
-func (t *Tailoring) SetAnchorBefore(anchor string) error {
- if err := t.setAnchor(anchor); err != nil {
- return err
- }
- t.before = true
- return nil
-}
-
-// Insert sets the ordering of str relative to the entry set by the
previous
-// call to SetAnchor or Insert. The argument extend corresponds
-// to the extend elements as defined in LDML. A non-empty value for extend
-// will cause the collation elements corresponding to extend to be appended
-// to the collation elements generated for the entry added by Insert.
-// This has the same net effect as sorting str after the string
anchor+extend.
-// See
http://www.unicode.org/reports/tr10/#Tailoring_Example for details
-// on parametric tailoring and
http://unicode.org/reports/tr35/#Collation_Elements
-// for full details on LDML.
-//
-// Examples: create a tailoring for Swedish, where "ä" is ordered after "z"
-// at the primary sorting level:
-// t := b.Tailoring("se")
-// t.SetAnchor("z")
-// t.Insert(colltab.Primary, "ä", "")
-// Order "ü" after "ue" at the secondary sorting level:
-// t.SetAnchor("ue")
-// t.Insert(colltab.Secondary, "ü","")
-// or
-// t.SetAnchor("u")
-// t.Insert(colltab.Secondary, "ü", "e")
-// Order "q" afer "ab" at the secondary level and "Q" after "q"
-// at the tertiary level:
-// t.SetAnchor("ab")
-// t.Insert(colltab.Secondary, "q", "")
-// t.Insert(colltab.Tertiary, "Q", "")
-// Order "b" before "a":
-// t.SetAnchorBefore("a")
-// t.Insert(colltab.Primary, "b", "")
-// Order "0" after the last primary ignorable:
-// t.SetAnchor("<last_primary_ignorable/>")
-// t.Insert(colltab.Primary, "0", "")
-func (t *Tailoring) Insert(level colltab.Level, str, extend string) error {
- if t.anchor == nil {
- return fmt.Errorf("%s:Insert: no anchor point set for tailoring of %s",
t.id, str)
- }
- str = norm.NFC.String(str)
- e := t.index.find(str)
- if e == nil {
- e = t.index.newEntry(str, nil)
- } else if e.logical != noAnchor {
- return fmt.Errorf("%s:Insert: cannot reinsert logical reset
position %q",
t.id, e.str)
- }
- if e.lock {
- return fmt.Errorf("%s:Insert: cannot reinsert element %q",
t.id, e.str)
- }
- a := t.anchor
- // Find the first element after the anchor which differs at a level
smaller or
- // equal to the given level. Then insert at this position.
- // See
http://unicode.org/reports/tr35/#Collation_Elements, Section
5.14.5 for details.
- e.before = t.before
- if t.before {
- t.before = false
- if a.prev == nil {
- a.insertBefore(e)
- } else {
- for a = a.prev; a.level > level; a = a.prev {
- }
- a.insertAfter(e)
- }
- e.level = level
- } else {
- for ; a.level > level; a = a.next {
- }
- e.level = a.level
- if a != e {
- a.insertAfter(e)
- a.level = level
- } else {
- // We don't set a to prev itself. This has the effect of the entry
- // getting new collation elements that are an increment of itself.
- // This is intentional.
- a.prev.level = level
- }
- }
- e.extend = norm.NFD.String(extend)
- e.exclude = false
- e.modified = true
- e.elems = nil
- t.anchor = e
- return nil
-}
-
-func (o *ordering) getWeight(e *entry) []rawCE {
- if len(e.elems) == 0 && e.logical == noAnchor {
- if e.implicit {
- for _, r := range e.runes {
- e.elems = append(e.elems, o.getWeight(o.find(string(r)))...)
- }
- } else if e.before {
- count := [colltab.Identity + 1]int{}
- a := e
- for ; a.elems == nil && !a.implicit; a = a.next {
- count[a.level]++
- }
- e.elems = []rawCE{makeRawCE(a.elems[0].w, a.elems[0].ccc)}
- for i := colltab.Primary; i < colltab.Quaternary; i++ {
- if count[i] != 0 {
- e.elems[0].w[i] -= count[i]
- break
- }
- }
- if e.prev != nil {
- o.verifyWeights(e.prev, e, e.prev.level)
- }
- } else {
- prev := e.prev
- e.elems = nextWeight(prev.level, o.getWeight(prev))
- o.verifyWeights(e, e.next, e.level)
- }
- }
- return e.elems
-}
-
-func (o *ordering) addExtension(e *entry) {
- if ex := o.find(e.extend); ex != nil {
- e.elems = append(e.elems, ex.elems...)
- } else {
- for _, r := range []rune(e.extend) {
- e.elems = append(e.elems, o.find(string(r)).elems...)
- }
- }
- e.extend = ""
-}
-
-func (o *ordering) verifyWeights(a, b *entry, level colltab.Level) error {
- if level == colltab.Identity || b == nil || b.elems == nil || a.elems ==
nil {
- return nil
- }
- for i := colltab.Primary; i < level; i++ {
- if a.elems[0].w[i] < b.elems[0].w[i] {
- return nil
- }
- }
- if a.elems[0].w[level] >= b.elems[0].w[level] {
- err := fmt.Errorf("%s:overflow: collation elements of %q (%X) overflows
those of %q (%X) at level %d (%X >= %X)",
o.id, a.str, a.runes, b.str,
b.runes, level, a.elems, b.elems)
- log.Println(err)
- // TODO: return the error instead, or better, fix the conflicting entry
by making room.
- }
- return nil
-}
-
-func (b *Builder) error(e error) {
- if e != nil {
- b.err = e
- }
-}
-
-func (b *Builder) errorID(locale string, e error) {
- if e != nil {
- b.err = fmt.Errorf("%s:%v", locale, e)
- }
-}
-
-// patchNorm ensures that NFC and NFD counterparts are consistent.
-func (o *ordering) patchNorm() {
- // Insert the NFD counterparts, if necessary.
- for _, e := range o.ordered {
- nfd := norm.NFD.String(e.str)
- if nfd != e.str {
- if e0 := o.find(nfd); e0 != nil && !e0.modified {
- e0.elems = e.elems
- } else if e.modified && !equalCEArrays(o.genColElems(nfd), e.elems) {
- e := o.newEntry(nfd, e.elems)
- e.modified = true
- }
- }
- }
- // Update unchanged composed forms if one of their parts changed.
- for _, e := range o.ordered {
- nfd := norm.NFD.String(e.str)
- if e.modified || nfd == e.str {
- continue
- }
- if e0 := o.find(nfd); e0 != nil {
- e.elems = e0.elems
- } else {
- e.elems = o.genColElems(nfd)
- if norm.NFD.LastBoundary([]byte(nfd)) == 0 {
- r := []rune(nfd)
- head := string(r[0])
- tail := ""
- for i := 1; i < len(r); i++ {
- s := norm.NFC.String(head + string(r[i]))
- if e0 := o.find(s); e0 != nil && e0.modified {
- head = s
- } else {
- tail += string(r[i])
- }
- }
- e.elems = append(o.genColElems(head), o.genColElems(tail)...)
- }
- }
- }
- // Exclude entries for which the individual runes generate the same
collation elements.
- for _, e := range o.ordered {
- if len(e.runes) > 1 && equalCEArrays(o.genColElems(e.str), e.elems) {
- e.exclude = true
- }
- }
-}
-
-func (b *Builder) buildOrdering(o *ordering) {
- for _, e := range o.ordered {
- o.getWeight(e)
- }
- for _, e := range o.ordered {
- o.addExtension(e)
- }
- o.patchNorm()
- o.sort()
- simplify(o)
- b.processExpansions(o) // requires simplify
- b.processContractions(o) // requires simplify
-
- t := newNode()
- for e := o.front(); e != nil; e, _ = e.nextIndexed() {
- if !e.skip() {
- ce, err := e.encode()
- b.errorID(
o.id, err)
- t.insert(e.runes[0], ce)
- }
- }
- o.handle = b.index.addTrie(t)
-}
-
-func (b *Builder) build() (*table, error) {
- if b.built {
- return b.t, b.err
- }
- b.built = true
- b.t = &table{
- maxContractLen: utf8.UTFMax,
- variableTop: uint32(b.varTop),
- }
-
- b.buildOrdering(&b.root)
- b.t.root = b.root.handle
- for _, t := range b.locale {
- b.buildOrdering(t.index)
- if b.err != nil {
- break
- }
- }
- i, err := b.index.generate()
- b.t.index = *i
- b.error(err)
- return b.t, b.err
-}
-
-// Build builds the root Collator.
-// TODO: return Weigher instead
-func (b *Builder) Build() (colltab.Weigher, error) {
- t, err := b.build()
- if err != nil {
- return nil, err
- }
- table := colltab.Init(t)
- if table == nil {
- panic("generated table of incompatible type")
- }
- return table, nil
-}
-
-// Build builds a Collator for Tailoring t.
-func (t *Tailoring) Build() (colltab.Weigher, error) {
- // TODO: implement.
- return nil, nil
-}
-
-// Print prints the tables for b and all its Tailorings as a Go file
-// that can be included in the Collate package.
-func (b *Builder) Print(w io.Writer) (n int, err error) {
- p := func(nn int, e error) {
- n += nn
- if err == nil {
- err = e
- }
- }
- t, err := b.build()
- if err != nil {
- return 0, err
- }
- p(fmt.Fprintf(w, "var availableLocales = []string{"))
- for _, loc := range b.locale {
- p(fmt.Fprintf(w, "%q, ",
loc.id))
- }
- p(fmt.Fprintln(w, "}\n"))
- p(fmt.Fprintf(w, "const varTop = 0x%x\n\n", b.varTop))
- p(fmt.Fprintln(w, "var locales = map[string]tableIndex{"))
- for _, loc := range b.locale {
- p(fmt.Fprintf(w, "\t%q: ",
loc.id))
- p(t.fprintIndex(w, loc.index.handle))
- p(fmt.Fprintln(w, ","))
- }
- p(fmt.Fprint(w, "}\n\n"))
- n, _, err = t.fprint(w, "main")
- return
-}
-
-// reproducibleFromNFKD checks whether the given expansion could be
generated
-// from an NFKD expansion.
-func reproducibleFromNFKD(e *entry, exp, nfkd []rawCE) bool {
- // Length must be equal.
- if len(exp) != len(nfkd) {
- return false
- }
- for i, ce := range exp {
- // Primary and secondary values should be equal.
- if ce.w[0] != nfkd[i].w[0] || ce.w[1] != nfkd[i].w[1] {
- return false
- }
- // Tertiary values should be equal to maxTertiary for third element
onwards.
- // TODO: there seem to be a lot of cases in CLDR (e.g. ㏭ in zh.xml)
that can
- // simply be dropped. Try this out by dropping the following code.
- if i >= 2 && ce.w[2] != maxTertiary {
- return false
- }
- if _, err := makeCE(ce); err != nil {
- // Simply return false. The error will be caught elsewhere.
- return false
- }
- }
- return true
-}
-
-func simplify(o *ordering) {
- // Runes that are a starter of a contraction should not be removed.
- // (To date, there is only Kannada character 0CCA.)
- keep := make(map[rune]bool)
- for e := o.front(); e != nil; e, _ = e.nextIndexed() {
- if len(e.runes) > 1 {
- keep[e.runes[0]] = true
- }
- }
- // Tag entries for which the runes NFKD decompose to identical values.
- for e := o.front(); e != nil; e, _ = e.nextIndexed() {
- s := e.str
- nfkd := norm.NFKD.String(s)
- nfd := norm.NFD.String(s)
- if e.decompose || len(e.runes) > 1 || len(e.elems) == 1 ||
keep[e.runes[0]] || nfkd == nfd {
- continue
- }
- if reproducibleFromNFKD(e, e.elems, o.genColElems(nfkd)) {
- e.decompose = true
- }
- }
-}
-
-// appendExpansion converts the given collation sequence to
-// collation elements and adds them to the expansion table.
-// It returns an index to the expansion table.
-func (b *Builder) appendExpansion(e *entry) int {
- t := b.t
- i := len(t.expandElem)
- ce := uint32(len(e.elems))
- t.expandElem = append(t.expandElem, ce)
- for _, w := range e.elems {
- ce, err := makeCE(w)
- if err != nil {
- b.error(err)
- return -1
- }
- t.expandElem = append(t.expandElem, ce)
- }
- return i
-}
-
-// processExpansions extracts data necessary to generate
-// the extraction tables.
-func (b *Builder) processExpansions(o *ordering) {
- for e := o.front(); e != nil; e, _ = e.nextIndexed() {
- if !e.expansion() {
- continue
- }
- key := fmt.Sprintf("%v", e.elems)
- i, ok := b.expIndex[key]
- if !ok {
- i = b.appendExpansion(e)
- b.expIndex[key] = i
- }
- e.expansionIndex = i
- }
-}
-
-func (b *Builder) processContractions(o *ordering) {
- // Collate contractions per starter rune.
- starters := []rune{}
- cm := make(map[rune][]*entry)
- for e := o.front(); e != nil; e, _ = e.nextIndexed() {
- if e.contraction() {
- if len(e.str) > b.t.maxContractLen {
- b.t.maxContractLen = len(e.str)
- }
- r := e.runes[0]
- if _, ok := cm[r]; !ok {
- starters = append(starters, r)
- }
- cm[r] = append(cm[r], e)
- }
- }
- // Add entries of single runes that are at a start of a contraction.
- for e := o.front(); e != nil; e, _ = e.nextIndexed() {
- if !e.contraction() {
- r := e.runes[0]
- if _, ok := cm[r]; ok {
- cm[r] = append(cm[r], e)
- }
- }
- }
- // Build the tries for the contractions.
- t := b.t
- for _, r := range starters {
- l := cm[r]
- // Compute suffix strings. There are 31 different contraction suffix
- // sets for 715 contractions and 82 contraction starter runes as of
- // version 6.0.0.
- sufx := []string{}
- hasSingle := false
- for _, e := range l {
- if len(e.runes) > 1 {
- sufx = append(sufx, string(e.runes[1:]))
- } else {
- hasSingle = true
- }
- }
- if !hasSingle {
- b.error(fmt.Errorf("no single entry for starter rune %U found", r))
- continue
- }
- // Unique the suffix set.
- sort.Strings(sufx)
- key := strings.Join(sufx, "\n")
- handle, ok := b.ctHandle[key]
- if !ok {
- var err error
- handle, err = t.contractTries.appendTrie(sufx)
- if err != nil {
- b.error(err)
- }
- b.ctHandle[key] = handle
- }
- // Bucket sort entries in index order.
- es := make([]*entry, len(l))
- for _, e := range l {
- var p, sn int
- if len(e.runes) > 1 {
- str := []byte(string(e.runes[1:]))
- p, sn = t.contractTries.lookup(handle, str)
- if sn != len(str) {
- log.Fatalf("%s: processContractions: unexpected length for '%X';
len=%d; want %d",
o.id, e.runes, sn, len(str))
- }
- }
- if es[p] != nil {
- log.Fatalf("%s: multiple contractions for position %d for rune %U",
o.id, p, e.runes[0])
- }
- es[p] = e
- }
- // Create collation elements for contractions.
- elems := []uint32{}
- for _, e := range es {
- ce, err := e.encodeBase()
- b.errorID(
o.id, err)
- elems = append(elems, ce)
- }
- key = fmt.Sprintf("%v", elems)
- i, ok := b.ctElem[key]
- if !ok {
- i = len(t.contractElem)
- b.ctElem[key] = i
- t.contractElem = append(t.contractElem, elems...)
- }
- // Store info in entry for starter rune.
- es[0].contractionIndex = i
- es[0].contractionHandle = handle
- }
-}
=======================================
--- /src/pkg/exp/locale/collate/build/builder_test.go Sat Jan 26 15:24:09
2013
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package build
-
-import "testing"
-
-// cjk returns an implicit collation element for a CJK rune.
-func cjk(r rune) []rawCE {
- // A CJK character C is represented in the DUCET as
- // [.AAAA.0020.0002.C][.BBBB.0000.0000.C]
- // Where AAAA is the most significant 15 bits plus a base value.
- // Any base value will work for the test, so we pick the common value of
FB40.
- const base = 0xFB40
- return []rawCE{
- {w: []int{base + int(r>>15), defaultSecondary, defaultTertiary, int(r)}},
- {w: []int{int(r&0x7FFF) | 0x8000, 0, 0, int(r)}},
- }
-}
-
-func pCE(p int) []rawCE {
- return mkCE([]int{p, defaultSecondary, defaultTertiary, 0}, 0)
-}
-
-func pqCE(p, q int) []rawCE {
- return mkCE([]int{p, defaultSecondary, defaultTertiary, q}, 0)
-}
-
-func ptCE(p, t int) []rawCE {
- return mkCE([]int{p, defaultSecondary, t, 0}, 0)
-}
-
-func ptcCE(p, t int, ccc uint8) []rawCE {
- return mkCE([]int{p, defaultSecondary, t, 0}, ccc)
-}
-
-func sCE(s int) []rawCE {
- return mkCE([]int{0, s, defaultTertiary, 0}, 0)
-}
-
-func stCE(s, t int) []rawCE {
- return mkCE([]int{0, s, t, 0}, 0)
-}
-
-func scCE(s int, ccc uint8) []rawCE {
- return mkCE([]int{0, s, defaultTertiary, 0}, ccc)
-}
-
-func mkCE(w []int, ccc uint8) []rawCE {
- return []rawCE{rawCE{w, ccc}}
-}
-
-// ducetElem is used to define test data that is used to generate a table.
-type ducetElem struct {
- str string
- ces []rawCE
-}
-
-func newBuilder(t *testing.T, ducet []ducetElem) *Builder {
- b := NewBuilder()
- for _, e := range ducet {
- ces := [][]int{}
- for _, ce := range e.ces {
- ces = append(ces, ce.w)
- }
- if err := b.Add([]rune(e.str), ces, nil); err != nil {
- t.Errorf(err.Error())
- }
- }
- b.t = &table{}
- b.root.sort()
- return b
-}
-
-type convertTest struct {
- in, out []rawCE
- err bool
-}
-
-var convLargeTests = []convertTest{
- {pCE(0xFB39), pCE(0xFB39), false},
- {cjk(0x2F9B2), pqCE(0x3F9B2, 0x2F9B2), false},
- {pCE(0xFB40), pCE(0), true},
- {append(pCE(0xFB40), pCE(0)[0]), pCE(0), true},
- {pCE(0xFFFE), pCE(illegalOffset), false},
- {pCE(0xFFFF), pCE(illegalOffset + 1), false},
-}
-
-func TestConvertLarge(t *testing.T) {
- for i, tt := range convLargeTests {
- e := new(entry)
- for _, ce := range
tt.in {
- e.elems = append(e.elems, makeRawCE(ce.w, ce.ccc))
- }
- elems, err := convertLargeWeights(e.elems)
- if tt.err {
- if err == nil {
- t.Errorf("%d: expected error; none found", i)
- }
- continue
- } else if err != nil {
- t.Errorf("%d: unexpected error: %v", i, err)
- }
- if !equalCEArrays(elems, tt.out) {
- t.Errorf("%d: conversion was %x; want %x", i, elems, tt.out)
- }
- }
-}
-
-// Collation element table for simplify tests.
-var simplifyTest = []ducetElem{
- {"\u0300", sCE(30)}, // grave
- {"\u030C", sCE(40)}, // caron
- {"A", ptCE(100, 8)},
- {"D", ptCE(104, 8)},
- {"E", ptCE(105, 8)},
- {"I", ptCE(110, 8)},
- {"z", ptCE(130, 8)},
- {"\u05F2", append(ptCE(200, 4), ptCE(200, 4)[0])},
- {"\u05B7", sCE(80)},
- {"\u00C0", append(ptCE(100, 8),
sCE(30)...)}, // A with grave, can be removed
- {"\u00C8", append(ptCE(105, 8),
sCE(30)...)}, // E with grave
- {"\uFB1F", append(ptCE(200, 4), ptCE(200, 4)[0],
sCE(80)[0])}, // eliminated by NFD
- {"\u00C8\u0302", ptCE(106,
8)}, // block previous from
simplifying
- {"\u01C5", append(ptCE(104, 9), ptCE(130, 4)[0], stCE(40,
maxTertiary)[0])}, // eliminated by NFKD
- // no removal: tertiary value of third element is not maxTertiary
- {"\u2162", append(ptCE(110, 9), ptCE(110, 4)[0], ptCE(110, 8)[0])},
-}
-
-var genColTests = []ducetElem{
- {"\uFA70", pqCE(0x1FA70, 0xFA70)},
- {"A\u0300", append(ptCE(100, 8), sCE(30)...)},
- {"A\u0300\uFA70", append(ptCE(100, 8), sCE(30)[0], pqCE(0x1FA70,
0xFA70)[0])},
- {"A\u0300A\u0300", append(ptCE(100, 8), sCE(30)[0], ptCE(100, 8)[0],
sCE(30)[0])},
-}
-
-func TestGenColElems(t *testing.T) {
- b := newBuilder(t, simplifyTest[:5])
-
- for i, tt := range genColTests {
- res := b.root.genColElems(tt.str)
- if !equalCEArrays(tt.ces, res) {
- t.Errorf("%d: result %X; want %X", i, res, tt.ces)
- }
- }
-}
-
-type strArray []string
-
-func (sa strArray) contains(s string) bool {
- for _, e := range sa {
- if e == s {
- return true
- }
- }
- return false
-}
-
-var simplifyRemoved = strArray{"\u00C0", "\uFB1F"}
-var simplifyMarked = strArray{"\u01C5"}
-
-func TestSimplify(t *testing.T) {
- b := newBuilder(t, simplifyTest)
- o := &b.root
- simplify(o)
-
- for i, tt := range simplifyTest {
- if simplifyRemoved.contains(tt.str) {
- continue
- }
- e := o.find(tt.str)
- if e.str != tt.str || !equalCEArrays(e.elems, tt.ces) {
- t.Errorf("%d: found element %s -> %X; want %s -> %X", i, e.str,
e.elems, tt.str, tt.ces)
- break
- }
- }
- var i, k int
- for e := o.front(); e != nil; e, _ = e.nextIndexed() {
- gold := simplifyMarked.contains(e.str)
- if gold {
- k++
- }
- if gold != e.decompose {
- t.Errorf("%d: %s has decompose %v; want %v", i, e.str, e.decompose,
gold)
- }
- i++
- }
- if k != len(simplifyMarked) {
- t.Errorf(" an entry that should be marked as decompose was deleted")
- }
-}
-
-var expandTest = []ducetElem{
- {"\u0300", append(scCE(29, 230), scCE(30, 230)...)},
- {"\u00C0", append(ptCE(100, 8), scCE(30, 230)...)},
- {"\u00C8", append(ptCE(105, 8), scCE(30, 230)...)},
- {"\u00C9", append(ptCE(105, 8), scCE(30, 230)...)}, // identical expansion
- {"\u05F2", append(ptCE(200, 4), ptCE(200, 4)[0], ptCE(200, 4)[0])},
- {"\u01FF", append(ptCE(200, 4), ptcCE(201, 4, 0)[0], scCE(30, 230)[0])},
-}
-
-func TestExpand(t *testing.T) {
- const (
- totalExpansions = 5
- totalElements = 2 + 2 + 2 + 3 + 3 + totalExpansions
- )
- b := newBuilder(t, expandTest)
- o := &b.root
- b.processExpansions(o)
-
- e := o.front()
- for _, tt := range expandTest {
- exp := b.t.expandElem[e.expansionIndex:]
- if int(exp[0]) != len(tt.ces) {
- t.Errorf("%U: len(expansion)==%d; want %d", []rune(tt.str)[0], exp[0],
len(tt.ces))
- }
- exp = exp[1:]
- for j, w := range tt.ces {
- if ce, _ := makeCE(w); exp[j] != ce {
- t.Errorf("%U: element %d is %X; want %X", []rune(tt.str)[0], j,
exp[j], ce)
- }
- }
- e, _ = e.nextIndexed()
- }
- // Verify uniquing.
- if len(b.t.expandElem) != totalElements {
- t.Errorf("len(expandElem)==%d; want %d", len(b.t.expandElem),
totalElements)
- }
-}
-
-var contractTest = []ducetElem{
- {"abc", pCE(102)},
- {"abd", pCE(103)},
- {"a", pCE(100)},
- {"ab", pCE(101)},
- {"ac", pCE(104)},
- {"bcd", pCE(202)},
- {"b", pCE(200)},
- {"bc", pCE(201)},
- {"bd", pCE(203)},
- // shares suffixes with a*
- {"Ab", pCE(301)},
- {"A", pCE(300)},
- {"Ac", pCE(304)},
- {"Abc", pCE(302)},
- {"Abd", pCE(303)},
- // starter to be ignored
- {"z", pCE(1000)},
-}
-
-func TestContract(t *testing.T) {
- const (
- totalElements = 5 + 5 + 4
- )
- b := newBuilder(t, contractTest)
- o := &b.root
- b.processContractions(o)
-
- indexMap := make(map[int]bool)
- handleMap := make(map[rune]*entry)
- for e := o.front(); e != nil; e, _ = e.nextIndexed() {
- if e.contractionHandle.n > 0 {
- handleMap[e.runes[0]] = e
- indexMap[e.contractionHandle.index] = true
- }
- }
- // Verify uniquing.
- if len(indexMap) != 2 {
- t.Errorf("number of tries is %d; want %d", len(indexMap), 2)
- }
- for _, tt := range contractTest {
- e, ok := handleMap[[]rune(tt.str)[0]]
- if !ok {
- continue
- }
- str := tt.str[1:]
- offset, n := b.t.contractTries.lookup(e.contractionHandle, []byte(str))
- if len(str) != n {
- t.Errorf("%s: bytes consumed==%d; want %d", tt.str, n, len(str))
- }
- ce := b.t.contractElem[offset+e.contractionIndex]
- if want, _ := makeCE(tt.ces[0]); want != ce {
- t.Errorf("%s: element %X; want %X", tt.str, ce, want)
- }
- }
- if len(b.t.contractElem) != totalElements {
- t.Errorf("len(expandElem)==%d; want %d", len(b.t.contractElem),
totalElements)
- }
-}
=======================================
--- /src/pkg/exp/locale/collate/build/colelem.go Tue Feb 12 06:59:55 2013
+++ /dev/null
@@ -1,293 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package build
-
-import (
- "exp/locale/collate/colltab"
- "fmt"
- "unicode"
-)
-
-const (
- defaultSecondary = 0x20
- defaultTertiary = 0x2
- maxTertiary = 0x1F
-)
-
-type rawCE struct {
- w []int
- ccc uint8
-}
-
-func makeRawCE(w []int, ccc uint8) rawCE {
- ce := rawCE{w: make([]int, 4), ccc: ccc}
- copy(ce.w, w)
- return ce
-}
-
-// A collation element is represented as an uint32.
-// In the typical case, a rune maps to a single collation element. If a
rune
-// can be the start of a contraction or expands into multiple collation
elements,
-// then the collation element that is associated with a rune will have a
special
-// form to represent such m to n mappings. Such special collation elements
-// have a value >= 0x80000000.
-
-const (
- maxPrimaryBits = 21
- maxSecondaryBits = 12
- maxTertiaryBits = 8
-)
-
-func makeCE(ce rawCE) (uint32, error) {
- v, e := colltab.MakeElem(ce.w[0], ce.w[1], ce.w[2], ce.ccc)
- return uint32(v), e
-}
-
-// For contractions, collation elements are of the form
-// 110bbbbb bbbbbbbb iiiiiiii iiiinnnn, where
-// - n* is the size of the first node in the contraction trie.
-// - i* is the index of the first node in the contraction trie.
-// - b* is the offset into the contraction collation element table.
-// See contract.go for details on the contraction trie.
-const (
- contractID = 0xC0000000
- maxNBits = 4
- maxTrieIndexBits = 12
- maxContractOffsetBits = 13
-)
-
-func makeContractIndex(h ctHandle, offset int) (uint32, error) {
- if h.n >= 1<<maxNBits {
- return 0, fmt.Errorf("size of contraction trie node too large: %d
>= %d", h.n, 1<<maxNBits)
- }
- if h.index >= 1<<maxTrieIndexBits {
- return 0, fmt.Errorf("size of contraction trie offset too large: %d
>= %d", h.index, 1<<maxTrieIndexBits)
- }
- if offset >= 1<<maxContractOffsetBits {
- return 0, fmt.Errorf("contraction offset out of bounds: %x >= %x",
offset, 1<<maxContractOffsetBits)
- }
- ce := uint32(contractID)
- ce += uint32(offset << (maxNBits + maxTrieIndexBits))
- ce += uint32(h.index << maxNBits)
- ce += uint32(h.n)
- return ce, nil
-}
-
-// For expansions, collation elements are of the form
-// 11100000 00000000 bbbbbbbb bbbbbbbb,
-// where b* is the index into the expansion sequence table.
-const (
- expandID = 0xE0000000
- maxExpandIndexBits = 16
-)
-
-func makeExpandIndex(index int) (uint32, error) {
- if index >= 1<<maxExpandIndexBits {
- return 0, fmt.Errorf("expansion index out of bounds: %x >= %x", index,
1<<maxExpandIndexBits)
- }
- return expandID + uint32(index), nil
-}
-
-// Each list of collation elements corresponding to an expansion starts
with
-// a header indicating the length of the sequence.
-func makeExpansionHeader(n int) (uint32, error) {
- return uint32(n), nil
-}
-
-// Some runes can be expanded using NFKD decomposition. Instead of storing
the full
-// sequence of collation elements, we decompose the rune and lookup the
collation
-// elements for each rune in the decomposition and modify the tertiary
weights.
-// The collation element, in this case, is of the form
-// 11110000 00000000 wwwwwwww vvvvvvvv, where
-// - v* is the replacement tertiary weight for the first rune,
-// - w* is the replacement tertiary weight for the second rune,
-// Tertiary weights of subsequent runes should be replaced with
maxTertiary.
-// See
http://www.unicode.org/reports/tr10/#Compatibility_Decompositions
for more details.
-const (
- decompID = 0xF0000000
-)
-
-func makeDecompose(t1, t2 int) (uint32, error) {
- if t1 >= 256 || t1 < 0 {
- return 0, fmt.Errorf("first tertiary weight out of bounds: %d >= 256",
t1)
- }
- if t2 >= 256 || t2 < 0 {
- return 0, fmt.Errorf("second tertiary weight out of bounds: %d >= 256",
t2)
- }
- return uint32(t2<<8+t1) + decompID, nil
-}
-
-const (
- // These constants were taken from
http://www.unicode.org/versions/Unicode6.0.0/ch12.pdf.
- minUnified rune = 0x4E00
- maxUnified = 0x9FFF
- minCompatibility = 0xF900
- maxCompatibility = 0xFAFF
- minRare = 0x3400
- maxRare = 0x4DBF
-)
-const (
- commonUnifiedOffset = 0x10000
- rareUnifiedOffset = 0x20000 // largest rune in common is U+FAFF
- otherOffset = 0x50000 // largest rune in rare is U+2FA1D
- illegalOffset = otherOffset + int(unicode.MaxRune)
- maxPrimary = illegalOffset + 1
-)
-
-// implicitPrimary returns the primary weight for the a rune
-// for which there is no entry for the rune in the collation table.
-// We take a different approach from the one specified in
-//
http://unicode.org/reports/tr10/#Implicit_Weights,
-// but preserve the resulting relative ordering of the runes.
-func implicitPrimary(r rune) int {
- if unicode.Is(unicode.Ideographic, r) {
- if r >= minUnified && r <= maxUnified {
- // The most common case for CJK.
- return int(r) + commonUnifiedOffset
- }
- if r >= minCompatibility && r <= maxCompatibility {
- // This will typically not hit. The DUCET explicitly specifies mappings
- // for all characters that do not decompose.
- return int(r) + commonUnifiedOffset
- }
- return int(r) + rareUnifiedOffset
- }
- return int(r) + otherOffset
-}
-
-// convertLargeWeights converts collation elements with large
-// primaries (either double primaries or for illegal runes)
-// to our own representation.
-// A CJK character C is represented in the DUCET as
-// [.FBxx.0020.0002.C][.BBBB.0000.0000.C]
-// We will rewrite these characters to a single CE.
-// We assume the CJK values start at 0x8000.
-// See
http://unicode.org/reports/tr10/#Implicit_Weights
-func convertLargeWeights(elems []rawCE) (res []rawCE, err error) {
- const (
- cjkPrimaryStart = 0xFB40
- rarePrimaryStart = 0xFB80
- otherPrimaryStart = 0xFBC0
- illegalPrimary = 0xFFFE
- highBitsMask = 0x3F
- lowBitsMask = 0x7FFF
- lowBitsFlag = 0x8000
- shiftBits = 15
- )
- for i := 0; i < len(elems); i++ {
- ce := elems[i].w
- p := ce[0]
- if p < cjkPrimaryStart {
- continue
- }
- if p > 0xFFFF {
- return elems, fmt.Errorf("found primary weight %X; should be <=
0xFFFF", p)
- }
- if p >= illegalPrimary {
- ce[0] = illegalOffset + p - illegalPrimary
- } else {
- if i+1 >= len(elems) {
- return elems, fmt.Errorf("second part of double primary weight
missing: %v", elems)
- }
- if elems[i+1].w[0]&lowBitsFlag == 0 {
- return elems, fmt.Errorf("malformed second part of double primary
weight: %v", elems)
- }
- np := ((p & highBitsMask) << shiftBits) + elems[i+1].w[0]&lowBitsMask
- switch {
- case p < rarePrimaryStart:
- np += commonUnifiedOffset
- case p < otherPrimaryStart:
- np += rareUnifiedOffset
- default:
- p += otherOffset
- }
- ce[0] = np
- for j := i + 1; j+1 < len(elems); j++ {
- elems[j] = elems[j+1]
- }
- elems = elems[:len(elems)-1]
- }
- }
- return elems, nil
-}
-
-// nextWeight computes the first possible collation weights following elems
-// for the given level.
-func nextWeight(level colltab.Level, elems []rawCE) []rawCE {
- if level == colltab.Identity {
- next := make([]rawCE, len(elems))
- copy(next, elems)
- return next
- }
- next := []rawCE{makeRawCE(elems[0].w, elems[0].ccc)}
- next[0].w[level]++
- if level < colltab.Secondary {
- next[0].w[colltab.Secondary] = defaultSecondary
- }
- if level < colltab.Tertiary {
- next[0].w[colltab.Tertiary] = defaultTertiary
- }
- // Filter entries that cannot influence ordering.
- for _, ce := range elems[1:] {
- skip := true
- for i := colltab.Primary; i < level; i++ {
- skip = skip && ce.w[i] == 0
- }
- if !skip {
- next = append(next, ce)
- }
- }
- return next
-}
-
-func nextVal(elems []rawCE, i int, level colltab.Level) (index, value int)
{
- for ; i < len(elems) && elems[i].w[level] == 0; i++ {
- }
- if i < len(elems) {
- return i, elems[i].w[level]
- }
- return i, 0
-}
-
-// compareWeights returns -1 if a < b, 1 if a > b, or 0 otherwise.
-// It also returns the collation level at which the difference is found.
-func compareWeights(a, b []rawCE) (result int, level colltab.Level) {
- for level := colltab.Primary; level < colltab.Identity; level++ {
- var va, vb int
- for ia, ib := 0, 0; ia < len(a) || ib < len(b); ia, ib = ia+1, ib+1 {
- ia, va = nextVal(a, ia, level)
- ib, vb = nextVal(b, ib, level)
- if va != vb {
- if va < vb {
- return -1, level
- } else {
- return 1, level
- }
- }
- }
- }
- return 0, colltab.Identity
-}
-
-func equalCE(a, b rawCE) bool {
- for i := 0; i < 3; i++ {
- if b.w[i] != a.w[i] {
- return false
- }
- }
- return true
-}
-
-func equalCEArrays(a, b []rawCE) bool {
- if len(a) != len(b) {
- return false
- }
- for i := range a {
- if !equalCE(a[i], b[i]) {
- return false
- }
- }
- return true
-}
=======================================
--- /src/pkg/exp/locale/collate/build/colelem_test.go Tue Feb 12 06:59:55
2013
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package build
-
-import (
- "exp/locale/collate/colltab"
- "testing"
-)
-
-type ceTest struct {
- f func(in []int) (uint32, error)
- arg []int
- val uint32
-}
-
-func normalCE(in []int) (ce uint32, err error) {
- return makeCE(rawCE{w: in[:3], ccc: uint8(in[3])})
-}
-
-func expandCE(in []int) (ce uint32, err error) {
- return makeExpandIndex(in[0])
-}
-
-func contractCE(in []int) (ce uint32, err error) {
- return makeContractIndex(ctHandle{in[0], in[1]}, in[2])
-}
-
-func decompCE(in []int) (ce uint32, err error) {
- return makeDecompose(in[0], in[1])
-}
-
-var ceTests = []ceTest{
- {normalCE, []int{0, 0, 0, 0}, 0xA0000000},
- {normalCE, []int{0, 0x28, 3, 0}, 0xA0002803},
- {normalCE, []int{0, 0x28, 3, 0xFF}, 0xAFF02803},
- {normalCE, []int{100, defaultSecondary, 3, 0}, 0x0000C883},
- // non-ignorable primary with non-default secondary
- {normalCE, []int{100, 0x28, defaultTertiary, 0}, 0x4000C828},
- {normalCE, []int{100, defaultSecondary + 8, 3, 0}, 0x0000C983},
- {normalCE, []int{100, 0, 3, 0}, 0xFFFF}, // non-ignorable primary with
non-supported secondary
- {normalCE, []int{100, 1, 3, 0}, 0xFFFF},
- {normalCE, []int{1 << maxPrimaryBits, defaultSecondary, 0, 0}, 0xFFFF},
- {normalCE, []int{0, 1 << maxSecondaryBits, 0, 0}, 0xFFFF},
- {normalCE, []int{100, defaultSecondary, 1 << maxTertiaryBits, 0}, 0xFFFF},
- {normalCE, []int{0x123, defaultSecondary, 8, 0xFF}, 0x88FF0123},
- {normalCE, []int{0x123, defaultSecondary + 1, 8, 0xFF}, 0xFFFF},
-
- {contractCE, []int{0, 0, 0}, 0xC0000000},
- {contractCE, []int{1, 1, 1}, 0xC0010011},
- {contractCE, []int{1, (1 << maxNBits) - 1, 1}, 0xC001001F},
- {contractCE, []int{(1 << maxTrieIndexBits) - 1, 1, 1}, 0xC001FFF1},
- {contractCE, []int{1, 1, (1 << maxContractOffsetBits) - 1}, 0xDFFF0011},
- {contractCE, []int{1, (1 << maxNBits), 1}, 0xFFFF},
- {contractCE, []int{(1 << maxTrieIndexBits), 1, 1}, 0xFFFF},
- {contractCE, []int{1, (1 << maxContractOffsetBits), 1}, 0xFFFF},
-
- {expandCE, []int{0}, 0xE0000000},
- {expandCE, []int{5}, 0xE0000005},
- {expandCE, []int{(1 << maxExpandIndexBits) - 1}, 0xE000FFFF},
- {expandCE, []int{1 << maxExpandIndexBits}, 0xFFFF},
-
- {decompCE, []int{0, 0}, 0xF0000000},
- {decompCE, []int{1, 1}, 0xF0000101},
- {decompCE, []int{0x1F, 0x1F}, 0xF0001F1F},
- {decompCE, []int{256, 0x1F}, 0xFFFF},
- {decompCE, []int{0x1F, 256}, 0xFFFF},
-}
-
-func TestColElem(t *testing.T) {
- for i, tt := range ceTests {
- in := make([]int, len(tt.arg))
- copy(in, tt.arg)
- ce, err := tt.f(in)
- if tt.val == 0xFFFF {
- if err == nil {
- t.Errorf("%d: expected error for args %x", i, tt.arg)
- }
- continue
- }
- if err != nil {
- t.Errorf("%d: unexpected error: %v", i, err.Error())
- }
- if ce != tt.val {
- t.Errorf("%d: colElem=%X; want %X", i, ce, tt.val)
- }
- }
-}
-
-func mkRawCES(in [][]int) []rawCE {
- out := []rawCE{}
- for _, w := range in {
- out = append(out, rawCE{w: w})
- }
- return out
-}
-
-type weightsTest struct {
- a, b [][]int
- level colltab.Level
- result int
-}
-
-var nextWeightTests = []weightsTest{
- {
- a: [][]int{{100, 20, 5, 0}},
- b: [][]int{{101, defaultSecondary, defaultTertiary, 0}},
- level: colltab.Primary,
- },
- {
- a: [][]int{{100, 20, 5, 0}},
- b: [][]int{{100, 21, defaultTertiary, 0}},
- level: colltab.Secondary,
- },
- {
- a: [][]int{{100, 20, 5, 0}},
- b: [][]int{{100, 20, 6, 0}},
- level: colltab.Tertiary,
- },
- {
- a: [][]int{{100, 20, 5, 0}},
- b: [][]int{{100, 20, 5, 0}},
- level: colltab.Identity,
- },
-}
-
-var extra = [][]int{{200, 32, 8, 0}, {0, 32, 8, 0}, {0, 0, 8, 0}, {0, 0,
0, 0}}
-
-func TestNextWeight(t *testing.T) {
- for i, tt := range nextWeightTests {
- test := func(l colltab.Level, tt weightsTest, a, gold [][]int) {
- res := nextWeight(tt.level, mkRawCES(a))
- if !equalCEArrays(mkRawCES(gold), res) {
- t.Errorf("%d:%d: expected weights %d; found %d", i, l, gold, res)
- }
- }
- test(-1, tt, tt.a, tt.b)
- for l := colltab.Primary; l <= colltab.Tertiary; l++ {
- if tt.level <= l {
- test(l, tt, append(tt.a, extra[l]), tt.b)
- } else {
- test(l, tt, append(tt.a, extra[l]), append(tt.b, extra[l]))
- }
- }
- }
-}
-
-var compareTests = []weightsTest{
- {
- [][]int{{100, 20, 5, 0}},
- [][]int{{100, 20, 5, 0}},
- colltab.Identity,
- 0,
- },
- {
- [][]int{{100, 20, 5, 0}, extra[0]},
- [][]int{{100, 20, 5, 1}},
- colltab.Primary,
- 1,
- },
- {
- [][]int{{100, 20, 5, 0}},
- [][]int{{101, 20, 5, 0}},
- colltab.Primary,
- -1,
- },
- {
- [][]int{{101, 20, 5, 0}},
- [][]int{{100, 20, 5, 0}},
- colltab.Primary,
- 1,
- },
- {
- [][]int{{100, 0, 0, 0}, {0, 20, 5, 0}},
- [][]int{{0, 20, 5, 0}, {100, 0, 0, 0}},
- colltab.Identity,
- 0,
- },
- {
- [][]int{{100, 20, 5, 0}},
- [][]int{{100, 21, 5, 0}},
- colltab.Secondary,
- -1,
- },
- {
- [][]int{{100, 20, 5, 0}},
- [][]int{{100, 20, 2, 0}},
- colltab.Tertiary,
- 1,
- },
- {
- [][]int{{100, 20, 5, 1}},
- [][]int{{100, 20, 5, 2}},
- colltab.Quaternary,
- -1,
- },
-}
-
-func TestCompareWeights(t *testing.T) {
- for i, tt := range compareTests {
- test := func(tt weightsTest, a, b [][]int) {
- res, level := compareWeights(mkRawCES(a), mkRawCES(b))
- if res != tt.result {
- t.Errorf("%d: expected comparisson result %d; found %d", i, tt.result,
res)
- }
- if level != tt.level {
- t.Errorf("%d: expected level %d; found %d", i, tt.level, level)
- }
- }
- test(tt, tt.a, tt.b)
- test(tt, append(tt.a, extra[0]), append(tt.b, extra[0]))
- }
-}
=======================================
--- /src/pkg/exp/locale/collate/build/contract.go Tue Oct 30 13:38:01 2012
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package build
-
-import (
- "fmt"
- "io"
- "reflect"
- "sort"
- "strings"
-)
-
-// This file contains code for detecting contractions and generating
-// the necessary tables.
-// Any Unicode Collation Algorithm (UCA) table entry that has more than
-// one rune one the left-hand side is called a contraction.
-// See
http://www.unicode.org/reports/tr10/#Contractions for more details.
-//
-// We define the following terms:
-// initial: a rune that appears as the first rune in a contraction.
-// suffix: a sequence of runes succeeding the initial rune
-// in a given contraction.
-// non-initial: a rune that appears in a suffix.
-//
-// A rune may be both a initial and a non-initial and may be so in
-// many contractions. An initial may typically also appear by itself.
-// In case of ambiguities, the UCA requires we match the longest
-// contraction.
-//
-// Many contraction rules share the same set of possible suffixes.
-// We store sets of suffixes in a trie that associates an index with
-// each suffix in the set. This index can be used to look up a
-// collation element associated with the (starter rune, suffix) pair.
-//
-// The trie is defined on a UTF-8 byte sequence.
-// The overall trie is represented as an array of ctEntries. Each node of
the trie
-// is represented as a subsequence of ctEntries, where each entry
corresponds to
-// a possible match of a next character in the search string. An entry
-// also includes the length and offset to the next sequence of entries
-// to check in case of a match.
-
-const (
- final = 0
- noIndex = 0xFF
-)
-
-// ctEntry associates to a matching byte an offset and/or next sequence of
-// bytes to check. A ctEntry c is called final if a match means that the
-// longest suffix has been found. An entry c is final if c.n == 0.
-// A single final entry can match a range of characters to an offset.
-// A non-final entry always matches a single byte. Note that a non-final
-// entry might still resemble a completed suffix.
-// Examples:
-// The suffix strings "ab" and "ac" can be represented as:
-// []ctEntry{
-// {'a', 1, 1, noIndex}, // 'a' by itself does not match, so i is
0xFF.
-// {'b', 'c', 0, 1}, // "ab" -> 1, "ac" -> 2
-// }
-//
-// The suffix strings "ab", "abc", "abd", and "abcd" can be represented as:
-// []ctEntry{
-// {'a', 1, 1, noIndex}, // 'a' must be followed by 'b'.
-// {'b', 1, 2, 1}, // "ab" -> 1, may be followed by 'c' or 'd'.
-// {'d', 'd', final, 3}, // "abd" -> 3
-// {'c', 4, 1, 2}, // "abc" -> 2, may be followed by 'd'.
-// {'d', 'd', final, 4}, // "abcd" -> 4
-// }
-// See genStateTests in contract_test.go for more examples.
-type ctEntry struct {
- l uint8 // non-final: byte value to match; final: lowest match in range.
- h uint8 // non-final: relative index to next block; final: highest match
in range.
- n uint8 // non-final: length of next block; final: final
- i uint8 // result offset. Will be noIndex if more bytes are needed to
complete.
-}
-
-// contractTrieSet holds a set of contraction tries. The tries are stored
-// consecutively in the entry field.
-type contractTrieSet []struct{ l, h, n, i uint8 }
-
-// ctHandle is used to identify a trie in the trie set, consisting in an
offset
-// in the array and the size of the first node.
-type ctHandle struct {
- index, n int
-}
-
-// appendTrie adds a new trie for the given suffixes to the trie set and
returns
-// a handle to it. The handle will be invalid on error.
-func (ct *contractTrieSet) appendTrie(suffixes []string) (ctHandle, error)
{
- es := make([]stridx, len(suffixes))
- for i, s := range suffixes {
- es[i].str = s
- }
- sort.Sort(offsetSort(es))
- for i := range es {
- es[i].index = i + 1
- }
- sort.Sort(genidxSort(es))
- i := len(*ct)
- n, err := ct.genStates(es)
- if err != nil {
- *ct = (*ct)[:i]
- return ctHandle{}, err
- }
- return ctHandle{i, n}, nil
-}
-
-// genStates generates ctEntries for a given suffix set and returns
-// the number of entries for the first node.
-func (ct *contractTrieSet) genStates(sis []stridx) (int, error) {
- if len(sis) == 0 {
- return 0, fmt.Errorf("genStates: list of suffices must be non-empty")
- }
- start := len(*ct)
- // create entries for differing first bytes.
- for _, si := range sis {
- s := si.str
- if len(s) == 0 {
- continue
- }
- added := false
- c := s[0]
- if len(s) > 1 {
- for j := len(*ct) - 1; j >= start; j-- {
- if (*ct)[j].l == c {
- added = true
- break
- }
- }
- if !added {
- *ct = append(*ct, ctEntry{l: c, i: noIndex})
- }
- } else {
- for j := len(*ct) - 1; j >= start; j-- {
- // Update the offset for longer suffixes with the same byte.
- if (*ct)[j].l == c {
- (*ct)[j].i = uint8(si.index)
- added = true
- }
- // Extend range of final ctEntry, if possible.
- if (*ct)[j].h+1 == c {
- (*ct)[j].h = c
- added = true
- }
- }
- if !added {
- *ct = append(*ct, ctEntry{l: c, h: c, n: final, i: uint8(si.index)})
- }
- }
- }
- n := len(*ct) - start
- // Append nodes for the remainder of the suffixes for each ctEntry.
- sp := 0
- for i, end := start, len(*ct); i < end; i++ {
- fe := (*ct)[i]
- if fe.h == 0 { // uninitialized non-final
- ln := len(*ct) - start - n
- if ln > 0xFF {
- return 0, fmt.Errorf("genStates: relative block offset too large: %d >
255", ln)
- }
- fe.h = uint8(ln)
- // Find first non-final strings with same byte as current entry.
- for ; sis[sp].str[0] != fe.l; sp++ {
- }
- se := sp + 1
- for ; se < len(sis) && len(sis[se].str) > 1 && sis[se].str[0] == fe.l;
se++ {
- }
- sl := sis[sp:se]
- sp = se
- for i, si := range sl {
- sl[i].str = si.str[1:]
- }
- nn, err := ct.genStates(sl)
- if err != nil {
- return 0, err
- }
- fe.n = uint8(nn)
- (*ct)[i] = fe
- }
- }
- sort.Sort(entrySort((*ct)[start : start+n]))
- return n, nil
-}
-
-// There may be both a final and non-final entry for a byte if the byte
-// is implied in a range of matches in the final entry.
-// We need to ensure that the non-final entry comes first in that case.
-type entrySort contractTrieSet
-
-func (fe entrySort) Len() int { return len(fe) }
-func (fe entrySort) Swap(i, j int) { fe[i], fe[j] = fe[j], fe[i] }
-func (fe entrySort) Less(i, j int) bool {
- return fe[i].l > fe[j].l
-}
-
-// stridx is used for sorting suffixes and their associated offsets.
-type stridx struct {
- str string
- index int
-}
-
-// For computing the offsets, we first sort by size, and then by string.
-// This ensures that strings that only differ in the last byte by 1
-// are sorted consecutively in increasing order such that they can
-// be packed as a range in a final ctEntry.
-type offsetSort []stridx
-
-func (si offsetSort) Len() int { return len(si) }
-func (si offsetSort) Swap(i, j int) { si[i], si[j] = si[j], si[i] }
-func (si offsetSort) Less(i, j int) bool {
- if len(si[i].str) != len(si[j].str) {
- return len(si[i].str) > len(si[j].str)
- }
- return si[i].str < si[j].str
-}
-
-// For indexing, we want to ensure that strings are sorted in string
order, where
-// for strings with the same prefix, we put longer strings before shorter
ones.
-type genidxSort []stridx
-
-func (si genidxSort) Len() int { return len(si) }
-func (si genidxSort) Swap(i, j int) { si[i], si[j] = si[j], si[i] }
-func (si genidxSort) Less(i, j int) bool {
- if strings.HasPrefix(si[j].str, si[i].str) {
- return false
- }
- if strings.HasPrefix(si[i].str, si[j].str) {
- return true
- }
- return si[i].str < si[j].str
-}
-
-// lookup matches the longest suffix in str and returns the associated
offset
-// and the number of bytes consumed.
-func (ct *contractTrieSet) lookup(h ctHandle, str []byte) (index, ns int) {
- states := (*ct)[h.index:]
- p := 0
- n := h.n
- for i := 0; i < n && p < len(str); {
- e := states[i]
- c := str[p]
- if c >= e.l {
- if e.l == c {
- p++
- if e.i != noIndex {
- index, ns = int(e.i), p
- }
- if e.n != final {
- // set to new state
- i, states, n = 0, states[int(e.h)+n:], int(e.n)
- } else {
- return
- }
- continue
- } else if e.n == final && c <= e.h {
- p++
- return int(c-e.l) + int(e.i), p
- }
- }
- i++
- }
- return
-}
-
-// print writes the contractTrieSet t as compilable Go code to w. It
returns
-// the total number of bytes written and the size of the resulting data
structure in bytes.
-func (t *contractTrieSet) print(w io.Writer, name string) (n, size int,
err error) {
- update3 := func(nn, sz int, e error) {
- n += nn
- if err == nil {
- err = e
- }
- size += sz
- }
- update2 := func(nn int, e error) { update3(nn, 0, e) }
-
- update3(t.printArray(w, name))
- update2(fmt.Fprintf(w, "var %sContractTrieSet = ", name))
- update3(t.printStruct(w, name))
- update2(fmt.Fprintln(w))
- return
-}
-
-func (ct contractTrieSet) printArray(w io.Writer, name string) (n, size
int, err error) {
- p := func(f string, a ...interface{}) {
- nn, e := fmt.Fprintf(w, f, a...)
- n += nn
- if err == nil {
- err = e
- }
- }
- size = len(ct) * 4
- p("// %sCTEntries: %d entries, %d bytes\n", name, len(ct), size)
- p("var %sCTEntries = [%d]struct{l,h,n,i uint8}{\n", name, len(ct))
- for _, fe := range ct {
- p("\t{0x%X, 0x%X, %d, %d},\n", fe.l, fe.h, fe.n, fe.i)
- }
- p("}\n")
- return
-}
-
-func (ct contractTrieSet) printStruct(w io.Writer, name string) (n, size
int, err error) {
- n, err = fmt.Fprintf(w, "contractTrieSet( %sCTEntries[:] )", name)
- size = int(reflect.TypeOf(ct).Size())
- return
-}
=======================================
--- /src/pkg/exp/locale/collate/build/contract_test.go Sun Oct 7 17:59:33
2012
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package build
-
-import (
- "bytes"
- "sort"
- "testing"
-)
-
-var largetosmall = []stridx{
- {"a", 5},
- {"ab", 4},
- {"abc", 3},
- {"abcd", 2},
- {"abcde", 1},
- {"abcdef", 0},
-}
-
-var offsetSortTests = [][]stridx{
- {
- {"bcde", 1},
- {"bc", 5},
- {"ab", 4},
- {"bcd", 3},
- {"abcd", 0},
- {"abc", 2},
- },
- largetosmall,
-}
-
-func TestOffsetSort(t *testing.T) {
- for i, st := range offsetSortTests {
- sort.Sort(offsetSort(st))
- for j, si := range st {
- if j != si.index {
- t.Errorf("%d: failed: %v", i, st)
- }
- }
- }
- for i, tt := range genStateTests {
- // ensure input is well-formed
- sort.Sort(offsetSort(
tt.in))
- for j, si := range
tt.in {
- if si.index != j+1 {
- t.Errorf("%dth sort failed: %v", i,
tt.in)
- }
- }
- }
-}
-
-var genidxtest1 = []stridx{
- {"bcde", 3},
- {"bc", 6},
- {"ab", 2},
- {"bcd", 5},
- {"abcd", 0},
- {"abc", 1},
- {"bcdf", 4},
-}
-
-var genidxSortTests = [][]stridx{
- genidxtest1,
- largetosmall,
-}
-
-func TestGenIdxSort(t *testing.T) {
- for i, st := range genidxSortTests {
- sort.Sort(genidxSort(st))
- for j, si := range st {
- if j != si.index {
- t.Errorf("%dth sort failed %v", i, st)
- break
- }
- }
- }
-}
-
-var entrySortTests = []contractTrieSet{
- {
- {10, 0, 1, 3},
- {99, 0, 1, 0},
- {20, 50, 0, 2},
- {30, 0, 1, 1},
- },
-}
-
-func TestEntrySort(t *testing.T) {
- for i, et := range entrySortTests {
- sort.Sort(entrySort(et))
- for j, fe := range et {
- if j != int(fe.i) {
- t.Errorf("%dth sort failed %v", i, et)
- break
- }
- }
- }
-}
-
-type GenStateTest struct {
- in []stridx
- firstBlockLen int
- out contractTrieSet
-}
-
-var genStateTests = []GenStateTest{
- {[]stridx{
- {"abc", 1},
- },
- 1,
- contractTrieSet{
- {'a', 0, 1, noIndex},
- {'b', 0, 1, noIndex},
- {'c', 'c', final, 1},
- },
- },
- {[]stridx{
- {"abc", 1},
- {"abd", 2},
- {"abe", 3},
- },
- 1,
- contractTrieSet{
- {'a', 0, 1, noIndex},
- {'b', 0, 1, noIndex},
- {'c', 'e', final, 1},
- },
- },
- {[]stridx{
- {"abc", 1},
- {"ab", 2},
- {"a", 3},
- },
- 1,
- contractTrieSet{
- {'a', 0, 1, 3},
- {'b', 0, 1, 2},
- {'c', 'c', final, 1},
- },
- },
- {[]stridx{
- {"abc", 1},
- {"abd", 2},
- {"ab", 3},
- {"ac", 4},
- {"a", 5},
- {"b", 6},
- },
- 2,
- contractTrieSet{
- {'b', 'b', final, 6},
- {'a', 0, 2, 5},
- {'c', 'c', final, 4},
- {'b', 0, 1, 3},
- {'c', 'd', final, 1},
- },
- },
- {[]stridx{
- {"bcde", 2},
- {"bc", 7},
- {"ab", 6},
- {"bcd", 5},
- {"abcd", 1},
- {"abc", 4},
- {"bcdf", 3},
- },
- 2,
- contractTrieSet{
- {'b', 3, 1, noIndex},
- {'a', 0, 1, noIndex},
- {'b', 0, 1, 6},
- {'c', 0, 1, 4},
- {'d', 'd', final, 1},
- {'c', 0, 1, 7},
- {'d', 0, 1, 5},
- {'e', 'f', final, 2},
- },
- },
-}
-
-func TestGenStates(t *testing.T) {
- for i, tt := range genStateTests {
- si := []stridx{}
- for _, e := range
tt.in {
- si = append(si, e)
- }
- // ensure input is well-formed
- sort.Sort(genidxSort(si))
- ct := contractTrieSet{}
- n, _ := ct.genStates(si)
- if nn := tt.firstBlockLen; nn != n {
- t.Errorf("%d: block len %v; want %v", i, n, nn)
- }
- if lv, lw := len(ct), len(tt.out); lv != lw {
- t.Errorf("%d: len %v; want %v", i, lv, lw)
- continue
- }
- for j, fe := range tt.out {
- const msg = "%d:%d: value %s=%v; want %v"
- if fe.l != ct[j].l {
- t.Errorf(msg, i, j, "l", ct[j].l, fe.l)
- }
- if fe.h != ct[j].h {
- t.Errorf(msg, i, j, "h", ct[j].h, fe.h)
- }
- if fe.n != ct[j].n {
- t.Errorf(msg, i, j, "n", ct[j].n, fe.n)
- }
- if fe.i != ct[j].i {
- t.Errorf(msg, i, j, "i", ct[j].i, fe.i)
- }
- }
- }
-}
-
-func TestLookupContraction(t *testing.T) {
- for i, tt := range genStateTests {
- input := []string{}
- for _, e := range
tt.in {
- input = append(input, e.str)
- }
- cts := contractTrieSet{}
- h, _ := cts.appendTrie(input)
- for j, si := range
tt.in {
- str := si.str
- for _, s := range []string{str, str + "X"} {
- msg := "%d:%d: %s(%s) %v; want %v"
- idx, sn := cts.lookup(h, []byte(s))
- if idx != si.index {
- t.Errorf(msg, i, j, "index", s, idx, si.index)
- }
- if sn != len(str) {
- t.Errorf(msg, i, j, "sn", s, sn, len(str))
- }
- }
- }
- }
-}
-
-func TestPrintContractionTrieSet(t *testing.T) {
- testdata := contractTrieSet(genStateTests[4].out)
- buf := &bytes.Buffer{}
- testdata.print(buf, "test")
- if contractTrieOutput != buf.String() {
- t.Errorf("output differs; found\n%s", buf.String())
- println(string(buf.Bytes()))
- }
-}
-
-const contractTrieOutput = `// testCTEntries: 8 entries, 32 bytes
-var testCTEntries = [8]struct{l,h,n,i uint8}{
- {0x62, 0x3, 1, 255},
- {0x61, 0x0, 1, 255},
- {0x62, 0x0, 1, 6},
- {0x63, 0x0, 1, 4},
- {0x64, 0x64, 0, 1},
- {0x63, 0x0, 1, 7},
- {0x64, 0x0, 1, 5},
- {0x65, 0x66, 0, 2},
-}
-var testContractTrieSet = contractTrieSet( testCTEntries[:] )
-`
=======================================
--- /src/pkg/exp/locale/collate/build/order.go Tue Feb 12 06:59:55 2013
+++ /dev/null
@@ -1,392 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package build
-
-import (
- "exp/locale/collate/colltab"
- "exp/norm"
- "fmt"
- "log"
- "sort"
- "strings"
- "unicode"
-)
-
-type logicalAnchor int
-
-const (
- firstAnchor logicalAnchor = -1
- noAnchor = 0
- lastAnchor = 1
-)
-
-// entry is used to keep track of a single entry in the collation element
table
-// during building. Examples of entries can be found in the Default Unicode
-// Collation Element Table.
-// See
http://www.unicode.org/Public/UCA/6.0.0/allkeys.txt.
-type entry struct {
- str string // same as string(runes)
- runes []rune
- elems []rawCE // the collation elements
- extend string // weights of extend to be appended to elems
- before bool // weights relative to next instead of previous.
- lock bool // entry is used in extension and can no longer be moved.
-
- // prev, next, and level are used to keep track of tailorings.
- prev, next *entry
- level colltab.Level // next differs at this level
- skipRemove bool // do not unlink when removed
-
- decompose bool // can use NFKD decomposition to generate elems
- exclude bool // do not include in table
- implicit bool // derived, is not included in the list
- modified bool // entry was modified in tailoring
- logical logicalAnchor
-
- expansionIndex int // used to store index into expansion table
- contractionHandle ctHandle
- contractionIndex int // index into contraction elements
-}
-
-func (e *entry) String() string {
- return fmt.Sprintf("%X (%q) -> %X (ch:%x; ci:%d, ei:%d)",
- e.runes, e.str, e.elems, e.contractionHandle, e.contractionIndex,
e.expansionIndex)
-}
-
-func (e *entry) skip() bool {
- return e.contraction()
-}
-
-func (e *entry) expansion() bool {
- return !e.decompose && len(e.elems) > 1
-}
-
-func (e *entry) contraction() bool {
- return len(e.runes) > 1
-}
-
-func (e *entry) contractionStarter() bool {
- return e.contractionHandle.n != 0
-}
-
-// nextIndexed gets the next entry that needs to be stored in the table.
-// It returns the entry and the collation level at which the next entry
differs
-// from the current entry.
-// Entries that can be explicitly derived and logical reset positions are
-// examples of entries that will not be indexed.
-func (e *entry) nextIndexed() (*entry, colltab.Level) {
- level := e.level
- for e = e.next; e != nil && (e.exclude || len(e.elems) == 0); e = e.next {
- if e.level < level {
- level = e.level
- }
- }
- return e, level
-}
-
-// remove unlinks entry e from the sorted chain and clears the collation
-// elements. e may not be at the front or end of the list. This should
always
-// be the case, as the front and end of the list are always logical
anchors,
-// which may not be removed.
-func (e *entry) remove() {
- if e.logical != noAnchor {
- log.Fatalf("may not remove anchor %q", e.str)
- }
- // TODO: need to set e.prev.level to e.level if e.level is smaller?
- e.elems = nil
- if !e.skipRemove {
- if e.prev != nil {
- e.prev.next = e.next
- }
- if e.next != nil {
- e.next.prev = e.prev
- }
- }
- e.skipRemove = false
-}
-
-// insertAfter inserts n after e.
-func (e *entry) insertAfter(n *entry) {
- if e == n {
- panic("e == anchor")
- }
- if e == nil {
- panic("unexpected nil anchor")
- }
- n.remove()
- n.decompose = false // redo decomposition test
-
- n.next = e.next
- n.prev = e
- if e.next != nil {
- e.next.prev = n
- }
- e.next = n
-}
-
-// insertBefore inserts n before e.
-func (e *entry) insertBefore(n *entry) {
- if e == n {
- panic("e == anchor")
- }
- if e == nil {
- panic("unexpected nil anchor")
- }
- n.remove()
- n.decompose = false // redo decomposition test
-
- n.prev = e.prev
- n.next = e
- if e.prev != nil {
- e.prev.next = n
- }
- e.prev = n
-}
-
-func (e *entry) encodeBase() (ce uint32, err error) {
- switch {
- case e.expansion():
- ce, err = makeExpandIndex(e.expansionIndex)
- default:
- if e.decompose {
- log.Fatal("decompose should be handled elsewhere")
- }
- ce, err = makeCE(e.elems[0])
- }
- return
-}
-
-func (e *entry) encode() (ce uint32, err error) {
- if e.skip() {
- log.Fatal("cannot build colElem for entry that should be skipped")
- }
- switch {
- case e.decompose:
- t1 := e.elems[0].w[2]
- t2 := 0
- if len(e.elems) > 1 {
- t2 = e.elems[1].w[2]
- }
- ce, err = makeDecompose(t1, t2)
- case e.contractionStarter():
- ce, err = makeContractIndex(e.contractionHandle, e.contractionIndex)
- default:
- if len(e.runes) > 1 {
- log.Fatal("colElem: contractions are handled in contraction trie")
- }
- ce, err = e.encodeBase()
- }
- return
-}
-
-// entryLess returns true if a sorts before b and false otherwise.
-func entryLess(a, b *entry) bool {
- if res, _ := compareWeights(a.elems, b.elems); res != 0 {
- return res == -1
- }
- if a.logical != noAnchor {
- return a.logical == firstAnchor
- }
- if b.logical != noAnchor {
- return b.logical == lastAnchor
- }
- return a.str < b.str
-}
-
-type sortedEntries []*entry
-
-func (s sortedEntries) Len() int {
- return len(s)
-}
-
-func (s sortedEntries) Swap(i, j int) {
- s[i], s[j] = s[j], s[i]
-}
-
-func (s sortedEntries) Less(i, j int) bool {
- return entryLess(s[i], s[j])
-}
-
-type ordering struct {
- id string
- entryMap map[string]*entry
- ordered []*entry
- handle *trieHandle
-}
-
-// insert inserts e into both entryMap and ordered.
-// Note that insert simply appends e to ordered. To reattain a sorted
-// order, o.sort() should be called.
-func (o *ordering) insert(e *entry) {
- if e.logical == noAnchor {
- o.entryMap[e.str] = e
- } else {
- // Use key format as used in UCA rules.
- o.entryMap[fmt.Sprintf("[%s]", e.str)] = e
- // Also add index entry for XML format.
- o.entryMap[fmt.Sprintf("<%s/>", strings.Replace(e.str, " ", "_", -1))] =
e
- }
- o.ordered = append(o.ordered, e)
-}
-
-// newEntry creates a new entry for the given info and inserts it into
-// the index.
-func (o *ordering) newEntry(s string, ces []rawCE) *entry {
- e := &entry{
- runes: []rune(s),
- elems: ces,
- str: s,
- }
- o.insert(e)
- return e
-}
-
-// find looks up and returns the entry for the given string.
-// It returns nil if str is not in the index and if an implicit value
-// cannot be derived, that is, if str represents more than one rune.
-func (o *ordering) find(str string) *entry {
- e := o.entryMap[str]
- if e == nil {
- r := []rune(str)
- if len(r) == 1 {
- const (
- firstHangul = 0xAC00
- lastHangul = 0xD7A3
- )
- if r[0] >= firstHangul && r[0] <= lastHangul {
- ce := []rawCE{}
- nfd := norm.NFD.String(str)
- for _, r := range nfd {
- ce = append(ce, o.find(string(r)).elems...)
- }
- e = o.newEntry(nfd, ce)
- } else {
- e = o.newEntry(string(r[0]), []rawCE{
- {w: []int{
- implicitPrimary(r[0]),
- defaultSecondary,
- defaultTertiary,
- int(r[0]),
- },
- },
- })
- e.modified = true
- }
- e.exclude = true // do not index implicits
- }
- }
- return e
-}
-
-// makeRootOrdering returns a newly initialized ordering value and
populates
-// it with a set of logical reset points that can be used as anchors.
-// The anchors first_tertiary_ignorable and __END__ will always sort at
-// the beginning and end, respectively. This means that prev and next are
non-nil
-// for any indexed entry.
-func makeRootOrdering() ordering {
- const max = unicode.MaxRune
- o := ordering{
- entryMap: make(map[string]*entry),
- }
- insert := func(typ logicalAnchor, s string, ce []int) {
- e := &entry{
- elems: []rawCE{{w: ce}},
- str: s,
- exclude: true,
- logical: typ,
- }
- o.insert(e)
- }
- insert(firstAnchor, "first tertiary ignorable", []int{0, 0, 0, 0})
- insert(lastAnchor, "last tertiary ignorable", []int{0, 0, 0, max})
- insert(lastAnchor, "last primary ignorable", []int{0, defaultSecondary,
defaultTertiary, max})
- insert(lastAnchor, "last non ignorable", []int{maxPrimary,
defaultSecondary, defaultTertiary, max})
- insert(lastAnchor, "__END__", []int{1 << maxPrimaryBits,
defaultSecondary, defaultTertiary, max})
- return o
-}
-
-// patchForInsert eleminates entries from the list with more than one
collation element.
-// The next and prev fields of the eliminated entries still point to
appropriate
-// values in the newly created list.
-// It requires that sort has been called.
-func (o *ordering) patchForInsert() {
- for i := 0; i < len(o.ordered)-1; {
- e := o.ordered[i]
- lev := e.level
- n := e.next
- for ; n != nil && len(n.elems) > 1; n = n.next {
- if n.level < lev {
- lev = n.level
- }
- n.skipRemove = true
- }
- for ; o.ordered[i] != n; i++ {
- o.ordered[i].level = lev
- o.ordered[i].next = n
- o.ordered[i+1].prev = e
- }
- }
-}
-
-// clone copies all ordering of es into a new ordering value.
-func (o *ordering) clone() *ordering {
- o.sort()
- oo := ordering{
- entryMap: make(map[string]*entry),
- }
- for _, e := range o.ordered {
- ne := &entry{
- runes: e.runes,
- elems: e.elems,
- str: e.str,
- decompose: e.decompose,
- exclude: e.exclude,
- logical: e.logical,
- }
- oo.insert(ne)
- }
- oo.sort() // link all ordering.
- oo.patchForInsert()
- return &oo
-}
-
-// front returns the first entry to be indexed.
-// It assumes that sort() has been called.
-func (o *ordering) front() *entry {
- e := o.ordered[0]
- if e.prev != nil {
- log.Panicf("unexpected first entry: %v", e)
- }
- // The first entry is always a logical position, which should not be
indexed.
- e, _ = e.nextIndexed()
- return e
-}
-
-// sort sorts all ordering based on their collation elements and
initializes
-// the prev, next, and level fields accordingly.
-func (o *ordering) sort() {
- sort.Sort(sortedEntries(o.ordered))
- l := o.ordered
- for i := 1; i < len(l); i++ {
- k := i - 1
- l[k].next = l[i]
- _, l[k].level = compareWeights(l[k].elems, l[i].elems)
- l[i].prev = l[k]
- }
-}
-
-// genColElems generates a collation element array from the runes in str.
This
-// assumes that all collation elements have already been added to the
Builder.
-func (o *ordering) genColElems(str string) []rawCE {
- elems := []rawCE{}
- for _, r := range []rune(str) {
- for _, ce := range o.find(string(r)).elems {
- if ce.w[0] != 0 || ce.w[1] != 0 || ce.w[2] != 0 {
- elems = append(elems, ce)
- }
- }
- }
- return elems
-}
=======================================
--- /src/pkg/exp/locale/collate/build/order_test.go Tue Feb 12 06:59:55 2013
+++ /dev/null
@@ -1,228 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package build
-
-import (
- "exp/locale/collate/colltab"
- "strconv"
- "testing"
-)
-
-type entryTest struct {
- f func(in []int) (uint32, error)
- arg []int
- val uint32
-}
-
-// makeList returns a list of entries of length n+2, with n normal
-// entries plus a leading and trailing anchor.
-func makeList(n int) []*entry {
- es := make([]*entry, n+2)
- weights := []rawCE{{w: []int{100, 20, 5, 0}}}
- for i := range es {
- runes := []rune{rune(i)}
- es[i] = &entry{
- runes: runes,
- elems: weights,
- }
- weights = nextWeight(colltab.Primary, weights)
- }
- for i := 1; i < len(es); i++ {
- es[i-1].next = es[i]
- es[i].prev = es[i-1]
- _, es[i-1].level = compareWeights(es[i-1].elems, es[i].elems)
- }
- es[0].exclude = true
- es[0].logical = firstAnchor
- es[len(es)-1].exclude = true
- es[len(es)-1].logical = lastAnchor
- return es
-}
-
-func TestNextIndexed(t *testing.T) {
- const n = 5
- es := makeList(n)
- for i := int64(0); i < 1<<n; i++ {
- mask := strconv.FormatInt(i+(1<<n), 2)
- for i, c := range mask {
- es[i].exclude = c == '1'
- }
- e := es[0]
- for i, c := range mask {
- if c == '0' {
- e, _ = e.nextIndexed()
- if e != es[i] {
- t.Errorf("%d: expected entry %d; found %d", i, es[i].elems, e.elems)
- }
- }
- }
- if e, _ = e.nextIndexed(); e != nil {
- t.Errorf("%d: expected nil entry; found %d", i, e.elems)
- }
- }
-}
-
-func TestRemove(t *testing.T) {
- const n = 5
- for i := int64(0); i < 1<<n; i++ {
- es := makeList(n)
- mask := strconv.FormatInt(i+(1<<n), 2)
- for i, c := range mask {
- if c == '0' {
- es[i].remove()
- }
- }
- e := es[0]
- for i, c := range mask {
- if c == '1' {
- if e != es[i] {
- t.Errorf("%d: expected entry %d; found %d", i, es[i].elems, e.elems)
- }
- e, _ = e.nextIndexed()
- }
- }
- if e != nil {
- t.Errorf("%d: expected nil entry; found %d", i, e.elems)
- }
- }
-}
-
-// nextPerm generates the next permutation of the array. The starting
-// permutation is assumed to be a list of integers sorted in increasing
order.
-// It returns false if there are no more permuations left.
-func nextPerm(a []int) bool {
- i := len(a) - 2
- for ; i >= 0; i-- {
- if a[i] < a[i+1] {
- break
- }
- }
- if i < 0 {
- return false
- }
- for j := len(a) - 1; j >= i; j-- {
- if a[j] > a[i] {
- a[i], a[j] = a[j], a[i]
- break
- }
- }
- for j := i + 1; j < (len(a)+i+1)/2; j++ {
- a[j], a[len(a)+i-j] = a[len(a)+i-j], a[j]
- }
- return true
-}
-
-func TestInsertAfter(t *testing.T) {
- const n = 5
- orig := makeList(n)
- perm := make([]int, n)
- for i := range perm {
- perm[i] = i + 1
- }
- for ok := true; ok; ok = nextPerm(perm) {
- es := makeList(n)
- last := es[0]
- for _, i := range perm {
- last.insertAfter(es[i])
- last = es[i]
- }
- for _, e := range es {
- e.elems = es[0].elems
- }
- e := es[0]
- for _, i := range perm {
- e, _ = e.nextIndexed()
- if e.runes[0] != orig[i].runes[0] {
- t.Errorf("%d:%d: expected entry %X; found %X", perm, i, orig[i].runes,
e.runes)
- break
- }
- }
- }
-}
-
-func TestInsertBefore(t *testing.T) {
- const n = 5
- orig := makeList(n)
- perm := make([]int, n)
- for i := range perm {
- perm[i] = i + 1
- }
- for ok := true; ok; ok = nextPerm(perm) {
- es := makeList(n)
- last := es[len(es)-1]
- for _, i := range perm {
- last.insertBefore(es[i])
- last = es[i]
- }
- for _, e := range es {
- e.elems = es[0].elems
- }
- e := es[0]
- for i := n - 1; i >= 0; i-- {
- e, _ = e.nextIndexed()
- if e.runes[0] != rune(perm[i]) {
- t.Errorf("%d:%d: expected entry %X; found %X", perm, i, orig[i].runes,
e.runes)
- break
- }
- }
- }
-}
-
-type entryLessTest struct {
- a, b *entry
- res bool
-}
-
-var (
- w1 = []rawCE{{w: []int{100, 20, 5, 5}}}
- w2 = []rawCE{{w: []int{101, 20, 5, 5}}}
-)
-
-var entryLessTests = []entryLessTest{
- {&entry{str: "a", elems: w1},
- &entry{str: "a", elems: w1},
- false,
- },
- {&entry{str: "a", elems: w1},
- &entry{str: "a", elems: w2},
- true,
- },
- {&entry{str: "a", elems: w1},
- &entry{str: "b", elems: w1},
- true,
- },
- {&entry{str: "a", elems: w2},
- &entry{str: "a", elems: w1},
- false,
- },
- {&entry{str: "c", elems: w1},
- &entry{str: "b", elems: w1},
- false,
- },
- {&entry{str: "a", elems: w1, logical: firstAnchor},
- &entry{str: "a", elems: w1},
- true,
- },
- {&entry{str: "a", elems: w1},
- &entry{str: "b", elems: w1, logical: firstAnchor},
- false,
- },
- {&entry{str: "b", elems: w1},
- &entry{str: "a", elems: w1, logical: lastAnchor},
- true,
- },
- {&entry{str: "a", elems: w1, logical: lastAnchor},
- &entry{str: "c", elems: w1},
- false,
- },
-}
-
-func TestEntryLess(t *testing.T) {
- for i, tt := range entryLessTests {
- if res := entryLess(tt.a, tt.b); res != tt.res {
- t.Errorf("%d: was %v; want %v", i, res, tt.res)
- }
- }
-}
=======================================
--- /src/pkg/exp/locale/collate/build/table.go Wed Jan 23 05:15:51 2013
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package build
-
-import (
- "fmt"
- "io"
- "reflect"
-)
-
-// table is an intermediate structure that roughly resembles the table in
collate.
-// It implements the non-exported interface collate.tableInitializer
-type table struct {
- index trie // main trie
- root *trieHandle
-
- // expansion info
- expandElem []uint32
-
- // contraction info
- contractTries contractTrieSet
- contractElem []uint32
- maxContractLen int
- variableTop uint32
-}
-
-func (t *table) TrieIndex() []uint16 {
- return t.index.index
-}
-
-func (t *table) TrieValues() []uint32 {
- return t.index.values
-}
-
-func (t *table) FirstBlockOffsets() (i, v uint16) {
- return t.root.lookupStart, t.root.valueStart
-}
-
-func (t *table) ExpandElems() []uint32 {
- return t.expandElem
-}
-
-func (t *table) ContractTries() []struct{ l, h, n, i uint8 } {
- return t.contractTries
-}
-
-func (t *table) ContractElems() []uint32 {
- return t.contractElem
-}
-
-func (t *table) MaxContractLen() int {
- return t.maxContractLen
-}
-
-func (t *table) VariableTop() uint32 {
- return t.variableTop
-}
-
-// print writes the table as Go compilable code to w. It prefixes the
-// variable names with name. It returns the number of bytes written
-// and the size of the resulting table.
-func (t *table) fprint(w io.Writer, name string) (n, size int, err error) {
- update := func(nn, sz int, e error) {
- n += nn
- if err == nil {
- err = e
- }
- size += sz
- }
- // Write arrays needed for the structure.
- update(printColElems(w, t.expandElem, name+"ExpandElem"))
- update(printColElems(w, t.contractElem, name+"ContractElem"))
- update(t.index.printArrays(w, name))
- update(t.contractTries.printArray(w, name))
-
- nn, e := fmt.Fprintf(w, "// Total size of %sTable is %d bytes\n", name,
size)
- update(nn, 0, e)
- return
-}
-
-func (t *table) fprintIndex(w io.Writer, h *trieHandle) (n int, err error)
{
- p := func(f string, a ...interface{}) {
- nn, e := fmt.Fprintf(w, f, a...)
- n += nn
- if err == nil {
- err = e
- }
- }
- p("tableIndex{\n")
- p("\t\tlookupOffset: 0x%x,\n", h.lookupStart)
- p("\t\tvaluesOffset: 0x%x,\n", h.valueStart)
- p("\t}")
- return
-}
-
-func printColElems(w io.Writer, a []uint32, name string) (n, sz int, err
error) {
- p := func(f string, a ...interface{}) {
- nn, e := fmt.Fprintf(w, f, a...)
- n += nn
- if err == nil {
- err = e
- }
- }
- sz = len(a) * int(reflect.TypeOf(uint32(0)).Size())
- p("// %s: %d entries, %d bytes\n", name, len(a), sz)
- p("var %s = [%d]uint32 {", name, len(a))
- for i, c := range a {
- switch {
- case i%64 == 0:
- p("\n\t// Block %d, offset 0x%x\n", i/64, i)
- case (i%64)%6 == 0:
- p("\n\t")
- }
- p("0x%.8X, ", c)
- }
- p("\n}\n\n")
- return
-}
=======================================
--- /src/pkg/exp/locale/collate/build/trie.go Tue Dec 18 11:04:09 2012
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// The trie in this file is used to associate the first full character
-// in a UTF-8 string to a collation element.
-// All but the last byte in a UTF-8 byte sequence are
-// used to look up offsets in the index table to be used for the next byte.
-// The last byte is used to index into a table of collation elements.
-// This file contains the code for the generation of the trie.
-
-package build
-
-import (
- "fmt"
- "hash/fnv"
- "io"
- "reflect"
-)
-
-const (
- blockSize = 64
- blockOffset = 2 // Subtract 2 blocks to compensate for the 0x80 added to
continuation bytes.
-)
-
-type trieHandle struct {
- lookupStart uint16 // offset in table for first byte
- valueStart uint16 // offset in table for first byte
-}
-
-type trie struct {
- index []uint16
- values []uint32
-}
-
-// trieNode is the intermediate trie structure used for generating a trie.
-type trieNode struct {
- index []*trieNode
- value []uint32
- b byte
- refValue uint16
- refIndex uint16
-}
-
-func newNode() *trieNode {
- return &trieNode{
- index: make([]*trieNode, 64),
- value: make([]uint32, 128), // root node size is 128 instead of 64
- }
-}
-
-func (n *trieNode) isInternal() bool {
- return n.value != nil
-}
-
-func (n *trieNode) insert(r rune, value uint32) {
- const maskx = 0x3F // mask out two most-significant bits
- str := string(r)
- if len(str) == 1 {
- n.value[str[0]] = value
- return
- }
- for i := 0; i < len(str)-1; i++ {
- b := str[i] & maskx
- if n.index == nil {
- n.index = make([]*trieNode, blockSize)
- }
- nn := n.index[b]
- if nn == nil {
- nn = &trieNode{}
- nn.b = b
- n.index[b] = nn
- }
- n = nn
- }
- if n.value == nil {
- n.value = make([]uint32, blockSize)
- }
- b := str[len(str)-1] & maskx
- n.value[b] = value
-}
-
-type trieBuilder struct {
- t *trie
-
- roots []*trieHandle
-
- lookupBlocks []*trieNode
- valueBlocks []*trieNode
-
- lookupBlockIdx map[uint32]*trieNode
- valueBlockIdx map[uint32]*trieNode
-}
-
-func newTrieBuilder() *trieBuilder {
- index := &trieBuilder{}
- index.lookupBlocks = make([]*trieNode, 0)
- index.valueBlocks = make([]*trieNode, 0)
- index.lookupBlockIdx = make(map[uint32]*trieNode)
- index.valueBlockIdx = make(map[uint32]*trieNode)
- // The third nil is the default null block. The other two blocks
- // are used to guarantee an offset of at least 3 for each block.
- index.lookupBlocks = append(index.lookupBlocks, nil, nil, nil)
- index.t = &trie{}
- return index
-}
-
-func (b *trieBuilder) computeOffsets(n *trieNode) *trieNode {
- hasher := fnv.New32()
- if n.index != nil {
- for i, nn := range n.index {
- var vi, vv uint16
- if nn != nil {
- nn = b.computeOffsets(nn)
- n.index[i] = nn
- vi = nn.refIndex
- vv = nn.refValue
- }
- hasher.Write([]byte{byte(vi >> 8), byte(vi)})
- hasher.Write([]byte{byte(vv >> 8), byte(vv)})
- }
- h := hasher.Sum32()
- nn, ok := b.lookupBlockIdx[h]
- if !ok {
- n.refIndex = uint16(len(b.lookupBlocks)) - blockOffset
- b.lookupBlocks = append(b.lookupBlocks, n)
- b.lookupBlockIdx[h] = n
- } else {
- n = nn
- }
- } else {
- for _, v := range n.value {
- hasher.Write([]byte{byte(v >> 24), byte(v >> 16), byte(v >> 8),
byte(v)})
- }
- h := hasher.Sum32()
- nn, ok := b.valueBlockIdx[h]
- if !ok {
- n.refValue = uint16(len(b.valueBlocks)) - blockOffset
- n.refIndex = n.refValue
- b.valueBlocks = append(b.valueBlocks, n)
- b.valueBlockIdx[h] = n
- } else {
- n = nn
- }
- }
- return n
-}
-
-func (b *trieBuilder) addStartValueBlock(n *trieNode) uint16 {
- hasher := fnv.New32()
- for _, v := range n.value[:2*blockSize] {
- hasher.Write([]byte{byte(v >> 24), byte(v >> 16), byte(v >> 8), byte(v)})
- }
- h := hasher.Sum32()
- nn, ok := b.valueBlockIdx[h]
- if !ok {
- n.refValue = uint16(len(b.valueBlocks))
- n.refIndex = n.refValue
- b.valueBlocks = append(b.valueBlocks, n)
- // Add a dummy block to accommodate the double block size.
- b.valueBlocks = append(b.valueBlocks, nil)
- b.valueBlockIdx[h] = n
- } else {
- n = nn
- }
- return n.refValue
-}
-
-func genValueBlock(t *trie, n *trieNode) {
- if n != nil {
- for _, v := range n.value {
- t.values = append(t.values, v)
- }
- }
-}
-
-func genLookupBlock(t *trie, n *trieNode) {
- for _, nn := range n.index {
- v := uint16(0)
- if nn != nil {
- if n.index != nil {
- v = nn.refIndex
- } else {
- v = nn.refValue
- }
- }
- t.index = append(t.index, v)
- }
-}
-
-func (b *trieBuilder) addTrie(n *trieNode) *trieHandle {
- h := &trieHandle{}
- b.roots = append(b.roots, h)
- h.valueStart = b.addStartValueBlock(n)
- if len(b.roots) == 1 {
- // We insert a null block after the first start value block.
- // This ensures that continuation bytes UTF-8 sequences of length
- // greater than 2 will automatically hit a null block if there
- // was an undefined entry.
- b.valueBlocks = append(b.valueBlocks, nil)
- }
- n = b.computeOffsets(n)
- // Offset by one extra block as the first byte starts at 0xC0 instead of
0x80.
- h.lookupStart = n.refIndex - 1
- return h
-}
-
-// generate generates and returns the trie for n.
-func (b *trieBuilder) generate() (t *trie, err error) {
- t = b.t
- if len(b.valueBlocks) >= 1<<16 {
- return nil, fmt.Errorf("maximum number of value blocks exceeded (%d
> %d)", len(b.valueBlocks), 1<<16)
- }
- if len(b.lookupBlocks) >= 1<<16 {
- return nil, fmt.Errorf("maximum number of lookup blocks exceeded (%d
> %d)", len(b.lookupBlocks), 1<<16)
- }
- genValueBlock(t, b.valueBlocks[0])
- genValueBlock(t, &trieNode{value: make([]uint32, 64)})
- for i := 2; i < len(b.valueBlocks); i++ {
- genValueBlock(t, b.valueBlocks[i])
- }
- n := &trieNode{index: make([]*trieNode, 64)}
- genLookupBlock(t, n)
- genLookupBlock(t, n)
- genLookupBlock(t, n)
- for i := 3; i < len(b.lookupBlocks); i++ {
- genLookupBlock(t, b.lookupBlocks[i])
- }
- return b.t, nil
-}
-
-func (t *trie) printArrays(w io.Writer, name string) (n, size int, err
error) {
- p := func(f string, a ...interface{}) {
- nn, e := fmt.Fprintf(w, f, a...)
- n += nn
- if err == nil {
- err = e
- }
- }
- nv := len(t.values)
- p("// %sValues: %d entries, %d bytes\n", name, nv, nv*4)
- p("// Block 2 is the null block.\n")
- p("var %sValues = [%d]uint32 {", name, nv)
- var printnewline bool
- for i, v := range t.values {
- if i%blockSize == 0 {
- p("\n\t// Block %#x, offset %#x", i/blockSize, i)
- }
- if i%4 == 0 {
- printnewline = true
- }
- if v != 0 {
- if printnewline {
- p("\n\t")
- printnewline = false
- }
- p("%#04x:%#08x, ", i, v)
- }
- }
- p("\n}\n\n")
- ni := len(t.index)
- p("// %sLookup: %d entries, %d bytes\n", name, ni, ni*2)
- p("// Block 0 is the null block.\n")
- p("var %sLookup = [%d]uint16 {", name, ni)
- printnewline = false
- for i, v := range t.index {
- if i%blockSize == 0 {
- p("\n\t// Block %#x, offset %#x", i/blockSize, i)
- }
- if i%8 == 0 {
- printnewline = true
- }
- if v != 0 {
- if printnewline {
- p("\n\t")
- printnewline = false
- }
- p("%#03x:%#02x, ", i, v)
- }
- }
- p("\n}\n\n")
- return n, nv*4 + ni*2, err
-}
-
-func (t *trie) printStruct(w io.Writer, handle *trieHandle, name string)
(n, sz int, err error) {
- const msg
= "trie{ %sLookup[%d:], %sValues[%d:], %sLookup[:], %sValues[:]}"
- n, err = fmt.Fprintf(w, msg, name, handle.lookupStart*blockSize, name,
handle.valueStart*blockSize, name, name)
- sz += int(reflect.TypeOf(trie{}).Size())
- return
-}
=======================================
--- /src/pkg/exp/locale/collate/build/trie_test.go Tue Oct 30 13:38:01 2012
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package build
-
-import (
- "bytes"
- "fmt"
- "testing"
-)
-
-// We take the smallest, largest and an arbitrary value for each
-// of the UTF-8 sequence lengths.
-var testRunes = []rune{
- 0x01, 0x0C, 0x7F, // 1-byte sequences
- 0x80, 0x100, 0x7FF, // 2-byte sequences
- 0x800, 0x999, 0xFFFF, // 3-byte sequences
- 0x10000, 0x10101, 0x10FFFF, // 4-byte sequences
- 0x200, 0x201, 0x202, 0x210, 0x215, // five entries in one sparse block
-}
-
-func makeTestTrie(t *testing.T) trie {
- n := newNode()
- for i, r := range testRunes {
- n.insert(r, uint32(i))
- }
- idx := newTrieBuilder()
- idx.addTrie(n)
- tr, err := idx.generate()
- if err != nil {
- t.Errorf(err.Error())
- }
- return *tr
-}
-
-func TestGenerateTrie(t *testing.T) {
- testdata := makeTestTrie(t)
- buf := &bytes.Buffer{}
- testdata.printArrays(buf, "test")
- fmt.Fprintf(buf, "var testTrie = ")
- testdata.printStruct(buf, &trieHandle{19, 0}, "test")
- if output != buf.String() {
- t.Error("output differs")
- }
-}
-
-var output = `// testValues: 832 entries, 3328 bytes
-// Block 2 is the null block.
-var testValues = [832]uint32 {
- // Block 0x0, offset 0x0
- 0x000c:0x00000001,
- // Block 0x1, offset 0x40
- 0x007f:0x00000002,
- // Block 0x2, offset 0x80
- // Block 0x3, offset 0xc0
- 0x00c0:0x00000003,
- // Block 0x4, offset 0x100
- 0x0100:0x00000004,
- // Block 0x5, offset 0x140
- 0x0140:0x0000000c, 0x0141:0x0000000d, 0x0142:0x0000000e,
- 0x0150:0x0000000f,
- 0x0155:0x00000010,
- // Block 0x6, offset 0x180
- 0x01bf:0x00000005,
- // Block 0x7, offset 0x1c0
- 0x01c0:0x00000006,
- // Block 0x8, offset 0x200
- 0x0219:0x00000007,
- // Block 0x9, offset 0x240
- 0x027f:0x00000008,
- // Block 0xa, offset 0x280
- 0x0280:0x00000009,
- // Block 0xb, offset 0x2c0
- 0x02c1:0x0000000a,
- // Block 0xc, offset 0x300
- 0x033f:0x0000000b,
-}
-
-// testLookup: 640 entries, 1280 bytes
-// Block 0 is the null block.
-var testLookup = [640]uint16 {
- // Block 0x0, offset 0x0
- // Block 0x1, offset 0x40
- // Block 0x2, offset 0x80
- // Block 0x3, offset 0xc0
- 0x0e0:0x05, 0x0e6:0x06,
- // Block 0x4, offset 0x100
- 0x13f:0x07,
- // Block 0x5, offset 0x140
- 0x140:0x08, 0x144:0x09,
- // Block 0x6, offset 0x180
- 0x190:0x03,
- // Block 0x7, offset 0x1c0
- 0x1ff:0x0a,
- // Block 0x8, offset 0x200
- 0x20f:0x05,
- // Block 0x9, offset 0x240
- 0x242:0x01, 0x244:0x02,
- 0x248:0x03,
- 0x25f:0x04,
- 0x260:0x01,
- 0x26f:0x02,
- 0x270:0x04, 0x274:0x06,
-}
-
-var testTrie = trie{ testLookup[1216:], testValues[0:], testLookup[:],
testValues[:]}`
=======================================
--- /src/pkg/exp/locale/collate/collate.go Tue Feb 12 06:59:55 2013
+++ /dev/null
@@ -1,588 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package collate contains types for comparing and sorting Unicode strings
-// according to a given collation order. Package locale provides a
high-level
-// interface to collation. Users should typically use that package instead.
-package collate
-
-import (
- "bytes"
- "exp/locale/collate/colltab"
- "exp/norm"
-)
-
-// AlternateHandling identifies the various ways in which variables are
handled.
-// A rune with a primary weight lower than the variable top is considered a
-// variable.
-// See
http://www.unicode.org/reports/tr10/#Variable_Weighting for details.
-type AlternateHandling int
-
-const (
- // AltNonIgnorable turns off special handling of variables.
- AltNonIgnorable AlternateHandling = iota
-
- // AltBlanked sets variables and all subsequent primary ignorables to be
- // ignorable at all levels. This is identical to removing all variables
- // and subsequent primary ignorables from the input.
- AltBlanked
-
- // AltShifted sets variables to be ignorable for levels one through three
and
- // adds a fourth level based on the values of the ignored levels.
- AltShifted
-
- // AltShiftTrimmed is a slight variant of AltShifted that is used to
- // emulate POSIX.
- AltShiftTrimmed
-)
-
-// Collator provides functionality for comparing strings for a given
-// collation order.
-type Collator struct {
- // TODO: hide most of these options. Low-level options are set through
the locale
- // identifier (as defined by LDML) while high-level options are set
through SetOptions.
- // Using high-level options allows us to be more flexible (such as not
ignoring
- // Thai vowels for IgnoreDiacriticals) and more user-friendly (such as
allowing
- // diacritical marks to be ignored but not case without having to fiddle
with levels).
-
- // Strength sets the maximum level to use in comparison.
- Strength colltab.Level
-
- // Alternate specifies an alternative handling of variables.
- Alternate AlternateHandling
-
- // Backwards specifies the order of sorting at the secondary level.
- // This option exists predominantly to support reverse sorting of accents
in French.
- Backwards bool
-
- // TODO: implement:
- // With HiraganaQuaternary enabled, Hiragana codepoints will get lower
values
- // than all the other non-variable code points. Strength must be greater
or
- // equal to Quaternary for this to take effect.
- HiraganaQuaternary bool
-
- // If CaseLevel is true, a level consisting only of case characteristics
will
- // be inserted in front of the tertiary level. To ignore accents but take
- // cases into account, set Strength to Primary and CaseLevel to true.
- CaseLevel bool
-
- // If Numeric is true, any sequence of decimal digits (category is Nd) is
sorted
- // at a primary level with its numeric value. For example, "A-21"
< "A-123".
- Numeric bool
-
- // The largest primary value that is considered to be variable.
- variableTop uint32
-
- f norm.Form
-
- t colltab.Weigher
-
- sorter sorter
-
- _iter [2]iter
-}
-
-// An Option is used to change the behavior of Collator. They override the
-// settings passed through the locale identifier.
-type Option int
-
-const (
- Numeric Option = 1 << iota // Sort numbers numerically ("2"
< "12").
- IgnoreCase // Case-insensitive search.
- IgnoreDiacritics // Ignore diacritical marks. ("o"
== "ö").
- IgnoreWidth // Ignore full versus normal width.
- UpperFirst // Sort upper case before lower case.
- LowerFirst // Sort lower case before upper case.
- Force // Force ordering if strings are
equivalent but not equal.
-
- Loose = IgnoreDiacritics | IgnoreWidth | IgnoreCase
-)
-
-// SetOptions accepts a Options or-ed together. All previous calls to
SetOptions are ignored.
-func (c *Collator) SetOptions(o Option) {
- // TODO: implement
-}
-
-func (c *Collator) iter(i int) *iter {
- // TODO: evaluate performance for making the second iterator optional.
- return &c._iter[i]
-}
-
-// Locales returns the list of locales for which collating differs from
its parent locale.
-// The returned value should not be modified.
-func Locales() []string {
- return availableLocales
-}
-
-// New returns a new Collator initialized for the given locale.
-func New(loc string) *Collator {
- // TODO: handle locale selection according to spec.
- var t tableIndex
- if loc != "" {
- if idx, ok := locales[loc]; ok {
- t = idx
- } else {
- t = locales["root"]
- }
- }
- return NewFromTable(colltab.Init(t))
-}
-
-func NewFromTable(t colltab.Weigher) *Collator {
- c := &Collator{
- Strength: colltab.Tertiary,
- f: norm.NFD,
- t: t,
- }
- c._iter[0].init(c)
- c._iter[1].init(c)
- c.variableTop = t.Top()
- return c
-}
-
-// Buffer holds keys generated by Key and KeyString.
-type Buffer struct {
- buf [4096]byte
- key []byte
-}
-
-func (b *Buffer) init() {
- if b.key == nil {
- b.key = b.buf[:0]
- }
-}
-
-// Reset clears the buffer from previous results generated by Key and
KeyString.
-func (b *Buffer) Reset() {
- b.key = b.key[:0]
-}
-
-// Compare returns an integer comparing the two byte slices.
-// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
-func (c *Collator) Compare(a, b []byte) int {
- // TODO: skip identical prefixes once we have a fast way to detect if a
rune is
- // part of a contraction. This would lead to roughly a 10% speedup for
the colcmp regtest.
- c.iter(0).setInput(a)
- c.iter(1).setInput(b)
- if res := c.compare(); res != 0 {
- return res
- }
- if colltab.Identity == c.Strength {
- return bytes.Compare(a, b)
- }
- return 0
-}
-
-// CompareString returns an integer comparing the two strings.
-// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
-func (c *Collator) CompareString(a, b string) int {
- // TODO: skip identical prefixes once we have a fast way to detect if a
rune is
- // part of a contraction. This would lead to roughly a 10% speedup for
the colcmp regtest.
- c.iter(0).setInputString(a)
- c.iter(1).setInputString(b)
- if res := c.compare(); res != 0 {
- return res
- }
- if colltab.Identity == c.Strength {
- if a < b {
- return -1
- } else if a > b {
- return 1
- }
- }
- return 0
-}
-
-func compareLevel(f func(i *iter) int, a, b *iter) int {
- a.pce = 0
- b.pce = 0
- for {
- va := f(a)
- vb := f(b)
- if va != vb {
- if va < vb {
- return -1
- }
- return 1
- } else if va == 0 {
- break
- }
- }
- return 0
-}
-
-func (c *Collator) compare() int {
- ia, ib := c.iter(0), c.iter(1)
- // Process primary level
- if c.Alternate != AltShifted {
- // TODO: implement script reordering
- // TODO: special hiragana handling
- if res := compareLevel((*iter).nextPrimary, ia, ib); res != 0 {
- return res
- }
- } else {
- // TODO: handle shifted
- }
- if colltab.Secondary <= c.Strength {
- f := (*iter).nextSecondary
- if c.Backwards {
- f = (*iter).prevSecondary
- }
- if res := compareLevel(f, ia, ib); res != 0 {
- return res
- }
- }
- // TODO: special case handling (Danish?)
- if colltab.Tertiary <= c.Strength || c.CaseLevel {
- if res := compareLevel((*iter).nextTertiary, ia, ib); res != 0 {
- return res
- }
- // TODO: Not needed for the default value of AltNonIgnorable?
- if colltab.Quaternary <= c.Strength {
- if res := compareLevel((*iter).nextQuaternary, ia, ib); res != 0 {
- return res
- }
- }
- }
- return 0
-}
-
-// Key returns the collation key for str.
-// Passing the buffer buf may avoid memory allocations.
-// The returned slice will point to an allocation in Buffer and will remain
-// valid until the next call to buf.Reset().
-func (c *Collator) Key(buf *Buffer, str []byte) []byte {
- // See
http://www.unicode.org/reports/tr10/#Main_Algorithm for more
details.
- buf.init()
- return c.key(buf, c.getColElems(str))
-}
-
-// KeyFromString returns the collation key for str.
-// Passing the buffer buf may avoid memory allocations.
-// The returned slice will point to an allocation in Buffer and will retain
-// valid until the next call to buf.ResetKeys().
-func (c *Collator) KeyFromString(buf *Buffer, str string) []byte {
- // See
http://www.unicode.org/reports/tr10/#Main_Algorithm for more
details.
- buf.init()
- return c.key(buf, c.getColElemsString(str))
-}
-
-func (c *Collator) key(buf *Buffer, w []colltab.Elem) []byte {
- processWeights(c.Alternate, c.t.Top(), w)
- kn := len(buf.key)
- c.keyFromElems(buf, w)
- return buf.key[kn:]
-}
-
-func (c *Collator) getColElems(str []byte) []colltab.Elem {
- i := c.iter(0)
- i.setInput(str)
- for i.next() {
- }
- return i.ce
-}
-
-func (c *Collator) getColElemsString(str string) []colltab.Elem {
- i := c.iter(0)
- i.setInputString(str)
- for i.next() {
- }
- return i.ce
-}
-
-type iter struct {
- bytes []byte
- str string
-
- wa [512]colltab.Elem
- ce []colltab.Elem
- pce int
- nce int // nce <= len(nce)
-
- prevCCC uint8
- pStarter int
-
- t colltab.Weigher
-}
-
-func (i *iter) init(c *Collator) {
- i.t = c.t
- i.ce = i.wa[:0]
-}
-
-func (i *iter) reset() {
- i.ce = i.ce[:0]
- i.nce = 0
- i.prevCCC = 0
- i.pStarter = 0
-}
-
-func (i *iter) setInput(s []byte) *iter {
- i.bytes = s
- i.str = ""
- i.reset()
- return i
-}
-
-func (i *iter) setInputString(s string) *iter {
- i.str = s
- i.bytes = nil
- i.reset()
- return i
-}
-
-func (i *iter) done() bool {
- return len(i.str) == 0 && len(i.bytes) == 0
-}
-
-func (i *iter) tail(n int) {
- if i.bytes == nil {
- i.str = i.str[n:]
- } else {
- i.bytes = i.bytes[n:]
- }
-}
-
-func (i *iter) appendNext() int {
- var sz int
- if i.bytes == nil {
- i.ce, sz = i.t.AppendNextString(i.ce, i.str)
- } else {
- i.ce, sz = i.t.AppendNext(i.ce, i.bytes)
- }
- return sz
-}
-
-// next appends Elems to the internal array until it adds an element with
CCC=0.
-// In the majority of cases, a Elem with a primary value > 0 will have
-// a CCC of 0. The CCC values of colation elements are also used to detect
if the
-// input string was not normalized and to adjust the result accordingly.
-func (i *iter) next() bool {
- for !i.done() {
- p0 := len(i.ce)
- sz := i.appendNext()
- i.tail(sz)
- last := len(i.ce) - 1
- if ccc := i.ce[last].CCC(); ccc == 0 {
- i.nce = len(i.ce)
- i.pStarter = last
- i.prevCCC = 0
- return true
- } else if p0 < last && i.ce[p0].CCC() == 0 {
- // set i.nce to only cover part of i.ce for which ccc == 0 and
- // use rest the next call to next.
- for p0++; p0 < last && i.ce[p0].CCC() == 0; p0++ {
- }
- i.nce = p0
- i.pStarter = p0 - 1
- i.prevCCC = ccc
- return true
- } else if ccc < i.prevCCC {
- i.doNorm(p0, ccc) // should be rare for most common cases
- } else {
- i.prevCCC = ccc
- }
- }
- if len(i.ce) != i.nce {
- i.nce = len(i.ce)
- return true
- }
- return false
-}
-
-// nextPlain is the same as next, but does not "normalize" the collation
-// elements.
-// TODO: remove this function. Using this instead of next does not seem
-// to improve performance in any significant way. We retain this until
-// later for evaluation purposes.
-func (i *iter) nextPlain() bool {
- if i.done() {
- return false
- }
- sz := i.appendNext()
- i.tail(sz)
- i.nce = len(i.ce)
- return true
-}
-
-const maxCombiningCharacters = 30
-
-// doNorm reorders the collation elements in i.ce.
-// It assumes that blocks of collation elements added with appendNext
-// either start and end with the same CCC or start with CCC == 0.
-// This allows for a single insertion point for the entire block.
-// The correctness of this assumption is verified in builder.go.
-func (i *iter) doNorm(p int, ccc uint8) {
- if p-i.pStarter > maxCombiningCharacters {
- i.prevCCC = i.ce[len(i.ce)-1].CCC()
- i.pStarter = len(i.ce) - 1
- return
- }
- n := len(i.ce)
- k := p
- for p--; p > i.pStarter && ccc < i.ce[p-1].CCC(); p-- {
- }
- i.ce = append(i.ce, i.ce[p:k]...)
- copy(i.ce[p:], i.ce[k:])
- i.ce = i.ce[:n]
-}
-
-func (i *iter) nextPrimary() int {
- for {
- for ; i.pce < i.nce; i.pce++ {
- if v := i.ce[i.pce].Primary(); v != 0 {
- i.pce++
- return v
- }
- }
- if !i.next() {
- return 0
- }
- }
- panic("should not reach here")
-}
-
-func (i *iter) nextSecondary() int {
- for ; i.pce < len(i.ce); i.pce++ {
- if v := i.ce[i.pce].Secondary(); v != 0 {
- i.pce++
- return v
- }
- }
- return 0
-}
-
-func (i *iter) prevSecondary() int {
- for ; i.pce < len(i.ce); i.pce++ {
- if v := i.ce[len(i.ce)-i.pce-1].Secondary(); v != 0 {
- i.pce++
- return v
- }
- }
- return 0
-}
-
-func (i *iter) nextTertiary() int {
- for ; i.pce < len(i.ce); i.pce++ {
- if v := i.ce[i.pce].Tertiary(); v != 0 {
- i.pce++
- return int(v)
- }
- }
- return 0
-}
-
-func (i *iter) nextQuaternary() int {
- for ; i.pce < len(i.ce); i.pce++ {
- if v := i.ce[i.pce].Quaternary(); v != 0 {
- i.pce++
- return v
- }
- }
- return 0
-}
-
-func appendPrimary(key []byte, p int) []byte {
- // Convert to variable length encoding; supports up to 23 bits.
- if p <= 0x7FFF {
- key = append(key, uint8(p>>8), uint8(p))
- } else {
- key = append(key, uint8(p>>16)|0x80, uint8(p>>8), uint8(p))
- }
- return key
-}
-
-// keyFromElems converts the weights ws to a compact sequence of bytes.
-// The result will be appended to the byte buffer in buf.
-func (c *Collator) keyFromElems(buf *Buffer, ws []colltab.Elem) {
- for _, v := range ws {
- if w := v.Primary(); w > 0 {
- buf.key = appendPrimary(buf.key, w)
- }
- }
- if colltab.Secondary <= c.Strength {
- buf.key = append(buf.key, 0, 0)
- // TODO: we can use one 0 if we can guarantee that all non-zero weights
are > 0xFF.
- if !c.Backwards {
- for _, v := range ws {
- if w := v.Secondary(); w > 0 {
- buf.key = append(buf.key, uint8(w>>8), uint8(w))
- }
- }
- } else {
- for i := len(ws) - 1; i >= 0; i-- {
- if w := ws[i].Secondary(); w > 0 {
- buf.key = append(buf.key, uint8(w>>8), uint8(w))
- }
- }
- }
- } else if c.CaseLevel {
- buf.key = append(buf.key, 0, 0)
- }
- if colltab.Tertiary <= c.Strength || c.CaseLevel {
- buf.key = append(buf.key, 0, 0)
- for _, v := range ws {
- if w := v.Tertiary(); w > 0 {
- buf.key = append(buf.key, uint8(w))
- }
- }
- // Derive the quaternary weights from the options and other levels.
- // Note that we represent MaxQuaternary as 0xFF. The first byte of the
- // representation of a primary weight is always smaller than 0xFF,
- // so using this single byte value will compare correctly.
- if colltab.Quaternary <= c.Strength && c.Alternate >= AltShifted {
- if c.Alternate == AltShiftTrimmed {
- lastNonFFFF := len(buf.key)
- buf.key = append(buf.key, 0)
- for _, v := range ws {
- if w := v.Quaternary(); w == colltab.MaxQuaternary {
- buf.key = append(buf.key, 0xFF)
- } else if w > 0 {
- buf.key = appendPrimary(buf.key, w)
- lastNonFFFF = len(buf.key)
- }
- }
- buf.key = buf.key[:lastNonFFFF]
- } else {
- buf.key = append(buf.key, 0)
- for _, v := range ws {
- if w := v.Quaternary(); w == colltab.MaxQuaternary {
- buf.key = append(buf.key, 0xFF)
- } else if w > 0 {
- buf.key = appendPrimary(buf.key, w)
- }
- }
- }
- }
- }
-}
-
-func processWeights(vw AlternateHandling, top uint32, wa []colltab.Elem) {
- ignore := false
- vtop := int(top)
- switch vw {
- case AltShifted, AltShiftTrimmed:
- for i := range wa {
- if p := wa[i].Primary(); p <= vtop && p != 0 {
- wa[i] = colltab.MakeQuaternary(p)
- ignore = true
- } else if p == 0 {
- if ignore {
- wa[i] = colltab.Ignore
- }
- } else {
- ignore = false
- }
- }
- case AltBlanked:
- for i := range wa {
- if p := wa[i].Primary(); p <= vtop && (ignore || p != 0) {
- wa[i] = colltab.Ignore
- ignore = true
- } else {
- ignore = false
- }
- }
- }
-}
=======================================
--- /src/pkg/exp/locale/collate/collate_test.go Wed Feb 27 05:09:42 2013
+++ /dev/null
@@ -1,515 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package collate
-
-import (
- "bytes"
- "exp/locale/collate/colltab"
- "testing"
-)
-
-type weightsTest struct {
- opt opts
- in, out ColElems
-}
-
-type opts struct {
- lev int
- alt AlternateHandling
- top int
-
- backwards bool
- caseLevel bool
-}
-
-func (o opts) level() colltab.Level {
- if o.lev == 0 {
- return colltab.Quaternary
- }
- return colltab.Level(o.lev - 1)
-}
-
-func makeCE(w []int) colltab.Elem {
- ce, err := colltab.MakeElem(w[0], w[1], w[2], uint8(w[3]))
- if err != nil {
- panic(err)
- }
- return ce
-}
-
-func (o opts) collator() *Collator {
- c := &Collator{
- Strength: o.level(),
- Alternate: o.alt,
- Backwards: o.backwards,
- CaseLevel: o.caseLevel,
- variableTop: uint32(o.top),
- }
- return c
-}
-
-const (
- maxQ = 0x1FFFFF
-)
-
-func wpq(p, q int) Weights {
- return W(p, defaults.Secondary, defaults.Tertiary, q)
-}
-
-func wsq(s, q int) Weights {
- return W(0, s, defaults.Tertiary, q)
-}
-
-func wq(q int) Weights {
- return W(0, 0, 0, q)
-}
-
-var zero = W(0, 0, 0, 0)
-
-var processTests = []weightsTest{
- // Shifted
- { // simple sequence of non-variables
- opt: opts{alt: AltShifted, top: 100},
- in: ColElems{W(200), W(300), W(400)},
- out: ColElems{wpq(200, maxQ), wpq(300, maxQ), wpq(400, maxQ)},
- },
- { // first is a variable
- opt: opts{alt: AltShifted, top: 250},
- in: ColElems{W(200), W(300), W(400)},
- out: ColElems{wq(200), wpq(300, maxQ), wpq(400, maxQ)},
- },
- { // all but first are variable
- opt: opts{alt: AltShifted, top: 999},
- in: ColElems{W(1000), W(200), W(300), W(400)},
- out: ColElems{wpq(1000, maxQ), wq(200), wq(300), wq(400)},
- },
- { // first is a modifier
- opt: opts{alt: AltShifted, top: 999},
- in: ColElems{W(0, 10), W(1000)},
- out: ColElems{wsq(10, maxQ), wpq(1000, maxQ)},
- },
- { // primary ignorables
- opt: opts{alt: AltShifted, top: 250},
- in: ColElems{W(200), W(0, 10), W(300), W(0, 15), W(400)},
- out: ColElems{wq(200), zero, wpq(300, maxQ), wsq(15, maxQ), wpq(400,
maxQ)},
- },
- { // secondary ignorables
- opt: opts{alt: AltShifted, top: 250},
- in: ColElems{W(200), W(0, 0, 10), W(300), W(0, 0, 15), W(400)},
- out: ColElems{wq(200), zero, wpq(300, maxQ), W(0, 0, 15, maxQ), wpq(400,
maxQ)},
- },
- { // tertiary ignorables, no change
- opt: opts{alt: AltShifted, top: 250},
- in: ColElems{W(200), zero, W(300), zero, W(400)},
- out: ColElems{wq(200), zero, wpq(300, maxQ), zero, wpq(400, maxQ)},
- },
-
- // ShiftTrimmed (same as Shifted)
- { // simple sequence of non-variables
- opt: opts{alt: AltShiftTrimmed, top: 100},
- in: ColElems{W(200), W(300), W(400)},
- out: ColElems{wpq(200, maxQ), wpq(300, maxQ), wpq(400, maxQ)},
- },
- { // first is a variable
- opt: opts{alt: AltShiftTrimmed, top: 250},
- in: ColElems{W(200), W(300), W(400)},
- out: ColElems{wq(200), wpq(300, maxQ), wpq(400, maxQ)},
- },
- { // all but first are variable
- opt: opts{alt: AltShiftTrimmed, top: 999},
- in: ColElems{W(1000), W(200), W(300), W(400)},
- out: ColElems{wpq(1000, maxQ), wq(200), wq(300), wq(400)},
- },
- { // first is a modifier
- opt: opts{alt: AltShiftTrimmed, top: 999},
- in: ColElems{W(0, 10), W(1000)},
- out: ColElems{wsq(10, maxQ), wpq(1000, maxQ)},
- },
- { // primary ignorables
- opt: opts{alt: AltShiftTrimmed, top: 250},
- in: ColElems{W(200), W(0, 10), W(300), W(0, 15), W(400)},
- out: ColElems{wq(200), zero, wpq(300, maxQ), wsq(15, maxQ), wpq(400,
maxQ)},
- },
- { // secondary ignorables
- opt: opts{alt: AltShiftTrimmed, top: 250},
- in: ColElems{W(200), W(0, 0, 10), W(300), W(0, 0, 15), W(400)},
- out: ColElems{wq(200), zero, wpq(300, maxQ), W(0, 0, 15, maxQ), wpq(400,
maxQ)},
- },
- { // tertiary ignorables, no change
- opt: opts{alt: AltShiftTrimmed, top: 250},
- in: ColElems{W(200), zero, W(300), zero, W(400)},
- out: ColElems{wq(200), zero, wpq(300, maxQ), zero, wpq(400, maxQ)},
- },
-
- // Blanked
- { // simple sequence of non-variables
- opt: opts{alt: AltBlanked, top: 100},
- in: ColElems{W(200), W(300), W(400)},
- out: ColElems{W(200), W(300), W(400)},
- },
- { // first is a variable
- opt: opts{alt: AltBlanked, top: 250},
- in: ColElems{W(200), W(300), W(400)},
- out: ColElems{zero, W(300), W(400)},
- },
- { // all but first are variable
- opt: opts{alt: AltBlanked, top: 999},
- in: ColElems{W(1000), W(200), W(300), W(400)},
- out: ColElems{W(1000), zero, zero, zero},
- },
- { // first is a modifier
- opt: opts{alt: AltBlanked, top: 999},
- in: ColElems{W(0, 10), W(1000)},
- out: ColElems{W(0, 10), W(1000)},
- },
- { // primary ignorables
- opt: opts{alt: AltBlanked, top: 250},
- in: ColElems{W(200), W(0, 10), W(300), W(0, 15), W(400)},
- out: ColElems{zero, zero, W(300), W(0, 15), W(400)},
- },
- { // secondary ignorables
- opt: opts{alt: AltBlanked, top: 250},
- in: ColElems{W(200), W(0, 0, 10), W(300), W(0, 0, 15), W(400)},
- out: ColElems{zero, zero, W(300), W(0, 0, 15), W(400)},
- },
- { // tertiary ignorables, no change
- opt: opts{alt: AltBlanked, top: 250},
- in: ColElems{W(200), zero, W(300), zero, W(400)},
- out: ColElems{zero, zero, W(300), zero, W(400)},
- },
-
- // Non-ignorable: input is always equal to output.
- { // all but first are variable
- opt: opts{alt: AltNonIgnorable, top: 999},
- in: ColElems{W(1000), W(200), W(300), W(400)},
- out: ColElems{W(1000), W(200), W(300), W(400)},
- },
- { // primary ignorables
- opt: opts{alt: AltNonIgnorable, top: 250},
- in: ColElems{W(200), W(0, 10), W(300), W(0, 15), W(400)},
- out: ColElems{W(200), W(0, 10), W(300), W(0, 15), W(400)},
- },
- { // secondary ignorables
- opt: opts{alt: AltNonIgnorable, top: 250},
- in: ColElems{W(200), W(0, 0, 10), W(300), W(0, 0, 15), W(400)},
- out: ColElems{W(200), W(0, 0, 10), W(300), W(0, 0, 15), W(400)},
- },
- { // tertiary ignorables, no change
- opt: opts{alt: AltNonIgnorable, top: 250},
- in: ColElems{W(200), zero, W(300), zero, W(400)},
- out: ColElems{W(200), zero, W(300), zero, W(400)},
- },
-}
-
-func TestProcessWeights(t *testing.T) {
- for i, tt := range processTests {
- in := convertFromWeights(
tt.in)
- out := convertFromWeights(tt.out)
- processWeights(tt.opt.alt, uint32(tt.opt.top), in)
- for j, w := range in {
- if w != out[j] {
- t.Errorf("%d: Weights %d was %v; want %v", i, j, w, out[j])
- }
- }
- }
-}
-
-type keyFromElemTest struct {
- opt opts
- in ColElems
- out []byte
-}
-
-var defS = byte(defaults.Secondary)
-var defT = byte(defaults.Tertiary)
-
-const sep = 0 // separator byte
-
-var keyFromElemTests = []keyFromElemTest{
- { // simple primary and secondary weights.
- opts{alt: AltShifted},
- ColElems{W(0x200), W(0x7FFF), W(0, 0x30), W(0x100)},
- []byte{0x2, 0, 0x7F, 0xFF, 0x1, 0x00, // primary
- sep, sep, 0, defS, 0, defS, 0, 0x30, 0, defS, // secondary
- sep, sep, defT, defT, defT, defT, // tertiary
- sep, 0xFF, 0xFF, 0xFF, 0xFF, // quaternary
- },
- },
- { // same as first, but with zero element that need to be removed
- opts{alt: AltShifted},
- ColElems{W(0x200), zero, W(0x7FFF), W(0, 0x30), zero, W(0x100)},
- []byte{0x2, 0, 0x7F, 0xFF, 0x1, 0x00, // primary
- sep, sep, 0, defS, 0, defS, 0, 0x30, 0, defS, // secondary
- sep, sep, defT, defT, defT, defT, // tertiary
- sep, 0xFF, 0xFF, 0xFF, 0xFF, // quaternary
- },
- },
- { // same as first, with large primary values
- opts{alt: AltShifted},
- ColElems{W(0x200), W(0x8000), W(0, 0x30), W(0x12345)},
- []byte{0x2, 0, 0x80, 0x80, 0x00, 0x81, 0x23, 0x45, // primary
- sep, sep, 0, defS, 0, defS, 0, 0x30, 0, defS, // secondary
- sep, sep, defT, defT, defT, defT, // tertiary
- sep, 0xFF, 0xFF, 0xFF, 0xFF, // quaternary
- },
- },
- { // same as first, but with the secondary level backwards
- opts{alt: AltShifted, backwards: true},
- ColElems{W(0x200), W(0x7FFF), W(0, 0x30), W(0x100)},
- []byte{0x2, 0, 0x7F, 0xFF, 0x1, 0x00, // primary
- sep, sep, 0, defS, 0, 0x30, 0, defS, 0, defS, // secondary
- sep, sep, defT, defT, defT, defT, // tertiary
- sep, 0xFF, 0xFF, 0xFF, 0xFF, // quaternary
- },
- },
- { // same as first, ignoring quaternary level
- opts{alt: AltShifted, lev: 3},
- ColElems{W(0x200), zero, W(0x7FFF), W(0, 0x30), zero, W(0x100)},
- []byte{0x2, 0, 0x7F, 0xFF, 0x1, 0x00, // primary
- sep, sep, 0, defS, 0, defS, 0, 0x30, 0, defS, // secondary
- sep, sep, defT, defT, defT, defT, // tertiary
- },
- },
- { // same as first, ignoring tertiary level
- opts{alt: AltShifted, lev: 2},
- ColElems{W(0x200), zero, W(0x7FFF), W(0, 0x30), zero, W(0x100)},
- []byte{0x2, 0, 0x7F, 0xFF, 0x1, 0x00, // primary
- sep, sep, 0, defS, 0, defS, 0, 0x30, 0, defS, // secondary
- },
- },
- { // same as first, ignoring secondary level
- opts{alt: AltShifted, lev: 1},
- ColElems{W(0x200), zero, W(0x7FFF), W(0, 0x30), zero, W(0x100)},
- []byte{0x2, 0, 0x7F, 0xFF, 0x1, 0x00},
- },
- { // simple primary and secondary weights.
- opts{alt: AltShiftTrimmed, top: 0x250},
- ColElems{W(0x300), W(0x200), W(0x7FFF), W(0, 0x30), W(0x800)},
- []byte{0x3, 0, 0x7F, 0xFF, 0x8, 0x00, // primary
- sep, sep, 0, defS, 0, defS, 0, 0x30, 0, defS, // secondary
- sep, sep, defT, defT, defT, defT, // tertiary
- sep, 0xFF, 0x2, 0, // quaternary
- },
- },
- { // as first, primary with case level enabled
- opts{alt: AltShifted, lev: 1, caseLevel: true},
- ColElems{W(0x200), W(0x7FFF), W(0, 0x30), W(0x100)},
- []byte{0x2, 0, 0x7F, 0xFF, 0x1, 0x00, // primary
- sep, sep, // secondary
- sep, sep, defT, defT, defT, defT, // tertiary
- },
- },
-}
-
-func TestKeyFromElems(t *testing.T) {
- buf := Buffer{}
- for i, tt := range keyFromElemTests {
- buf.Reset()
- in := convertFromWeights(
tt.in)
- processWeights(tt.opt.alt, uint32(tt.opt.top), in)
- tt.opt.collator().keyFromElems(&buf, in)
- res := buf.key
- if len(res) != len(tt.out) {
- t.Errorf("%d: len(ws) was %d; want %d (%X should be %X)", i, len(res),
len(tt.out), res, tt.out)
- }
- n := len(res)
- if len(tt.out) < n {
- n = len(tt.out)
- }
- for j, c := range res[:n] {
- if c != tt.out[j] {
- t.Errorf("%d: byte %d was %X; want %X", i, j, c, tt.out[j])
- }
- }
- }
-}
-
-func TestGetColElems(t *testing.T) {
- for i, tt := range appendNextTests {
- c, err := makeTable(
tt.in)
- if err != nil {
- // error is reported in TestAppendNext
- continue
- }
- // Create one large test per table
- str := make([]byte, 0, 4000)
- out := ColElems{}
- for len(str) < 3000 {
- for _, chk := range tt.chk {
- str = append(str,
chk.in[:chk.n]...)
- out = append(out, chk.out...)
- }
- }
- for j, chk := range append(tt.chk, check{string(str), len(str), out}) {
- out := convertFromWeights(chk.out)
- ce := c.getColElems([]byte(
chk.in)[:chk.n])
- if len(ce) != len(out) {
- t.Errorf("%d:%d: len(ws) was %d; want %d", i, j, len(ce), len(out))
- continue
- }
- cnt := 0
- for k, w := range ce {
- w, _ = colltab.MakeElem(w.Primary(), w.Secondary(), int(w.Tertiary()),
0)
- if w != out[k] {
- t.Errorf("%d:%d: Weights %d was %X; want %X", i, j, k, w, out[k])
- cnt++
- }
- if cnt > 10 {
- break
- }
- }
- }
- }
-}
-
-type keyTest struct {
- in string
- out []byte
-}
-
-var keyTests = []keyTest{
- {"abc",
- []byte{0, 100, 0, 200, 1, 44, 0, 0, 0, 32, 0, 32, 0, 32, 0, 0, 2, 2, 2,
0, 255, 255, 255},
- },
- {"a\u0301",
- []byte{0, 102, 0, 0, 0, 32, 0, 0, 2, 0, 255},
- },
- {"aaaaa",
- []byte{0, 100, 0, 100, 0, 100, 0, 100, 0, 100, 0, 0,
- 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 0,
- 2, 2, 2, 2, 2, 0,
- 255, 255, 255, 255, 255,
- },
- },
-}
-
-func TestKey(t *testing.T) {
- c, _ := makeTable(appendNextTests[4].in)
- c.Alternate = AltShifted
- c.Strength = colltab.Quaternary
- buf := Buffer{}
- keys1 := [][]byte{}
- keys2 := [][]byte{}
- for _, tt := range keyTests {
- keys1 = append(keys1, c.Key(&buf, []byte(
tt.in)))
- keys2 = append(keys2, c.KeyFromString(&buf,
tt.in))
- }
- // Separate generation from testing to ensure buffers are not overwritten.
- for i, tt := range keyTests {
- if !bytes.Equal(keys1[i], tt.out) {
- t.Errorf("%d: Key(%q) = %d; want %d", i,
tt.in, keys1[i], tt.out)
- }
- if !bytes.Equal(keys2[i], tt.out) {
- t.Errorf("%d: KeyFromString(%q) = %d; want %d", i,
tt.in, keys2[i],
tt.out)
- }
- }
-}
-
-type compareTest struct {
- a, b string
- res int // comparison result
-}
-
-var compareTests = []compareTest{
- {"a\u0301", "a", 1},
- {"a\u0301b", "ab", 1},
- {"a", "a\u0301", -1},
- {"ab", "a\u0301b", -1},
- {"bc", "a\u0301c", 1},
- {"ab", "aB", -1},
- {"a\u0301", "a\u0301", 0},
- {"a", "a", 0},
- // Only clip prefixes of whole runes.
- {"\u302E", "\u302F", 1},
- // Don't clip prefixes when last rune of prefix may be part of
contraction.
- {"a\u035E", "a\u0301\u035F", -1},
- {"a\u0301\u035Fb", "a\u0301\u035F", -1},
-}
-
-func TestCompare(t *testing.T) {
- c, _ := makeTable(appendNextTests[4].in)
- for i, tt := range compareTests {
- if res := c.Compare([]byte(tt.a), []byte(tt.b)); res != tt.res {
- t.Errorf("%d: Compare(%q, %q) == %d; want %d", i, tt.a, tt.b, res,
tt.res)
- }
- if res := c.CompareString(tt.a, tt.b); res != tt.res {
- t.Errorf("%d: CompareString(%q, %q) == %d; want %d", i, tt.a, tt.b,
res, tt.res)
- }
- }
-}
-
-func TestDoNorm(t *testing.T) {
- const div = -1 // The insertion point of the next block.
- tests := []struct {
- in, out []int
- }{
- {in: []int{4, div, 3},
- out: []int{3, 4},
- },
- {in: []int{4, div, 3, 3, 3},
- out: []int{3, 3, 3, 4},
- },
- {in: []int{0, 4, div, 3},
- out: []int{0, 3, 4},
- },
- {in: []int{0, 0, 4, 5, div, 3, 3},
- out: []int{0, 0, 3, 3, 4, 5},
- },
- {in: []int{0, 0, 1, 4, 5, div, 3, 3},
- out: []int{0, 0, 1, 3, 3, 4, 5},
- },
- {in: []int{0, 0, 1, 4, 5, div, 4, 4},
- out: []int{0, 0, 1, 4, 4, 4, 5},
- },
- }
- for j, tt := range tests {
- i := iter{}
- var w, p, s int
- for k, cc := range
tt.in {
- if cc == 0 {
- s = 0
- }
- if cc == div {
- w = 100
- p = k
- i.pStarter = s
- continue
- }
- i.ce = append(i.ce, makeCE([]int{w, defaultSecondary, 2, cc}))
- }
- i.prevCCC = i.ce[p-1].CCC()
- i.doNorm(p, i.ce[p].CCC())
- if len(i.ce) != len(tt.out) {
- t.Errorf("%d: length was %d; want %d", j, len(i.ce), len(tt.out))
- }
- prevCCC := uint8(0)
- for k, ce := range i.ce {
- if int(ce.CCC()) != tt.out[k] {
- t.Errorf("%d:%d: unexpected CCC. Was %d; want %d", j, k, ce.CCC(),
tt.out[k])
- }
- if k > 0 && ce.CCC() == prevCCC && i.ce[k-1].Primary() > ce.Primary() {
- t.Errorf("%d:%d: normalization crossed across CCC boundary.", j, k)
- }
- }
- }
- // test cutoff of large sequence of combining characters.
- result := []uint8{8, 8, 8, 5, 5}
- for o := -2; o <= 2; o++ {
- i := iter{pStarter: 2, prevCCC: 8}
- n := maxCombiningCharacters + 1 + o
- for j := 1; j < n+i.pStarter; j++ {
- i.ce = append(i.ce, makeCE([]int{100, defaultSecondary, 2, 8}))
- }
- p := len(i.ce)
- i.ce = append(i.ce, makeCE([]int{0, defaultSecondary, 2, 5}))
- i.doNorm(p, 5)
- if i.prevCCC != result[o+2] {
- t.Errorf("%d: i.prevCCC was %d; want %d", n, i.prevCCC, result[o+2])
- }
- if result[o+2] == 5 && i.pStarter != p {
- t.Errorf("%d: i.pStarter was %d; want %d", n, i.pStarter, p)
- }
- }
-}
=======================================
--- /src/pkg/exp/locale/collate/colltab/colelem.go Tue Feb 12 06:59:55 2013
+++ /dev/null
@@ -1,369 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package colltab
-
-import (
- "fmt"
- "unicode"
-)
-
-// Level identifies the collation comparison level.
-// The primary level corresponds to the basic sorting of text.
-// The secondary level corresponds to accents and related linguistic
elements.
-// The tertiary level corresponds to casing and related concepts.
-// The quaternary level is derived from the other levels by the
-// various algorithms for handling variable elements.
-type Level int
-
-const (
- Primary Level = iota
- Secondary
- Tertiary
- Quaternary
- Identity
-)
-
-const (
- defaultSecondary = 0x20
- defaultTertiary = 0x2
- maxTertiary = 0x1F
- MaxQuaternary = 0x1FFFFF // 21 bits.
-)
-
-// Elem is a representation of a collation element. This API provides ways
to encode
-// and decode Elems. Implementations of collation tables may use values
greater
-// or equal to PrivateUse for their own purposes. However, these should
never be
-// returned by AppendNext.
-type Elem uint32
-
-const (
- maxCE Elem = 0xAFFFFFFF
- PrivateUse = minContract
- minContract = 0xC0000000
- maxContract = 0xDFFFFFFF
- minExpand = 0xE0000000
- maxExpand = 0xEFFFFFFF
- minDecomp = 0xF0000000
-)
-
-type ceType int
-
-const (
- ceNormal ceType = iota // ceNormal includes implicits (ce == 0)
- ceContractionIndex // rune can be a start of a contraction
- ceExpansionIndex // rune expands into a sequence of
collation elements
- ceDecompose // rune expands using NFKC decomposition
-)
-
-func (ce Elem) ctype() ceType {
- if ce <= maxCE {
- return ceNormal
- }
- if ce <= maxContract {
- return ceContractionIndex
- } else {
- if ce <= maxExpand {
- return ceExpansionIndex
- }
- return ceDecompose
- }
- panic("should not reach here")
- return ceType(-1)
-}
-
-// For normal collation elements, we assume that a collation element
either has
-// a primary or non-default secondary value, not both.
-// Collation elements with a primary value are of the form
-// 01pppppp pppppppp ppppppp0 ssssssss
-// - p* is primary collation value
-// - s* is the secondary collation value
-// 00pppppp pppppppp ppppppps sssttttt, where
-// - p* is primary collation value
-// - s* offset of secondary from default value.
-// - t* is the tertiary collation value
-// 100ttttt cccccccc pppppppp pppppppp
-// - t* is the tertiar collation value
-// - c* is the cannonical combining class
-// - p* is the primary collation value
-// Collation elements with a secondary value are of the form
-// 1010cccc ccccssss ssssssss tttttttt, where
-// - c* is the canonical combining class
-// - s* is the secondary collation value
-// - t* is the tertiary collation value
-// 11qqqqqq qqqqqqqq qqqqqqq0 00000000
-// - q* quaternary value
-const (
- ceTypeMask = 0xC0000000
- ceTypeMaskExt = 0xE0000000
- ceIgnoreMask = 0xF00FFFFF
- ceType1 = 0x40000000
- ceType2 = 0x00000000
- ceType3or4 = 0x80000000
- ceType4 = 0xA0000000
- ceTypeQ = 0xC0000000
- Ignore = ceType4
- firstNonPrimary = 0x80000000
- lastSpecialPrimary = 0xA0000000
- secondaryMask = 0x80000000
- hasTertiaryMask = 0x40000000
- primaryValueMask = 0x3FFFFE00
- maxPrimaryBits = 21
- compactPrimaryBits = 16
- maxSecondaryBits = 12
- maxTertiaryBits = 8
- maxCCCBits = 8
- maxSecondaryCompactBits = 8
- maxSecondaryDiffBits = 4
- maxTertiaryCompactBits = 5
- primaryShift = 9
- compactSecondaryShift = 5
- minCompactSecondary = defaultSecondary - 4
-)
-
-func makeImplicitCE(primary int) Elem {
- return ceType1 | Elem(primary<<primaryShift) | defaultSecondary
-}
-
-// MakeElem returns an Elem for the given values. It will return an error
-// if the given combination of values is invalid.
-func MakeElem(primary, secondary, tertiary int, ccc uint8) (Elem, error) {
- if w := primary; w >= 1<<maxPrimaryBits || w < 0 {
- return 0, fmt.Errorf("makeCE: primary weight out of bounds: %x >= %x",
w, 1<<maxPrimaryBits)
- }
- if w := secondary; w >= 1<<maxSecondaryBits || w < 0 {
- return 0, fmt.Errorf("makeCE: secondary weight out of bounds: %x >= %x",
w, 1<<maxSecondaryBits)
- }
- if w := tertiary; w >= 1<<maxTertiaryBits || w < 0 {
- return 0, fmt.Errorf("makeCE: tertiary weight out of bounds: %x >= %x",
w, 1<<maxTertiaryBits)
- }
- ce := Elem(0)
- if primary != 0 {
- if ccc != 0 {
- if primary >= 1<<compactPrimaryBits {
- return 0, fmt.Errorf("makeCE: primary weight with non-zero CCC out of
bounds: %x >= %x", primary, 1<<compactPrimaryBits)
- }
- if secondary != defaultSecondary {
- return 0, fmt.Errorf("makeCE: cannot combine non-default secondary
value (%x) with non-zero CCC (%x)", secondary, ccc)
- }
- ce = Elem(tertiary << (compactPrimaryBits + maxCCCBits))
- ce |= Elem(ccc) << compactPrimaryBits
- ce |= Elem(primary)
- ce |= ceType3or4
- } else if tertiary == defaultTertiary {
- if secondary >= 1<<maxSecondaryCompactBits {
- return 0, fmt.Errorf("makeCE: secondary weight with non-zero primary
out of bounds: %x >= %x", secondary, 1<<maxSecondaryCompactBits)
- }
- ce = Elem(primary<<(maxSecondaryCompactBits+1) + secondary)
- ce |= ceType1
- } else {
- d := secondary - defaultSecondary + maxSecondaryDiffBits
- if d >= 1<<maxSecondaryDiffBits || d < 0 {
- return 0, fmt.Errorf("makeCE: secondary weight diff out of bounds: %x
< 0 || %x > %x", d, d, 1<<maxSecondaryDiffBits)
- }
- if tertiary >= 1<<maxTertiaryCompactBits {
- return 0, fmt.Errorf("makeCE: tertiary weight with non-zero primary
out of bounds: %x > %x", tertiary, 1<<maxTertiaryCompactBits)
- }
- ce = Elem(primary<<maxSecondaryDiffBits + d)
- ce = ce<<maxTertiaryCompactBits + Elem(tertiary)
- }
- } else {
- ce = Elem(secondary<<maxTertiaryBits + tertiary)
- ce += Elem(ccc) << (maxSecondaryBits + maxTertiaryBits)
- ce |= ceType4
- }
- return ce, nil
-}
-
-// MakeQuaternary returns an Elem with the given quaternary value.
-func MakeQuaternary(v int) Elem {
- return ceTypeQ | Elem(v<<primaryShift)
-}
-
-// Mask sets weights for any level smaller than l to 0.
-// The resulting Elem can be used to test for equality with
-// other Elems to which the same mask has been applied.
-func (ce Elem) Mask(l Level) uint32 {
- return 0
-}
-
-// CCC returns the canoncial combining class associated with the
underlying character,
-// if applicable, or 0 otherwise.
-func (ce Elem) CCC() uint8 {
- if ce&ceType3or4 != 0 {
- if ce&ceType4 == ceType3or4 {
- return uint8(ce >> 16)
- }
- return uint8(ce >> 20)
- }
- return 0
-}
-
-// Primary returns the primary collation weight for ce.
-func (ce Elem) Primary() int {
- if ce >= firstNonPrimary {
- if ce > lastSpecialPrimary {
- return 0
- }
- return int(uint16(ce))
- }
- return int(ce&primaryValueMask) >> primaryShift
-}
-
-// Secondary returns the secondary collation weight for ce.
-func (ce Elem) Secondary() int {
- switch ce & ceTypeMask {
- case ceType1:
- return int(uint8(ce))
- case ceType2:
- return minCompactSecondary + int((ce>>compactSecondaryShift)&0xF)
- case ceType3or4:
- if ce < ceType4 {
- return defaultSecondary
- }
- return int(ce>>8) & 0xFFF
- case ceTypeQ:
- return 0
- }
- panic("should not reach here")
-}
-
-// Tertiary returns the tertiary collation weight for ce.
-func (ce Elem) Tertiary() uint8 {
- if ce&hasTertiaryMask == 0 {
- if ce&ceType3or4 == 0 {
- return uint8(ce & 0x1F)
- }
- if ce&ceType4 == ceType4 {
- return uint8(ce)
- }
- return uint8(ce>>24) & 0x1F // type 2
- } else if ce&ceTypeMask == ceType1 {
- return defaultTertiary
- }
- // ce is a quaternary value.
- return 0
-}
-
-func (ce Elem) updateTertiary(t uint8) Elem {
- if ce&ceTypeMask == ceType1 {
- // convert to type 4
- nce := ce & primaryValueMask
- nce |= Elem(uint8(ce)-minCompactSecondary) << compactSecondaryShift
- ce = nce
- } else if ce&ceTypeMaskExt == ceType3or4 {
- ce &= ^Elem(maxTertiary << 24)
- return ce | (Elem(t) << 24)
- } else {
- // type 2 or 4
- ce &= ^Elem(maxTertiary)
- }
- return ce | Elem(t)
-}
-
-// Quaternary returns the quaternary value if explicitly specified,
-// 0 if ce == Ignore, or MaxQuaternary otherwise.
-// Quaternary values are used only for shifted variants.
-func (ce Elem) Quaternary() int {
- if ce&ceTypeMask == ceTypeQ {
- return int(ce&primaryValueMask) >> primaryShift
- } else if ce&ceIgnoreMask == Ignore {
- return 0
- }
- return MaxQuaternary
-}
-
-// Weight returns the collation weight for the given level.
-func (ce Elem) Weight(l Level) int {
- switch l {
- case Primary:
- return ce.Primary()
- case Secondary:
- return ce.Secondary()
- case Tertiary:
- return int(ce.Tertiary())
- case Quaternary:
- return ce.Quaternary()
- }
- return 0 // return 0 (ignore) for undefined levels.
-}
-
-// For contractions, collation elements are of the form
-// 110bbbbb bbbbbbbb iiiiiiii iiiinnnn, where
-// - n* is the size of the first node in the contraction trie.
-// - i* is the index of the first node in the contraction trie.
-// - b* is the offset into the contraction collation element table.
-// See contract.go for details on the contraction trie.
-const (
- maxNBits = 4
- maxTrieIndexBits = 12
- maxContractOffsetBits = 13
-)
-
-func splitContractIndex(ce Elem) (index, n, offset int) {
- n = int(ce & (1<<maxNBits - 1))
- ce >>= maxNBits
- index = int(ce & (1<<maxTrieIndexBits - 1))
- ce >>= maxTrieIndexBits
- offset = int(ce & (1<<maxContractOffsetBits - 1))
- return
-}
-
-// For expansions, Elems are of the form 11100000 00000000 bbbbbbbb
bbbbbbbb,
-// where b* is the index into the expansion sequence table.
-const maxExpandIndexBits = 16
-
-func splitExpandIndex(ce Elem) (index int) {
- return int(uint16(ce))
-}
-
-// Some runes can be expanded using NFKD decomposition. Instead of storing
the full
-// sequence of collation elements, we decompose the rune and lookup the
collation
-// elements for each rune in the decomposition and modify the tertiary
weights.
-// The Elem, in this case, is of the form 11110000 00000000 wwwwwwww
vvvvvvvv, where
-// - v* is the replacement tertiary weight for the first rune,
-// - w* is the replacement tertiary weight for the second rune,
-// Tertiary weights of subsequent runes should be replaced with
maxTertiary.
-// See
http://www.unicode.org/reports/tr10/#Compatibility_Decompositions
for more details.
-func splitDecompose(ce Elem) (t1, t2 uint8) {
- return uint8(ce), uint8(ce >> 8)
-}
-
-const (
- // These constants were taken from
http://www.unicode.org/versions/Unicode6.0.0/ch12.pdf.
- minUnified rune = 0x4E00
- maxUnified = 0x9FFF
- minCompatibility = 0xF900
- maxCompatibility = 0xFAFF
- minRare = 0x3400
- maxRare = 0x4DBF
-)
-const (
- commonUnifiedOffset = 0x10000
- rareUnifiedOffset = 0x20000 // largest rune in common is U+FAFF
- otherOffset = 0x50000 // largest rune in rare is U+2FA1D
- illegalOffset = otherOffset + int(unicode.MaxRune)
- maxPrimary = illegalOffset + 1
-)
-
-// implicitPrimary returns the primary weight for the a rune
-// for which there is no entry for the rune in the collation table.
-// We take a different approach from the one specified in
-//
http://unicode.org/reports/tr10/#Implicit_Weights,
-// but preserve the resulting relative ordering of the runes.
-func implicitPrimary(r rune) int {
- if unicode.Is(unicode.Ideographic, r) {
- if r >= minUnified && r <= maxUnified {
- // The most common case for CJK.
- return int(r) + commonUnifiedOffset
- }
- if r >= minCompatibility && r <= maxCompatibility {
- // This will typically not hit. The DUCET explicitly specifies mappings
- // for all characters that do not decompose.
- return int(r) + commonUnifiedOffset
- }
- return int(r) + rareUnifiedOffset
- }
- return int(r) + otherOffset
-}
=======================================
--- /src/pkg/exp/locale/collate/colltab/colelem_test.go Tue Feb 12 06:59:55
2013
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package colltab
-
-import (
- "testing"
- "unicode"
-)
-
-type ceTest struct {
- f func(inout []int) (Elem, ceType)
- arg []int
-}
-
-func makeCE(weights []int) Elem {
- ce, _ := MakeElem(weights[0], weights[1], weights[2], uint8(weights[3]))
- return ce
-}
-
-func makeContractIndex(index, n, offset int) Elem {
- const (
- contractID = 0xC0000000
- maxNBits = 4
- maxTrieIndexBits = 12
- maxContractOffsetBits = 13
- )
- ce := Elem(contractID)
- ce += Elem(offset << (maxNBits + maxTrieIndexBits))
- ce += Elem(index << maxNBits)
- ce += Elem(n)
- return ce
-}
-
-func makeExpandIndex(index int) Elem {
- const expandID = 0xE0000000
- return expandID + Elem(index)
-}
-
-func makeDecompose(t1, t2 int) Elem {
- const decompID = 0xF0000000
- return Elem(t2<<8+t1) + decompID
-}
-
-func normalCE(inout []int) (ce Elem, t ceType) {
- ce = makeCE(inout)
- inout[0] = ce.Primary()
- inout[1] = ce.Secondary()
- inout[2] = int(ce.Tertiary())
- inout[3] = int(ce.CCC())
- return ce, ceNormal
-}
-
-func expandCE(inout []int) (ce Elem, t ceType) {
- ce = makeExpandIndex(inout[0])
- inout[0] = splitExpandIndex(ce)
- return ce, ceExpansionIndex
-}
-
-func contractCE(inout []int) (ce Elem, t ceType) {
- ce = makeContractIndex(inout[0], inout[1], inout[2])
- i, n, o := splitContractIndex(ce)
- inout[0], inout[1], inout[2] = i, n, o
- return ce, ceContractionIndex
-}
-
-func decompCE(inout []int) (ce Elem, t ceType) {
- ce = makeDecompose(inout[0], inout[1])
- t1, t2 := splitDecompose(ce)
- inout[0], inout[1] = int(t1), int(t2)
- return ce, ceDecompose
-}
-
-var ceTests = []ceTest{
- {normalCE, []int{0, 0, 0, 0}},
- {normalCE, []int{0, 30, 3, 0}},
- {normalCE, []int{0, 30, 3, 0xFF}},
- {normalCE, []int{100, defaultSecondary, defaultTertiary, 0}},
- {normalCE, []int{100, defaultSecondary, defaultTertiary, 0xFF}},
- {normalCE, []int{100, defaultSecondary, 3, 0}},
- {normalCE, []int{0x123, defaultSecondary, 8, 0xFF}},
-
- {contractCE, []int{0, 0, 0}},
- {contractCE, []int{1, 1, 1}},
- {contractCE, []int{1, (1 << maxNBits) - 1, 1}},
- {contractCE, []int{(1 << maxTrieIndexBits) - 1, 1, 1}},
- {contractCE, []int{1, 1, (1 << maxContractOffsetBits) - 1}},
-
- {expandCE, []int{0}},
- {expandCE, []int{5}},
- {expandCE, []int{(1 << maxExpandIndexBits) - 1}},
-
- {decompCE, []int{0, 0}},
- {decompCE, []int{1, 1}},
- {decompCE, []int{0x1F, 0x1F}},
-}
-
-func TestColElem(t *testing.T) {
- for i, tt := range ceTests {
- inout := make([]int, len(tt.arg))
- copy(inout, tt.arg)
- ce, typ := tt.f(inout)
- if ce.ctype() != typ {
- t.Errorf("%d: type is %d; want %d (ColElem: %X)", i, ce.ctype(), typ,
ce)
- }
- for j, a := range tt.arg {
- if inout[j] != a {
- t.Errorf("%d: argument %d is %X; want %X (ColElem: %X)", i, j,
inout[j], a, ce)
- }
- }
- }
-}
-
-type implicitTest struct {
- r rune
- p int
-}
-
-var implicitTests = []implicitTest{
- {0x33FF, 0x533FF},
- {0x3400, 0x23400},
- {0x4DC0, 0x54DC0},
- {0x4DFF, 0x54DFF},
- {0x4E00, 0x14E00},
- {0x9FCB, 0x19FCB},
- {0xA000, 0x5A000},
- {0xF8FF, 0x5F8FF},
- {0xF900, 0x1F900},
- {0xFA23, 0x1FA23},
- {0xFAD9, 0x1FAD9},
- {0xFB00, 0x5FB00},
- {0x20000, 0x40000},
- {0x2B81C, 0x4B81C},
- {unicode.MaxRune, 0x15FFFF}, // maximum primary value
-}
-
-func TestImplicit(t *testing.T) {
- for _, tt := range implicitTests {
- if p := implicitPrimary(tt.r); p != tt.p {
- t.Errorf("%U: was %X; want %X", tt.r, p, tt.p)
- }
- }
-}
-
-func TestUpdateTertiary(t *testing.T) {
- tests := []struct {
- in, out Elem
- t uint8
- }{
- {0x4000FE20, 0x0000FE8A, 0x0A},
- {0x4000FE21, 0x0000FEAA, 0x0A},
- {0x0000FE8B, 0x0000FE83, 0x03},
- {0x82FF0188, 0x9BFF0188, 0x1B},
- {0xAFF0CC02, 0xAFF0CC1B, 0x1B},
- }
- for i, tt := range tests {
- if out := tt.in.updateTertiary(tt.t); out != tt.out {
- t.Errorf("%d: was %X; want %X", i, out, tt.out)
- }
- }
-}
=======================================
--- /src/pkg/exp/locale/collate/colltab/colltab.go Tue Feb 12 06:59:55 2013
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package colltab
-
-// A Weigher can be used as a source for Collator and Searcher.
-type Weigher interface {
- // Start finds the start of the segment that includes position p.
- Start(p int, b []byte) int
-
- // StartString finds the start of the segment that includes position p.
- StartString(p int, s string) int
-
- // AppendNext appends Elems to buf corresponding to the longest match
- // of a single character or contraction from the start of s.
- // It returns the new buf and the number of bytes consumed.
- AppendNext(buf []Elem, s []byte) (ce []Elem, n int)
-
- // AppendNextString appends Elems to buf corresponding to the longest
match
- // of a single character or contraction from the start of s.
- // It returns the new buf and the number of bytes consumed.
- AppendNextString(buf []Elem, s string) (ce []Elem, n int)
-
- // Domain returns a slice of all single characters and contractions for
which
- // collation elements are defined in this table.
- Domain() []string
-
- // Top returns the highest variable primary value.
- Top() uint32
-}
=======================================
--- /src/pkg/exp/locale/collate/colltab/contract.go Tue Feb 12 06:59:55 2013
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package colltab
-
-import "unicode/utf8"
-
-// For a description of contractTrieSet, see
exp/locale/collate/build/contract.go.
-
-type contractTrieSet []struct{ l, h, n, i uint8 }
-
-// ctScanner is used to match a trie to an input sequence.
-// A contraction may match a non-contiguous sequence of bytes in an input
string.
-// For example, if there is a contraction for <a, combining_ring>, it
should match
-// the sequence <a, combining_cedilla, combining_ring>, as
combining_cedilla does
-// not block combining_ring.
-// ctScanner does not automatically skip over non-blocking non-starters,
but rather
-// retains the state of the last match and leaves it up to the user to
continue
-// the match at the appropriate points.
-type ctScanner struct {
- states contractTrieSet
- s []byte
- n int
- index int
- pindex int
- done bool
-}
-
-type ctScannerString struct {
- states contractTrieSet
- s string
- n int
- index int
- pindex int
- done bool
-}
-
-func (t contractTrieSet) scanner(index, n int, b []byte) ctScanner {
- return ctScanner{s: b, states: t[index:], n: n}
-}
-
-func (t contractTrieSet) scannerString(index, n int, str string)
ctScannerString {
- return ctScannerString{s: str, states: t[index:], n: n}
-}
-
-// result returns the offset i and bytes consumed p so far. If no suffix
-// matched, i and p will be 0.
-func (s *ctScanner) result() (i, p int) {
- return s.index, s.pindex
-}
-
-func (s *ctScannerString) result() (i, p int) {
- return s.index, s.pindex
-}
-
-const (
- final = 0
- noIndex = 0xFF
-)
-
-// scan matches the longest suffix at the current location in the input
-// and returns the number of bytes consumed.
-func (s *ctScanner) scan(p int) int {
- pr := p // the p at the rune start
- str := s.s
- states, n := s.states, s.n
- for i := 0; i < n && p < len(str); {
- e := states[i]
- c := str[p]
- // TODO: a significant number of contractions are of a form that
- // cannot match discontiguous UTF-8 in a normalized string. We could let
- // a negative value of e.n mean that we can set s.done = true and avoid
- // the need for additional matches.
- if c >= e.l {
- if e.l == c {
- p++
- if e.i != noIndex {
- s.index = int(e.i)
- s.pindex = p
- }
- if e.n != final {
- i, states, n = 0, states[int(e.h)+n:], int(e.n)
- if p >= len(str) || utf8.RuneStart(str[p]) {
- s.states, s.n, pr = states, n, p
- }
- } else {
- s.done = true
- return p
- }
- continue
- } else if e.n == final && c <= e.h {
- p++
- s.done = true
- s.index = int(c-e.l) + int(e.i)
- s.pindex = p
- return p
- }
- }
- i++
- }
- return pr
-}
-
-// scan is a verbatim copy of ctScanner.scan.
-func (s *ctScannerString) scan(p int) int {
- pr := p // the p at the rune start
- str := s.s
- states, n := s.states, s.n
- for i := 0; i < n && p < len(str); {
- e := states[i]
- c := str[p]
- // TODO: a significant number of contractions are of a form that
- // cannot match discontiguous UTF-8 in a normalized string. We could let
- // a negative value of e.n mean that we can set s.done = true and avoid
- // the need for additional matches.
- if c >= e.l {
- if e.l == c {
- p++
- if e.i != noIndex {
- s.index = int(e.i)
- s.pindex = p
- }
- if e.n != final {
- i, states, n = 0, states[int(e.h)+n:], int(e.n)
- if p >= len(str) || utf8.RuneStart(str[p]) {
- s.states, s.n, pr = states, n, p
- }
- } else {
- s.done = true
- return p
- }
- continue
- } else if e.n == final && c <= e.h {
- p++
- s.done = true
- s.index = int(c-e.l) + int(e.i)
- s.pindex = p
- return p
- }
- }
- i++
- }
- return pr
-}
=======================================
--- /src/pkg/exp/locale/collate/colltab/contract_test.go Tue Feb 12
06:59:55 2013
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package colltab
-
-import (
- "testing"
-)
-
-type lookupStrings struct {
- str string
- offset int
- n int // bytes consumed from input
-}
-
-type LookupTest struct {
- lookup []lookupStrings
- n int
- tries contractTrieSet
-}
-
-var lookupTests = []LookupTest{
- {[]lookupStrings{
- {"abc", 1, 3},
- {"a", 0, 0},
- {"b", 0, 0},
- {"c", 0, 0},
- {"d", 0, 0},
- },
- 1,
- contractTrieSet{
- {'a', 0, 1, 0xFF},
- {'b', 0, 1, 0xFF},
- {'c', 'c', 0, 1},
- },
- },
- {[]lookupStrings{
- {"abc", 1, 3},
- {"abd", 2, 3},
- {"abe", 3, 3},
- {"a", 0, 0},
- {"ab", 0, 0},
- {"d", 0, 0},
- {"f", 0, 0},
- },
- 1,
- contractTrieSet{
- {'a', 0, 1, 0xFF},
- {'b', 0, 1, 0xFF},
- {'c', 'e', 0, 1},
- },
- },
- {[]lookupStrings{
- {"abc", 1, 3},
- {"ab", 2, 2},
- {"a", 3, 1},
- {"abcd", 1, 3},
- {"abe", 2, 2},
- },
- 1,
- contractTrieSet{
- {'a', 0, 1, 3},
- {'b', 0, 1, 2},
- {'c', 'c', 0, 1},
- },
- },
- {[]lookupStrings{
- {"abc", 1, 3},
- {"abd", 2, 3},
- {"ab", 3, 2},
- {"ac", 4, 2},
- {"a", 5, 1},
- {"b", 6, 1},
- {"ba", 6, 1},
- },
- 2,
- contractTrieSet{
- {'b', 'b', 0, 6},
- {'a', 0, 2, 5},
- {'c', 'c', 0, 4},
- {'b', 0, 1, 3},
- {'c', 'd', 0, 1},
- },
- },
- {[]lookupStrings{
- {"bcde", 2, 4},
- {"bc", 7, 2},
- {"ab", 6, 2},
- {"bcd", 5, 3},
- {"abcd", 1, 4},
- {"abc", 4, 3},
- {"bcdf", 3, 4},
- },
- 2,
- contractTrieSet{
- {'b', 3, 1, 0xFF},
- {'a', 0, 1, 0xFF},
- {'b', 0, 1, 6},
- {'c', 0, 1, 4},
- {'d', 'd', 0, 1},
- {'c', 0, 1, 7},
- {'d', 0, 1, 5},
- {'e', 'f', 0, 2},
- },
- },
-}
-
-func lookup(c *contractTrieSet, nnode int, s []uint8) (i, n int) {
- scan := c.scanner(0, nnode, s)
- scan.scan(0)
- return scan.result()
-}
-
-func TestLookupContraction(t *testing.T) {
- for i, tt := range lookupTests {
- cts := contractTrieSet(tt.tries)
- for j, lu := range tt.lookup {
- str := lu.str
- for _, s := range []string{str, str + "X"} {
- const msg = `%d:%d: %s of "%s" %v; want %v`
- offset, n := lookup(&cts, tt.n, []byte(s))
- if offset != lu.offset {
- t.Errorf(msg, i, j, "offset", s, offset, lu.offset)
- }
- if n != lu.n {
- t.Errorf(msg, i, j, "bytes consumed", s, n, len(str))
- }
- }
- }
- }
-}
=======================================
--- /src/pkg/exp/locale/collate/colltab/export.go Tue Feb 12 06:59:55 2013
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package colltab
-
-// Init is for internal use only.
-func Init(data interface{}) Weigher {
- init, ok := data.(tableInitializer)
- if !ok {
- return nil
- }
- t := &table{}
- loff, voff := init.FirstBlockOffsets()
- t.index.index = init.TrieIndex()
- t.index.index0 = t.index.index[blockSize*int(loff):]
- t.index.values = init.TrieValues()
- t.index.values0 = t.index.values[blockSize*int(voff):]
- t.expandElem = init.ExpandElems()
- t.contractTries = init.ContractTries()
- t.contractElem = init.ContractElems()
- t.maxContractLen = init.MaxContractLen()
- t.variableTop = init.VariableTop()
- return t
-}
-
-type tableInitializer interface {
- TrieIndex() []uint16
- TrieValues() []uint32
- FirstBlockOffsets() (lookup, value uint16)
- ExpandElems() []uint32
- ContractTries() []struct{ l, h, n, i uint8 }
- ContractElems() []uint32
- MaxContractLen() int
- VariableTop() uint32
-}
=======================================
--- /src/pkg/exp/locale/collate/colltab/table.go Tue Feb 12 06:59:55 2013
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package colltab
-
-import (
- "exp/norm"
- "unicode/utf8"
-)
-
-// table holds all collation data for a given collation ordering.
-type table struct {
- index trie // main trie
-
- // expansion info
- expandElem []uint32
-
- // contraction info
- contractTries contractTrieSet
- contractElem []uint32
- maxContractLen int
- variableTop uint32
-}
-
-func (t *table) AppendNext(w []Elem, b []byte) (res []Elem, n int) {
- return t.appendNext(w, source{bytes: b})
-}
-
-func (t *table) AppendNextString(w []Elem, s string) (res []Elem, n int) {
- return t.appendNext(w, source{str: s})
-}
-
-func (t *table) Start(p int, b []byte) int {
- // TODO: implement
- panic("not implemented")
-}
-
-func (t *table) StartString(p int, s string) int {
- // TODO: implement
- panic("not implemented")
-}
-
-func (t *table) Domain() []string {
- // TODO: implement
- panic("not implemented")
-}
-
-func (t *table) Top() uint32 {
- return t.variableTop
-}
-
-type source struct {
- str string
- bytes []byte
-}
-
-func (src *source) lookup(t *table) (ce Elem, sz int) {
- if src.bytes == nil {
- return t.index.lookupString(src.str)
- }
- return t.index.lookup(src.bytes)
-}
-
-func (src *source) tail(sz int) {
- if src.bytes == nil {
- src.str = src.str[sz:]
- } else {
- src.bytes = src.bytes[sz:]
- }
-}
-
-func (src *source) nfd(buf []byte, end int) []byte {
- if src.bytes == nil {
- return norm.NFD.AppendString(buf[:0], src.str[:end])
- }
- return norm.NFD.Append(buf[:0], src.bytes[:end]...)
-}
-
-func (src *source) rune() (r rune, sz int) {
- if src.bytes == nil {
- return utf8.DecodeRuneInString(src.str)
- }
- return utf8.DecodeRune(src.bytes)
-}
-
-func (src *source) properties(f norm.Form) norm.Properties {
- if src.bytes == nil {
- return f.PropertiesString(src.str)
- }
- return f.Properties(src.bytes)
-}
-
-// appendNext appends the weights corresponding to the next rune or
-// contraction in s. If a contraction is matched to a discontinuous
-// sequence of runes, the weights for the interstitial runes are
-// appended as well. It returns a new slice that includes the appended
-// weights and the number of bytes consumed from s.
-func (t *table) appendNext(w []Elem, src source) (res []Elem, n int) {
- ce, sz := src.lookup(t)
- tp := ce.ctype()
- if tp == ceNormal {
- if ce == 0 {
- r, _ := src.rune()
- const (
- hangulSize = 3
- firstHangul = 0xAC00
- lastHangul = 0xD7A3
- )
- if r >= firstHangul && r <= lastHangul {
- // TODO: performance can be considerably improved here.
- n = sz
- var buf [16]byte // Used for decomposing Hangul.
- for b := src.nfd(buf[:0], hangulSize); len(b) > 0; b = b[sz:] {
- ce, sz = t.index.lookup(b)
- w = append(w, ce)
- }
- return w, n
- }
- ce = makeImplicitCE(implicitPrimary(r))
- }
- w = append(w, ce)
- } else if tp == ceExpansionIndex {
- w = t.appendExpansion(w, ce)
- } else if tp == ceContractionIndex {
- n := 0
- src.tail(sz)
- if src.bytes == nil {
- w, n = t.matchContractionString(w, ce, src.str)
- } else {
- w, n = t.matchContraction(w, ce, src.bytes)
- }
- sz += n
- } else if tp == ceDecompose {
- // Decompose using NFKD and replace tertiary weights.
- t1, t2 := splitDecompose(ce)
- i := len(w)
- nfkd := src.properties(norm.NFKD).Decomposition()
- for p := 0; len(nfkd) > 0; nfkd = nfkd[p:] {
- w, p = t.appendNext(w, source{bytes: nfkd})
- }
- w[i] = w[i].updateTertiary(t1)
- if i++; i < len(w) {
- w[i] = w[i].updateTertiary(t2)
- for i++; i < len(w); i++ {
- w[i] = w[i].updateTertiary(maxTertiary)
- }
- }
- }
- return w, sz
-}
-
-func (t *table) appendExpansion(w []Elem, ce Elem) []Elem {
- i := splitExpandIndex(ce)
- n := int(t.expandElem[i])
- i++
- for _, ce := range t.expandElem[i : i+n] {
- w = append(w, Elem(ce))
- }
- return w
-}
-
-func (t *table) matchContraction(w []Elem, ce Elem, suffix []byte)
([]Elem, int) {
- index, n, offset := splitContractIndex(ce)
-
- scan := t.contractTries.scanner(index, n, suffix)
- buf := [norm.MaxSegmentSize]byte{}
- bufp := 0
- p := scan.scan(0)
-
- if !scan.done && p < len(suffix) && suffix[p] >= utf8.RuneSelf {
- // By now we should have filtered most cases.
- p0 := p
- bufn := 0
- rune := norm.NFD.Properties(suffix[p:])
- p += rune.Size()
- if rune.LeadCCC() != 0 {
- prevCC := rune.TrailCCC()
- // A gap may only occur in the last normalization segment.
- // This also ensures that len(scan.s) < norm.MaxSegmentSize.
- if end := norm.NFD.FirstBoundary(suffix[p:]); end != -1 {
- scan.s = suffix[:p+end]
- }
- for p < len(suffix) && !scan.done && suffix[p] >= utf8.RuneSelf {
- rune = norm.NFD.Properties(suffix[p:])
- if ccc := rune.LeadCCC(); ccc == 0 || prevCC >= ccc {
- break
- }
- prevCC = rune.TrailCCC()
- if pp := scan.scan(p); pp != p {
- // Copy the interstitial runes for later processing.
- bufn += copy(buf[bufn:], suffix[p0:p])
- if scan.pindex == pp {
- bufp = bufn
- }
- p, p0 = pp, pp
- } else {
- p += rune.Size()
- }
- }
- }
- }
- // Append weights for the matched contraction, which may be an expansion.
- i, n := scan.result()
- ce = Elem(t.contractElem[i+offset])
- if ce.ctype() == ceNormal {
- w = append(w, ce)
- } else {
- w = t.appendExpansion(w, ce)
- }
- // Append weights for the runes in the segment not part of the
contraction.
- for b, p := buf[:bufp], 0; len(b) > 0; b = b[p:] {
- w, p = t.appendNext(w, source{bytes: b})
- }
- return w, n
-}
-
-// TODO: unify the two implementations. This is best done after first
simplifying
-// the algorithm taking into account the inclusion of both NFC and NFD
forms
-// in the table.
-func (t *table) matchContractionString(w []Elem, ce Elem, suffix string)
([]Elem, int) {
- index, n, offset := splitContractIndex(ce)
-
- scan := t.contractTries.scannerString(index, n, suffix)
- buf := [norm.MaxSegmentSize]byte{}
- bufp := 0
- p := scan.scan(0)
-
- if !scan.done && p < len(suffix) && suffix[p] >= utf8.RuneSelf {
- // By now we should have filtered most cases.
- p0 := p
- bufn := 0
- rune := norm.NFD.PropertiesString(suffix[p:])
- p += rune.Size()
- if rune.LeadCCC() != 0 {
- prevCC := rune.TrailCCC()
- // A gap may only occur in the last normalization segment.
- // This also ensures that len(scan.s) < norm.MaxSegmentSize.
- if end := norm.NFD.FirstBoundaryInString(suffix[p:]); end != -1 {
- scan.s = suffix[:p+end]
- }
- for p < len(suffix) && !scan.done && suffix[p] >= utf8.RuneSelf {
- rune = norm.NFD.PropertiesString(suffix[p:])
- if ccc := rune.LeadCCC(); ccc == 0 || prevCC >= ccc {
- break
- }
- prevCC = rune.TrailCCC()
- if pp := scan.scan(p); pp != p {
- // Copy the interstitial runes for later processing.
- bufn += copy(buf[bufn:], suffix[p0:p])
- if scan.pindex == pp {
- bufp = bufn
- }
- p, p0 = pp, pp
- } else {
- p += rune.Size()
- }
- }
- }
- }
- // Append weights for the matched contraction, which may be an expansion.
- i, n := scan.result()
- ce = Elem(t.contractElem[i+offset])
- if ce.ctype() == ceNormal {
- w = append(w, ce)
- } else {
- w = t.appendExpansion(w, ce)
- }
- // Append weights for the runes in the segment not part of the
contraction.
- for b, p := buf[:bufp], 0; len(b) > 0; b = b[p:] {
- w, p = t.appendNext(w, source{bytes: b})
- }
- return w, n
-}
=======================================
--- /src/pkg/exp/locale/collate/colltab/trie.go Tue Feb 12 06:59:55 2013
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// The trie in this file is used to associate the first full character
-// in an UTF-8 string to a collation element.
-// All but the last byte in a UTF-8 byte sequence are
-// used to lookup offsets in the index table to be used for the next byte.
-// The last byte is used to index into a table of collation elements.
-// For a full description, see exp/locale/collate/build/trie.go.
-
-package colltab
-
-const blockSize = 64
-
-type trie struct {
- index0 []uint16 // index for first byte (0xC0-0xFF)
- values0 []uint32 // index for first byte (0x00-0x7F)
- index []uint16
- values []uint32
-}
-
-const (
- t1 = 0x00 // 0000 0000
- tx = 0x80 // 1000 0000
- t2 = 0xC0 // 1100 0000
- t3 = 0xE0 // 1110 0000
- t4 = 0xF0 // 1111 0000
- t5 = 0xF8 // 1111 1000
- t6 = 0xFC // 1111 1100
- te = 0xFE // 1111 1110
-)
-
-func (t *trie) lookupValue(n uint16, b byte) Elem {
- return Elem(t.values[int(n)<<6+int(b)])
-}
-
-// lookup returns the trie value for the first UTF-8 encoding in s and
-// the width in bytes of this encoding. The size will be 0 if s does not
-// hold enough bytes to complete the encoding. len(s) must be greater than
0.
-func (t *trie) lookup(s []byte) (v Elem, sz int) {
- c0 := s[0]
- switch {
- case c0 < tx:
- return Elem(t.values0[c0]), 1
- case c0 < t2:
- return 0, 1
- case c0 < t3:
- if len(s) < 2 {
- return 0, 0
- }
- i := t.index0[c0]
- c1 := s[1]
- if c1 < tx || t2 <= c1 {
- return 0, 1
- }
- return t.lookupValue(i, c1), 2
- case c0 < t4:
- if len(s) < 3 {
- return 0, 0
- }
- i := t.index0[c0]
- c1 := s[1]
- if c1 < tx || t2 <= c1 {
- return 0, 1
- }
- o := int(i)<<6 + int(c1)
- i = t.index[o]
- c2 := s[2]
- if c2 < tx || t2 <= c2 {
- return 0, 2
- }
- return t.lookupValue(i, c2), 3
- case c0 < t5:
- if len(s) < 4 {
- return 0, 0
- }
- i := t.index0[c0]
- c1 := s[1]
- if c1 < tx || t2 <= c1 {
- return 0, 1
- }
- o := int(i)<<6 + int(c1)
- i = t.index[o]
- c2 := s[2]
- if c2 < tx || t2 <= c2 {
- return 0, 2
- }
- o = int(i)<<6 + int(c2)
- i = t.index[o]
- c3 := s[3]
- if c3 < tx || t2 <= c3 {
- return 0, 3
- }
- return t.lookupValue(i, c3), 4
- }
- // Illegal rune
- return 0, 1
-}
-
-// The body of lookupString is a verbatim copy of that of lookup.
-func (t *trie) lookupString(s string) (v Elem, sz int) {
- c0 := s[0]
- switch {
- case c0 < tx:
- return Elem(t.values0[c0]), 1
- case c0 < t2:
- return 0, 1
- case c0 < t3:
- if len(s) < 2 {
- return 0, 0
- }
- i := t.index0[c0]
- c1 := s[1]
- if c1 < tx || t2 <= c1 {
- return 0, 1
- }
- return t.lookupValue(i, c1), 2
- case c0 < t4:
- if len(s) < 3 {
- return 0, 0
- }
- i := t.index0[c0]
- c1 := s[1]
- if c1 < tx || t2 <= c1 {
- return 0, 1
- }
- o := int(i)<<6 + int(c1)
- i = t.index[o]
- c2 := s[2]
- if c2 < tx || t2 <= c2 {
- return 0, 2
- }
- return t.lookupValue(i, c2), 3
- case c0 < t5:
- if len(s) < 4 {
- return 0, 0
- }
- i := t.index0[c0]
- c1 := s[1]
- if c1 < tx || t2 <= c1 {
- return 0, 1
- }
- o := int(i)<<6 + int(c1)
- i = t.index[o]
- c2 := s[2]
- if c2 < tx || t2 <= c2 {
- return 0, 2
- }
- o = int(i)<<6 + int(c2)
- i = t.index[o]
- c3 := s[3]
- if c3 < tx || t2 <= c3 {
- return 0, 3
- }
- return t.lookupValue(i, c3), 4
- }
- // Illegal rune
- return 0, 1
-}
=======================================
--- /src/pkg/exp/locale/collate/colltab/trie_test.go Tue Feb 12 06:59:55
2013
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package colltab
-
-import (
- "testing"
-)
-
-// We take the smallest, largest and an arbitrary value for each
-// of the UTF-8 sequence lengths.
-var testRunes = []rune{
- 0x01, 0x0C, 0x7F, // 1-byte sequences
- 0x80, 0x100, 0x7FF, // 2-byte sequences
- 0x800, 0x999, 0xFFFF, // 3-byte sequences
- 0x10000, 0x10101, 0x10FFFF, // 4-byte sequences
- 0x200, 0x201, 0x202, 0x210, 0x215, // five entries in one sparse block
-}
-
-// Test cases for illegal runes.
-type trietest struct {
- size int
- bytes []byte
-}
-
-var tests = []trietest{
- // illegal runes
- {1, []byte{0x80}},
- {1, []byte{0xFF}},
- {1, []byte{t2, tx - 1}},
- {1, []byte{t2, t2}},
- {2, []byte{t3, tx, tx - 1}},
- {2, []byte{t3, tx, t2}},
- {1, []byte{t3, tx - 1, tx}},
- {3, []byte{t4, tx, tx, tx - 1}},
- {3, []byte{t4, tx, tx, t2}},
- {1, []byte{t4, t2, tx, tx - 1}},
- {2, []byte{t4, tx, t2, tx - 1}},
-
- // short runes
- {0, []byte{t2}},
- {0, []byte{t3, tx}},
- {0, []byte{t4, tx, tx}},
-
- // we only support UTF-8 up to utf8.UTFMax bytes (4 bytes)
- {1, []byte{t5, tx, tx, tx, tx}},
- {1, []byte{t6, tx, tx, tx, tx, tx}},
-}
-
-func TestLookupTrie(t *testing.T) {
- for i, r := range testRunes {
- b := []byte(string(r))
- v, sz := testTrie.lookup(b)
- if int(v) != i {
- t.Errorf("lookup(%U): found value %#x, expected %#x", r, v, i)
- }
- if sz != len(b) {
- t.Errorf("lookup(%U): found size %d, expected %d", r, sz, len(b))
- }
- }
- for i, tt := range tests {
- v, sz := testTrie.lookup(tt.bytes)
- if int(v) != 0 {
- t.Errorf("lookup of illegal rune, case %d: found value %#x, expected
0", i, v)
- }
- if sz != tt.size {
- t.Errorf("lookup of illegal rune, case %d: found size %d, expected %d",
i, sz, tt.size)
- }
- }
-}
-
-// test data is taken from exp/collate/locale/build/trie_test.go
-var testValues = [832]uint32{
- 0x000c: 0x00000001,
- 0x007f: 0x00000002,
- 0x00c0: 0x00000003,
- 0x0100: 0x00000004,
- 0x0140: 0x0000000c, 0x0141: 0x0000000d, 0x0142: 0x0000000e,
- 0x0150: 0x0000000f,
- 0x0155: 0x00000010,
- 0x01bf: 0x00000005,
- 0x01c0: 0x00000006,
- 0x0219: 0x00000007,
- 0x027f: 0x00000008,
- 0x0280: 0x00000009,
- 0x02c1: 0x0000000a,
- 0x033f: 0x0000000b,
-}
-
-var testLookup = [640]uint16{
- 0x0e0: 0x05, 0x0e6: 0x06,
- 0x13f: 0x07,
- 0x140: 0x08, 0x144: 0x09,
- 0x190: 0x03,
- 0x1ff: 0x0a,
- 0x20f: 0x05,
- 0x242: 0x01, 0x244: 0x02,
- 0x248: 0x03,
- 0x25f: 0x04,
- 0x260: 0x01,
- 0x26f: 0x02,
- 0x270: 0x04, 0x274: 0x06,
-}
-
-var testTrie = trie{testLookup[6*blockSize:], testValues[:],
testLookup[:], testValues[:]}
=======================================
--- /src/pkg/exp/locale/collate/export_test.go Tue Feb 12 06:59:55 2013
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package collate
-
-// Export for testing.
-// TODO: no longer necessary. Remove at some point.
-
-import (
- "exp/locale/collate/colltab"
- "fmt"
-)
-
-const (
- defaultSecondary = 0x20
- defaultTertiary = 0x2
-)
-
-type Weights struct {
- Primary, Secondary, Tertiary, Quaternary int
-}
-
-func W(ce ...int) Weights {
- w := Weights{ce[0], defaultSecondary, defaultTertiary, 0}
- if len(ce) > 1 {
- w.Secondary = ce[1]
- }
- if len(ce) > 2 {
- w.Tertiary = ce[2]
- }
- if len(ce) > 3 {
- w.Quaternary = ce[3]
- }
- return w
-}
-func (w Weights) String() string {
- return fmt.Sprintf("[%X.%X.%X.%X]", w.Primary, w.Secondary, w.Tertiary,
w.Quaternary)
-}
-
-func convertFromWeights(ws []Weights) []colltab.Elem {
- out := make([]colltab.Elem, len(ws))
- for i, w := range ws {
- out[i], _ = colltab.MakeElem(w.Primary, w.Secondary, w.Tertiary, 0)
- if out[i] == colltab.Ignore && w.Quaternary > 0 {
- out[i] = colltab.MakeQuaternary(w.Quaternary)
- }
- }
- return out
-}
=======================================
--- /src/pkg/exp/locale/collate/index.go Tue Feb 12 06:59:55 2013
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package collate
-
-// tableIndex holds information for constructing a table
-// for a certain locale based on the main table.
-type tableIndex struct {
- lookupOffset uint32
- valuesOffset uint32
-}
-
-func (t tableIndex) TrieIndex() []uint16 {
- return mainLookup[:]
-}
-
-func (t tableIndex) TrieValues() []uint32 {
- return mainValues[:]
-}
-
-func (t tableIndex) FirstBlockOffsets() (lookup, value uint16) {
- return uint16(t.lookupOffset), uint16(t.valuesOffset)
-}
-
-func (t tableIndex) ExpandElems() []uint32 {
- return mainExpandElem[:]
-}
-
-func (t tableIndex) ContractTries() []struct{ l, h, n, i uint8 } {
- return mainCTEntries[:]
-}
-
-func (t tableIndex) ContractElems() []uint32 {
- return mainContractElem[:]
-}
-
-func (t tableIndex) MaxContractLen() int {
- return 18 // TODO: generate
-}
-
-func (t tableIndex) VariableTop() uint32 {
- return varTop
-}
=======================================
--- /src/pkg/exp/locale/collate/maketables.go Thu Feb 21 10:47:31 2013
+++ /dev/null
@@ -1,718 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-// Collation table generator.
-// Data read from the web.
-
-package main
-
-import (
- "archive/zip"
- "bufio"
- "bytes"
- "encoding/xml"
- "exp/locale/collate"
- "exp/locale/collate/build"
- "exp/locale/collate/colltab"
- "flag"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "net/http"
- "os"
- "path"
- "regexp"
- "sort"
- "strconv"
- "strings"
- "unicode"
- "unicode/utf8"
-)
-
-var (
- root = flag.String("root",
-
"
http://unicode.org/Public/UCA/"+unicode.Version+"/CollationAuxiliary.zip",
- `URL of the Default Unicode Collation Element Table (DUCET). This can be
a zip
-file containing the file allkeys_CLDR.txt or an allkeys.txt file.`)
- cldr = flag.String("cldr",
- "
http://www.unicode.org/Public/cldr/22/core.zip",
- "URL of CLDR archive.")
- test = flag.Bool("test", false,
- "test existing tables; can be used to compare web data with package
data.")
- localFiles = flag.Bool("local", false,
- "data files have been copied to the current directory; for debugging
only.")
- short = flag.Bool("short", false, `Use "short" alternatives, when
available.`)
- draft = flag.Bool("draft", false, `Use draft versions, when available.`)
- tags = flag.String("tags", "", "build tags to be included after +build
directive")
- pkg = flag.String("package", "collate",
- "the name of the package in which the generated file is to be included")
-
- tables = flagStringSetAllowAll("tables", "collate", "collate,chars",
- "comma-spearated list of tables to generate.")
- exclude = flagStringSet("exclude", "zh2", "",
- "comma-separated list of languages to exclude.")
- include = flagStringSet("include", "", "",
- "comma-separated list of languages to include. Include trumps exclude.")
- types = flagStringSetAllowAll("types", "", "",
- "comma-separated list of types that should be included in addition to
the standard type.")
-)
-
-// stringSet implements an ordered set based on a list. It implements
flag.Value
-// to allow a set to be specified as a comma-separated list.
-type stringSet struct {
- s []string
- allowed *stringSet
- dirty bool // needs compaction if true
- all bool
- allowAll bool
-}
-
-func flagStringSet(name, def, allowed, usage string) *stringSet {
- ss := &stringSet{}
- if allowed != "" {
- usage += fmt.Sprintf(" (allowed values: any of %s)", allowed)
- ss.allowed = &stringSet{}
- failOnError(ss.allowed.Set(allowed))
- }
- ss.Set(def)
- flag.Var(ss, name, usage)
- return ss
-}
-
-func flagStringSetAllowAll(name, def, allowed, usage string) *stringSet {
- ss := &stringSet{allowAll: true}
- if allowed == "" {
- flag.Var(ss, name, usage+fmt.Sprintf(` Use "all" to select all.`))
- } else {
- ss.allowed = &stringSet{}
- failOnError(ss.allowed.Set(allowed))
- flag.Var(ss, name, usage+fmt.Sprintf(` (allowed values: "all" or any
of %s)`, allowed))
- }
- ss.Set(def)
- return ss
-}
-
-func (ss stringSet) Len() int {
- return len(ss.s)
-}
-
-func (ss stringSet) String() string {
- return strings.Join(ss.s, ",")
-}
-
-func (ss *stringSet) Set(s string) error {
- if ss.allowAll && s == "all" {
- ss.s = nil
- ss.all = true
- return nil
- }
- ss.s = ss.s[:0]
- for _, s := range strings.Split(s, ",") {
- if s := strings.TrimSpace(s); s != "" {
- if ss.allowed != nil && !ss.allowed.contains(s) {
- return fmt.Errorf("unsupported value %q; must be one of %s", s,
ss.allowed)
- }
- ss.add(s)
- }
- }
- ss.compact()
- return nil
-}
-
-func (ss *stringSet) add(s string) {
- ss.s = append(ss.s, s)
- ss.dirty = true
-}
-
-func (ss *stringSet) values() []string {
- ss.compact()
- return ss.s
-}
-
-func (ss *stringSet) contains(s string) bool {
- if ss.all {
- return true
- }
- for _, v := range ss.s {
- if v == s {
- return true
- }
- }
- return false
-}
-
-func (ss *stringSet) compact() {
- if !ss.dirty {
- return
- }
- a := ss.s
- sort.Strings(a)
- k := 0
- for i := 1; i < len(a); i++ {
- if a[k] != a[i] {
- a[k+1] = a[i]
- k++
- }
- }
- ss.s = a[:k+1]
- ss.dirty = false
-}
-
-func skipLang(l string) bool {
- if include.Len() > 0 {
- return !include.contains(l)
- }
- return exclude.contains(l)
-}
-
-func skipAlt(a string) bool {
- if *draft && a == "proposed" {
- return false
- }
- if *short && a == "short" {
- return false
- }
- return true
-}
-
-func failOnError(e error) {
- if e != nil {
- log.Panic(e)
- }
-}
-
-// openReader opens the URL or file given by url and returns it as an
io.ReadCloser
-// or nil on error.
-func openReader(url *string) (io.ReadCloser, error) {
- if *localFiles {
- pwd, _ := os.Getwd()
- *url = "file://" + path.Join(pwd, path.Base(*url))
- }
- t := &http.Transport{}
- t.RegisterProtocol("file", http.NewFileTransport(http.Dir("/")))
- c := &http.Client{Transport: t}
- resp, err := c.Get(*url)
- if err != nil {
- return nil, err
- }
- if resp.StatusCode != 200 {
- return nil, fmt.Errorf(`bad GET status for "%s": %s`, *url, resp.Status)
- }
- return resp.Body, nil
-}
-
-func openArchive(url *string) *zip.Reader {
- f, err := openReader(url)
- failOnError(err)
- buffer, err := ioutil.ReadAll(f)
- f.Close()
- failOnError(err)
- archive, err := zip.NewReader(bytes.NewReader(buffer), int64(len(buffer)))
- failOnError(err)
- return archive
-}
-
-// parseUCA parses a Default Unicode Collation Element Table of the format
-// specified in
http://www.unicode.org/reports/tr10/#File_Format.
-// It returns the variable top.
-func parseUCA(builder *build.Builder) {
- var r io.ReadCloser
- var err error
- if strings.HasSuffix(*root, ".zip") {
- for _, f := range openArchive(root).File {
- if strings.HasSuffix(f.Name, "allkeys_CLDR.txt") {
- r, err = f.Open()
- }
- }
- if r == nil {
- err = fmt.Errorf("file allkeys_CLDR.txt not found in archive %q", *root)
- }
- } else {
- r, err = openReader(root)
- }
- failOnError(err)
- defer r.Close()
- scanner := bufio.NewScanner(r)
- colelem := regexp.MustCompile(`\[([.*])([0-9A-F.]+)\]`)
- for i := 1; scanner.Scan(); i++ {
- line := scanner.Text()
- if len(line) == 0 || line[0] == '#' {
- continue
- }
- if line[0] == '@' {
- // parse properties
- switch {
- case strings.HasPrefix(line[1:], "version "):
- a := strings.Split(line[1:], " ")
- if a[1] != unicode.Version {
- log.Fatalf("incompatible version %s; want %s", a[1], unicode.Version)
- }
- case strings.HasPrefix(line[1:], "backwards "):
- log.Fatalf("%d: unsupported option backwards", i)
- default:
- log.Printf("%d: unknown option %s", i, line[1:])
- }
- } else {
- // parse entries
- part := strings.Split(line, " ; ")
- if len(part) != 2 {
- log.Fatalf("%d: production rule without ';': %v", i, line)
- }
- lhs := []rune{}
- for _, v := range strings.Split(part[0], " ") {
- if v == "" {
- continue
- }
- lhs = append(lhs, rune(convHex(i, v)))
- }
- var n int
- var vars []int
- rhs := [][]int{}
- for i, m := range colelem.FindAllStringSubmatch(part[1], -1) {
- n += len(m[0])
- elem := []int{}
- for _, h := range strings.Split(m[2], ".") {
- elem = append(elem, convHex(i, h))
- }
- if m[1] == "*" {
- vars = append(vars, i)
- }
- rhs = append(rhs, elem)
- }
- if len(part[1]) < n+3 || part[1][n+1] != '#' {
- log.Fatalf("%d: expected comment; found %s", i, part[1][n:])
- }
- if *test {
- testInput.add(string(lhs))
- }
- failOnError(builder.Add(lhs, rhs, vars))
- }
- }
- if scanner.Err() != nil {
- log.Fatal(scanner.Err())
- }
-}
-
-func convHex(line int, s string) int {
- r, e := strconv.ParseInt(s, 16, 32)
- if e != nil {
- log.Fatalf("%d: %v", line, e)
- }
- return int(r)
-}
-
-var testInput = stringSet{}
-
-// LDML holds all collation information parsed from an LDML XML file.
-// The format of these files is defined in
http://unicode.org/reports/tr35/.
-type LDML struct {
- XMLName xml.Name `xml:"ldml"`
- Language Attr `xml:"identity>language"`
- Territory Attr `xml:"identity>territory"`
- Chars *struct {
- ExemplarCharacters []AttrValue `xml:"exemplarCharacters"`
- MoreInformaton string `xml:"moreInformation,omitempty"`
- } `xml:"characters"`
- Default Attr `xml:"collations>default"`
- Collations []Collation `xml:"collations>collation"`
-}
-
-type Attr struct {
- XMLName xml.Name
- Attr string `xml:"type,attr"`
-}
-
-func (t Attr) String() string {
- return t.Attr
-}
-
-type AttrValue struct {
- Type string `xml:"type,attr"`
- Key string `xml:"key,attr,omitempty"`
- Draft string `xml:"draft,attr,omitempty"`
- Value string `xml:",innerxml"`
-}
-
-type Collation struct {
- Type string `xml:"type,attr"`
- Alt string `xml:"alt,attr"`
- SuppressContraction string `xml:"suppress_contractions,omitempty"`
- Settings *Settings `xml:"settings"`
- Optimize string `xml:"optimize"`
- Rules Rules `xml:"rules"`
-}
-
-type Optimize struct {
- XMLName xml.Name `xml:"optimize"`
- Data string `xml:"chardata"`
-}
-
-type Suppression struct {
- XMLName xml.Name `xml:"suppress_contractions"`
- Data string `xml:"chardata"`
-}
-
-type Settings struct {
- Strength string `xml:"strenght,attr,omitempty"`
- Backwards string `xml:"backwards,attr,omitempty"`
- Normalization string `xml:"normalization,attr,omitempty"`
- CaseLevel string `xml:"caseLevel,attr,omitempty"`
- CaseFirst string `xml:"caseFirst,attr,omitempty"`
- HiraganaQuarternary string `xml:"hiraganaQuartenary,attr,omitempty"`
- Numeric string `xml:"numeric,attr,omitempty"`
- VariableTop string `xml:"variableTop,attr,omitempty"`
-}
-
-type Rules struct {
- XMLName xml.Name `xml:"rules"`
- Any []RuleElem `xml:",any"`
-}
-
-type RuleElem struct {
- XMLName xml.Name
- Value string `xml:",innerxml"`
- Before string `xml:"before,attr"`
- Any []RuleElem `xml:",any"` // for <x> elements
-}
-
-var charRe = regexp.MustCompile(`&#x([0-9A-F]*);`)
-var tagRe = regexp.MustCompile(`<([a-z_]*) */>`)
-
-func (r *RuleElem) rewrite() {
- // Convert hexadecimal Unicode codepoint notation to a string.
- if m := charRe.FindAllStringSubmatch(r.Value, -1); m != nil {
- runes := []rune{}
- for _, sa := range m {
- runes = append(runes, rune(convHex(-1, sa[1])))
- }
- r.Value = string(runes)
- }
- // Strip spaces from reset positions.
- if m := tagRe.FindStringSubmatch(r.Value); m != nil {
- r.Value = fmt.Sprintf("<%s/>", m[1])
- }
- for _, rr := range r.Any {
- rr.rewrite()
- }
-}
-
-func decodeXML(f *zip.File) *LDML {
- r, err := f.Open()
- failOnError(err)
- d := xml.NewDecoder(r)
- var x LDML
- err = d.Decode(&x)
- failOnError(err)
- return &x
-}
-
-var mainLocales = []string{}
-
-// charsets holds a list of exemplar characters per category.
-type charSets map[string][]string
-
-func (p charSets) fprint(w io.Writer) {
- fmt.Fprintln(w, "[exN]string{")
- for i, k := range
[]string{"", "contractions", "punctuation", "auxiliary", "currencySymbol", "index"}
{
- if set := p[k]; len(set) != 0 {
- fmt.Fprintf(w, "\t\t%d: %q,\n", i, strings.Join(set, " "))
- }
- }
- fmt.Fprintln(w, "\t},")
-}
-
-var localeChars = make(map[string]charSets)
-
-const exemplarHeader = `
-type exemplarType int
-const (
- exCharacters exemplarType = iota
- exContractions
- exPunctuation
- exAuxiliary
- exCurrency
- exIndex
- exN
-)
-`
-
-func printExemplarCharacters(w io.Writer) {
- fmt.Fprintln(w, exemplarHeader)
- fmt.Fprintln(w, "var exemplarCharacters = map[string][exN]string{")
- for _, loc := range mainLocales {
- fmt.Fprintf(w, "\t%q: ", loc)
- localeChars[loc].fprint(w)
- }
- fmt.Fprintln(w, "}")
-}
-
-var mainRe = regexp.MustCompile(`.*/main/(.*)\.xml`)
-
-// parseMain parses XML files in the main directory of the CLDR core.zip
file.
-func parseMain() {
- for _, f := range openArchive(cldr).File {
- if m := mainRe.FindStringSubmatch(f.Name); m != nil {
- locale := m[1]
- x := decodeXML(f)
- if skipLang(x.Language.Attr) {
- continue
- }
- if x.Chars != nil {
- for _, ec := range x.Chars.ExemplarCharacters {
- if ec.Draft != "" {
- continue
- }
- if _, ok := localeChars[locale]; !ok {
- mainLocales = append(mainLocales, locale)
- localeChars[locale] = make(charSets)
- }
- localeChars[locale][ec.Type] = parseCharacters(ec.Value)
- }
- }
- }
- }
-}
-
-func parseCharacters(chars string) []string {
- parseSingle := func(s string) (r rune, tail string, escaped bool) {
- if s[0] == '\\' {
- if s[1] == 'u' || s[1] == 'U' {
- r, _, tail, err := strconv.UnquoteChar(s, 0)
- failOnError(err)
- return r, tail, false
- } else if strings.HasPrefix(s[1:], "&") {
- return '&', s[6:], false
- }
- return rune(s[1]), s[2:], true
- } else if strings.HasPrefix(s, """) {
- return '"', s[6:], false
- }
- r, sz := utf8.DecodeRuneInString(s)
- return r, s[sz:], false
- }
- chars = strings.Trim(chars, "[ ]")
- list := []string{}
- var r, last, end rune
- for len(chars) > 0 {
- if chars[0] == '{' { // character sequence
- buf := []rune{}
- for chars = chars[1:]; len(chars) > 0; {
- r, chars, _ = parseSingle(chars)
- if r == '}' {
- break
- }
- if r == ' ' {
- log.Fatalf("space not supported in sequence %q", chars)
- }
- buf = append(buf, r)
- }
- list = append(list, string(buf))
- last = 0
- } else { // single character
- escaped := false
- r, chars, escaped = parseSingle(chars)
- if r != ' ' {
- if r == '-' && !escaped {
- if last == 0 {
- log.Fatal("'-' should be preceded by a character")
- }
- end, chars, _ = parseSingle(chars)
- for ; last <= end; last++ {
- list = append(list, string(last))
- }
- last = 0
- } else {
- list = append(list, string(r))
- last = r
- }
- }
- }
- }
- return list
-}
-
-var fileRe = regexp.MustCompile(`.*/collation/(.*)\.xml`)
-
-// parseCollation parses XML files in the collation directory of the CLDR
core.zip file.
-func parseCollation(b *build.Builder) {
- for _, f := range openArchive(cldr).File {
- if m := fileRe.FindStringSubmatch(f.Name); m != nil {
- lang := m[1]
- x := decodeXML(f)
- if skipLang(x.Language.Attr) {
- continue
- }
- def := "standard"
- if x.Default.Attr != "" {
- def = x.Default.Attr
- }
- todo := make(map[string]Collation)
- for _, c := range x.Collations {
- if c.Type != def && !types.contains(c.Type) {
- continue
- }
- if c.Alt != "" && skipAlt(c.Alt) {
- continue
- }
- for j := range c.Rules.Any {
- c.Rules.Any[j].rewrite()
- }
- locale := lang
- if c.Type != def {
- locale += "_u_co_" + c.Type
- }
- _, exists := todo[locale]
- if c.Alt != "" || !exists {
- todo[locale] = c
- }
- }
- for _, c := range x.Collations {
- locale := lang
- if c.Type != def {
- locale += "_u_co_" + c.Type
- }
- if d, ok := todo[locale]; ok && d.Alt == c.Alt {
- insertCollation(b, locale, &c)
- }
- }
- }
- }
-}
-
-var lmap = map[byte]colltab.Level{
- 'p': colltab.Primary,
- 's': colltab.Secondary,
- 't': colltab.Tertiary,
- 'i': colltab.Identity,
-}
-
-// cldrIndex is a Unicode-reserved sentinel value used.
-// We ignore any rule that starts with this rune.
-// See
http://unicode.org/reports/tr35/#Collation_Elements for details.
-const cldrIndex = 0xFDD0
-
-func insertTailoring(t *build.Tailoring, r RuleElem, context, extend
string) {
- switch l := r.XMLName.Local; l {
- case "p", "s", "t", "i":
- if []rune(r.Value)[0] != cldrIndex {
- str := context + r.Value
- if *test {
- testInput.add(str)
- }
- err := t.Insert(lmap[l[0]], str, context+extend)
- failOnError(err)
- }
- case "pc", "sc", "tc", "ic":
- level := lmap[l[0]]
- for _, s := range r.Value {
- str := context + string(s)
- if *test {
- testInput.add(str)
- }
- err := t.Insert(level, str, context+extend)
- failOnError(err)
- }
- default:
- log.Fatalf("unsupported tag: %q", l)
- }
-}
-
-func insertCollation(builder *build.Builder, locale string, c *Collation) {
- t := builder.Tailoring(locale)
- for _, r := range c.Rules.Any {
- switch r.XMLName.Local {
- case "reset":
- if r.Before == "" {
- failOnError(t.SetAnchor(r.Value))
- } else {
- failOnError(t.SetAnchorBefore(r.Value))
- }
- case "x":
- var context, extend string
- for _, r1 := range r.Any {
- switch r1.XMLName.Local {
- case "context":
- context = r1.Value
- case "extend":
- extend = r1.Value
- }
- }
- for _, r1 := range r.Any {
- if t := r1.XMLName.Local; t == "context" || t == "extend" {
- continue
- }
- insertTailoring(t, r1, context, extend)
- }
- default:
- insertTailoring(t, r, "", "")
- }
- }
-}
-
-func testCollator(c *collate.Collator) {
- c0 := collate.New("")
-
- // iterator over all characters for all locales and check
- // whether Key is equal.
- buf := collate.Buffer{}
-
- // Add all common and not too uncommon runes to the test set.
- for i := rune(0); i < 0x30000; i++ {
- testInput.add(string(i))
- }
- for i := rune(0xE0000); i < 0xF0000; i++ {
- testInput.add(string(i))
- }
- for _, str := range testInput.values() {
- k0 := c0.KeyFromString(&buf, str)
- k := c.KeyFromString(&buf, str)
- if !bytes.Equal(k0, k) {
- failOnError(fmt.Errorf("test:%U: keys differ (%x vs %x)", []rune(str),
k0, k))
- }
- buf.Reset()
- }
- fmt.Println("PASS")
-}
-
-func main() {
- flag.Parse()
- b := build.NewBuilder()
- if *root != "" {
- parseUCA(b)
- }
- if *cldr != "" {
- if tables.contains("chars") {
- parseMain()
- }
- parseCollation(b)
- }
-
- c, err := b.Build()
- failOnError(err)
-
- if *test {
- testCollator(collate.NewFromTable(c))
- } else {
- fmt.Println("// Generated by running")
- fmt.Printf("// maketables -root=%s -cldr=%s\n", *root, *cldr)
- fmt.Println("// DO NOT EDIT")
- fmt.Println("// TODO: implement more compact representation for sparse
blocks.")
- if *tags != "" {
- fmt.Printf("// +build %s\n", *tags)
- }
- fmt.Println("")
- fmt.Printf("package %s\n", *pkg)
- if tables.contains("collate") {
- fmt.Println("")
- _, err = b.Print(os.Stdout)
- failOnError(err)
- }
- if tables.contains("chars") {
- printExemplarCharacters(os.Stdout)
- }
- }
-}
=======================================
--- /src/pkg/exp/locale/collate/regtest.go Thu Feb 21 10:47:31 2013
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-package main
-
-import (
- "archive/zip"
- "bufio"
- "bytes"
- "exp/locale/collate"
- "exp/locale/collate/build"
- "exp/locale/collate/colltab"
- "flag"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "net/http"
- "os"
- "path"
- "regexp"
- "strconv"
- "strings"
- "unicode"
- "unicode/utf8"
-)
-
-// This regression test runs tests for the test files in CollationTest.zip
-// (taken from
http://www.unicode.org/Public/UCA/<unicode.Version>/).
-//
-// The test files have the following form:
-// # header
-// 0009 0021; # ('\u0009') <CHARACTER TABULATION> [| | | 0201 025E]
-// 0009 003F; # ('\u0009') <CHARACTER TABULATION> [| | | 0201 0263]
-// 000A 0021; # ('\u000A') <LINE FEED (LF)> [| | | 0202 025E]
-// 000A 003F; # ('\u000A') <LINE FEED (LF)> [| | | 0202 0263]
-//
-// The part before the semicolon is the hex representation of a sequence
-// of runes. After the hash mark is a comment. The strings
-// represented by rune sequence are in the file in sorted order, as
-// defined by the DUCET.
-
-var testdata = flag.String("testdata",
- "
http://www.unicode.org/Public/UCA/"+unicode.Version+"/CollationTest.zip",
- "URL of Unicode collation tests zip file")
-var ducet = flag.String("ducet",
- "
http://unicode.org/Public/UCA/"+unicode.Version+"/allkeys.txt",
- "URL of the Default Unicode Collation Element Table (DUCET).")
-var localFiles = flag.Bool("local",
- false,
- "data files have been copied to the current directory; for debugging
only")
-
-type Test struct {
- name string
- str [][]byte
- comment []string
-}
-
-var versionRe = regexp.MustCompile(`# UCA Version: (.*)\n?$`)
-var testRe = regexp.MustCompile(`^([\dA-F ]+);.*# (.*)\n?$`)
-
-func Error(e error) {
- if e != nil {
- log.Fatal(e)
- }
-}
-
-// openReader opens the url or file given by url and returns it as an
io.ReadCloser
-// or nil on error.
-func openReader(url string) io.ReadCloser {
- if *localFiles {
- pwd, _ := os.Getwd()
- url = "file://" + path.Join(pwd, path.Base(url))
- }
- t := &http.Transport{}
- t.RegisterProtocol("file", http.NewFileTransport(http.Dir("/")))
- c := &http.Client{Transport: t}
- resp, err := c.Get(url)
- Error(err)
- if resp.StatusCode != 200 {
- Error(fmt.Errorf(`bad GET status for "%s": %s`, url, resp.Status))
- }
- return resp.Body
-}
-
-// parseUCA parses a Default Unicode Collation Element Table of the format
-// specified in
http://www.unicode.org/reports/tr10/#File_Format.
-// It returns the variable top.
-func parseUCA(builder *build.Builder) {
- r := openReader(*ducet)
- defer r.Close()
- input := bufio.NewReader(r)
- colelem := regexp.MustCompile(`\[([.*])([0-9A-F.]+)\]`)
- for i := 1; true; i++ {
- l, prefix, err := input.ReadLine()
- if err == io.EOF {
- break
- }
- Error(err)
- line := string(l)
- if prefix {
- log.Fatalf("%d: buffer overflow", i)
- }
- if len(line) == 0 || line[0] == '#' {
- continue
- }
- if line[0] == '@' {
- if strings.HasPrefix(line[1:], "version ") {
- if v := strings.Split(line[1:], " ")[1]; v != unicode.Version {
- log.Fatalf("incompatible version %s; want %s", v, unicode.Version)
- }
- }
- } else {
- // parse entries
- part := strings.Split(line, " ; ")
- if len(part) != 2 {
- log.Fatalf("%d: production rule without ';': %v", i, line)
- }
- lhs := []rune{}
- for _, v := range strings.Split(part[0], " ") {
- if v != "" {
- lhs = append(lhs, rune(convHex(i, v)))
- }
- }
- vars := []int{}
- rhs := [][]int{}
- for i, m := range colelem.FindAllStringSubmatch(part[1], -1) {
- if m[1] == "*" {
- vars = append(vars, i)
- }
- elem := []int{}
- for _, h := range strings.Split(m[2], ".") {
- elem = append(elem, convHex(i, h))
- }
- rhs = append(rhs, elem)
- }
- builder.Add(lhs, rhs, vars)
- }
- }
-}
-
-func convHex(line int, s string) int {
- r, e := strconv.ParseInt(s, 16, 32)
- if e != nil {
- log.Fatalf("%d: %v", line, e)
- }
- return int(r)
-}
-
-func loadTestData() []Test {
- f := openReader(*testdata)
- buffer, err := ioutil.ReadAll(f)
- f.Close()
- Error(err)
- archive, err := zip.NewReader(bytes.NewReader(buffer), int64(len(buffer)))
- Error(err)
- tests := []Test{}
- for _, f := range archive.File {
- // Skip the short versions, which are simply duplicates of the long
versions.
- if strings.Contains(f.Name, "SHORT") || f.FileInfo().IsDir() {
- continue
- }
- ff, err := f.Open()
- Error(err)
- defer ff.Close()
- scanner := bufio.NewScanner(ff)
- test := Test{name: path.Base(f.Name)}
- for scanner.Scan() {
- line := scanner.Text()
- if len(line) <= 1 || line[0] == '#' {
- if m := versionRe.FindStringSubmatch(line); m != nil {
- if m[1] != unicode.Version {
- log.Printf("warning:%s: version is %s; want %s", f.Name, m[1],
unicode.Version)
- }
- }
- continue
- }
- m := testRe.FindStringSubmatch(line)
- if m == nil || len(m) < 3 {
- log.Fatalf(`Failed to parse: "%s" result: %#v`, line, m)
- }
- str := []byte{}
- // In the regression test data (unpaired) surrogates are assigned a
weight
- // corresponding to their code point value. However, utf8.DecodeRune,
- // which is used to compute the implicit weight, assigns FFFD to
surrogates.
- // We therefore skip tests with surrogates. This skips about 35 entries
- // per test.
- valid := true
- for _, split := range strings.Split(m[1], " ") {
- r, err := strconv.ParseUint(split, 16, 64)
- Error(err)
- valid = valid && utf8.ValidRune(rune(r))
- str = append(str, string(rune(r))...)
- }
- if valid {
- test.str = append(test.str, str)
- test.comment = append(test.comment, m[2])
- }
- }
- if scanner.Err() != nil {
- log.Fatal(scanner.Err())
- }
- tests = append(tests, test)
- }
- return tests
-}
-
-var errorCount int
-
-func fail(t Test, pattern string, args ...interface{}) {
- format := fmt.Sprintf("error:%s:%s",
t.name, pattern)
- log.Printf(format, args...)
- errorCount++
- if errorCount > 30 {
- log.Fatal("too many errors")
- }
-}
-
-func runes(b []byte) []rune {
- return []rune(string(b))
-}
-
-func doTest(t Test) {
- bld := build.NewBuilder()
- parseUCA(bld)
- w, err := bld.Build()
- Error(err)
- c := collate.NewFromTable(w)
- c.Strength = colltab.Quaternary
- c.Alternate = collate.AltShifted
- b := &collate.Buffer{}
- if strings.Contains(
t.name, "NON_IGNOR") {
- c.Strength = colltab.Tertiary
- c.Alternate = collate.AltNonIgnorable
- }
- prev := t.str[0]
- for i := 1; i < len(t.str); i++ {
- b.Reset()
- s := t.str[i]
- ka := c.Key(b, prev)
- kb := c.Key(b, s)
- if r := bytes.Compare(ka, kb); r == 1 {
- fail(t, "%d: Key(%.4X) < Key(%.4X) (%X < %X) == %d; want -1 or 0", i,
[]rune(string(prev)), []rune(string(s)), ka, kb, r)
- prev = s
- continue
- }
- if r := c.Compare(prev, s); r == 1 {
- fail(t, "%d: Compare(%.4X, %.4X) == %d; want -1 or 0", i, runes(prev),
runes(s), r)
- }
- if r := c.Compare(s, prev); r == -1 {
- fail(t, "%d: Compare(%.4X, %.4X) == %d; want 1 or 0", i, runes(s),
runes(prev), r)
- }
- prev = s
- }
-}
-
-func main() {
- flag.Parse()
- for _, test := range loadTestData() {
- doTest(test)
- }
- if errorCount == 0 {
- fmt.Println("PASS")
- }
-}
=======================================
--- /src/pkg/exp/locale/collate/sort.go Wed Feb 27 02:08:18 2013
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package collate
-
-import (
- "bytes"
- "sort"
-)
-
-const (
- maxSortBuffer = 40960
- maxSortEntries = 4096
-)
-
-type swapper interface {
- Swap(i, j int)
-}
-
-type sorter struct {
- buf *Buffer
- keys [][]byte
- src swapper
-}
-
-func (s *sorter) init(n int) {
- if s.buf == nil {
- s.buf = &Buffer{}
- s.buf.init()
- }
- if cap(s.keys) < n {
- s.keys = make([][]byte, n)
- }
- s.keys = s.keys[0:n]
-}
-
-func (s *sorter) sort(src swapper) {
- s.src = src
- sort.Sort(s)
-}
-
-func (s sorter) Len() int {
- return len(s.keys)
-}
-
-func (s sorter) Less(i, j int) bool {
- return bytes.Compare(s.keys[i], s.keys[j]) == -1
-}
-
-func (s sorter) Swap(i, j int) {
- s.keys[i], s.keys[j] = s.keys[j], s.keys[i]
- s.src.Swap(i, j)
-}
-
-// A Lister can be sorted by Collator's Sort method.
-type Lister interface {
- Len() int
- Swap(i, j int)
- // Bytes returns the bytes of the text at index i.
- Bytes(i int) []byte
-}
-
-// Sort uses sort.Sort to sort the strings represented by x using the
rules of c.
-func (c *Collator) Sort(x Lister) {
- n := x.Len()
- c.sorter.init(n)
- for i := 0; i < n; i++ {
- c.sorter.keys[i] = c.Key(c.sorter.buf, x.Bytes(i))
- }
- c.sorter.sort(x)
-}
-
-// SortStrings uses sort.Sort to sort the strings in x using the rules of
c.
-func (c *Collator) SortStrings(x []string) {
- c.sorter.init(len(x))
- for i, s := range x {
- c.sorter.keys[i] = c.KeyFromString(c.sorter.buf, s)
- }
- c.sorter.sort(sort.StringSlice(x))
-}
=======================================
--- /src/pkg/exp/locale/collate/sort_test.go Wed Feb 27 02:08:18 2013
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package collate_test
-
-import (
- "exp/locale/collate"
- "fmt"
- "testing"
-)
-
-func ExampleCollator_Strings() {
- c := collate.New("root")
- strings := []string{
- "ad",
- "ab",
- "äb",
- "ac",
- }
- c.SortStrings(strings)
- fmt.Println(strings)
- // Output: [ab äb ac ad]
-}
-
-type sorter []string
-
-func (s sorter) Len() int {
- return len(s)
-}
-
-func (s sorter) Swap(i, j int) {
- s[j], s[i] = s[i], s[j]
-}
-
-func (s sorter) Bytes(i int) []byte {
- return []byte(s[i])
-}
-
-func TestSort(t *testing.T) {
- c := collate.New("en")
- strings := []string{
- "bcd",
- "abc",
- "ddd",
- }
- c.Sort(sorter(strings))
- res := fmt.Sprint(strings)
- want := "[abc bcd ddd]"
- if res != want {
- t.Errorf("found %s; want %s", res, want)
- }
-}
=======================================
--- /src/pkg/exp/locale/collate/table_test.go Tue Feb 12 06:59:55 2013
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package collate
-
-import (
- "exp/locale/collate/build"
- "exp/locale/collate/colltab"
- "exp/norm"
- "testing"
-)
-
-type ColElems []Weights
-
-type input struct {
- str string
- ces [][]int
-}
-
-type check struct {
- in string
- n int
- out ColElems
-}
-
-type tableTest struct {
- in []input
- chk []check
-}
-
-func w(ce ...int) Weights {
- return W(ce...)
-}
-
-var defaults = w(0)
-
-func pt(p, t int) []int {
- return []int{p, defaults.Secondary, t}
-}
-
-func makeTable(in []input) (*Collator, error) {
- b := build.NewBuilder()
- for _, r := range in {
- if e := b.Add([]rune(r.str), r.ces, nil); e != nil {
- panic(e)
- }
- }
- t, err := b.Build()
- if err != nil {
- return nil, err
- }
- return NewFromTable(t), nil
-}
-
-// modSeq holds a seqeunce of modifiers in increasing order of CCC long
enough
-// to cause a segment overflow if not handled correctly. The last rune in
this
-// list has a CCC of 214.
-var modSeq = []rune{
- 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7, 0x05B8, 0x05B9,
0x05BB,
- 0x05BC, 0x05BD, 0x05BF, 0x05C1, 0x05C2, 0xFB1E, 0x064B, 0x064C, 0x064D,
0x064E,
- 0x064F, 0x0650, 0x0651, 0x0652, 0x0670, 0x0711, 0x0C55, 0x0C56, 0x0E38,
0x0E48,
- 0x0EB8, 0x0EC8, 0x0F71, 0x0F72, 0x0F74, 0x0321, 0x1DCE,
-}
-
-var mods []input
-var modW = func() ColElems {
- ws := ColElems{}
- for _, r := range modSeq {
- rune := norm.NFC.PropertiesString(string(r))
- ws = append(ws, w(0, int(rune.CCC())))
- mods = append(mods, input{string(r), [][]int{{0, int(rune.CCC())}}})
- }
- return ws
-}()
-
-var appendNextTests = []tableTest{
- { // test getWeights
- []input{
- {"a", [][]int{{100}}},
- {"b", [][]int{{105}}},
- {"c", [][]int{{110}}},
- {"ß", [][]int{{120}}},
- },
- []check{
- {"a", 1, ColElems{w(100)}},
- {"b", 1, ColElems{w(105)}},
- {"c", 1, ColElems{w(110)}},
- {"d", 1, ColElems{w(0x50064)}},
- {"ab", 1, ColElems{w(100)}},
- {"bc", 1, ColElems{w(105)}},
- {"dd", 1, ColElems{w(0x50064)}},
- {"ß", 2, ColElems{w(120)}},
- },
- },
- { // test expansion
- []input{
- {"u", [][]int{{100}}},
- {"U", [][]int{{100}, {0, 25}}},
- {"w", [][]int{{100}, {100}}},
- {"W", [][]int{{100}, {0, 25}, {100}, {0, 25}}},
- },
- []check{
- {"u", 1, ColElems{w(100)}},
- {"U", 1, ColElems{w(100), w(0, 25)}},
- {"w", 1, ColElems{w(100), w(100)}},
- {"W", 1, ColElems{w(100), w(0, 25), w(100), w(0, 25)}},
- },
- },
- { // test decompose
- []input{
- {"D", [][]int{pt(104, 8)}},
- {"z", [][]int{pt(130, 8)}},
- {"\u030C", [][]int{{0, 40}}}, // Caron
- {"\u01C5", [][]int{pt(104, 9), pt(130, 4), {0, 40, 0x1F}}}, // Dž =
D+z+caron
- },
- []check{
- {"\u01C5", 2, ColElems{w(pt(104, 9)...), w(pt(130, 4)...), w(0, 40,
0x1F)}},
- },
- },
- { // test basic contraction
- []input{
- {"a", [][]int{{100}}},
- {"ab", [][]int{{101}}},
- {"aab", [][]int{{101}, {101}}},
- {"abc", [][]int{{102}}},
- {"b", [][]int{{200}}},
- {"c", [][]int{{300}}},
- {"d", [][]int{{400}}},
- },
- []check{
- {"a", 1, ColElems{w(100)}},
- {"aa", 1, ColElems{w(100)}},
- {"aac", 1, ColElems{w(100)}},
- {"d", 1, ColElems{w(400)}},
- {"ab", 2, ColElems{w(101)}},
- {"abb", 2, ColElems{w(101)}},
- {"aab", 3, ColElems{w(101), w(101)}},
- {"aaba", 3, ColElems{w(101), w(101)}},
- {"abc", 3, ColElems{w(102)}},
- {"abcd", 3, ColElems{w(102)}},
- },
- },
- { // test discontinuous contraction
- append(mods, []input{
- // modifiers; secondary weight equals ccc
- {"\u0316", [][]int{{0, 220}}},
- {"\u0317", [][]int{{0, 220}, {0, 220}}},
- {"\u302D", [][]int{{0, 222}}},
- {"\u302E", [][]int{{0, 225}}}, // used as starter
- {"\u302F", [][]int{{0, 224}}}, // used as starter
- {"\u18A9", [][]int{{0, 228}}},
- {"\u0300", [][]int{{0, 230}}},
- {"\u0301", [][]int{{0, 230}}},
- {"\u0315", [][]int{{0, 232}}},
- {"\u031A", [][]int{{0, 232}}},
- {"\u035C", [][]int{{0, 233}}},
- {"\u035F", [][]int{{0, 233}}},
- {"\u035D", [][]int{{0, 234}}},
- {"\u035E", [][]int{{0, 234}}},
- {"\u0345", [][]int{{0, 240}}},
-
- // starters
- {"a", [][]int{{100}}},
- {"b", [][]int{{200}}},
- {"c", [][]int{{300}}},
- {"\u03B1", [][]int{{900}}},
- {"\x01", [][]int{{0, 0, 0, 0}}},
-
- // contractions
- {"a\u0300", [][]int{{101}}},
- {"a\u0301", [][]int{{102}}},
- {"a\u035E", [][]int{{110}}},
- {"a\u035Eb\u035E", [][]int{{115}}},
- {"ac\u035Eaca\u035E", [][]int{{116}}},
- {"a\u035Db\u035D", [][]int{{117}}},
- {"a\u0301\u035Db", [][]int{{120}}},
- {"a\u0301\u035F", [][]int{{121}}},
- {"a\u0301\u035Fb", [][]int{{119}}},
- {"\u03B1\u0345", [][]int{{901}, {902}}},
- {"\u302E\u302F", [][]int{{0, 131}, {0, 131}}},
- {"\u302F\u18A9", [][]int{{0, 130}}},
- }...),
- []check{
- {"a\x01\u0300", 1, ColElems{w(100)}},
- {"ab", 1, ColElems{w(100)}}, // closing
segment
- {"a\u0316\u0300b", 5, ColElems{w(101), w(0, 220)}}, // closing
segment
- {"a\u0316\u0300", 5, ColElems{w(101), w(0, 220)}}, // no closing
segment
- {"a\u0316\u0300\u035Cb", 5, ColElems{w(101), w(0, 220)}}, // completes
before segment end
- {"a\u0316\u0300\u035C", 5, ColElems{w(101), w(0, 220)}}, // completes
before segment end
-
- {"a\u0316\u0301b", 5, ColElems{w(102), w(0, 220)}}, // closing
segment
- {"a\u0316\u0301", 5, ColElems{w(102), w(0, 220)}}, // no closing
segment
- {"a\u0316\u0301\u035Cb", 5, ColElems{w(102), w(0, 220)}}, // completes
before segment end
- {"a\u0316\u0301\u035C", 5, ColElems{w(102), w(0, 220)}}, // completes
before segment end
-
- // match blocked by modifier with same ccc
- {"a\u0301\u0315\u031A\u035Fb", 3, ColElems{w(102)}},
-
- // multiple gaps
- {"a\u0301\u035Db", 6, ColElems{w(120)}},
- {"a\u0301\u035F", 5, ColElems{w(121)}},
- {"a\u0301\u035Fb", 6, ColElems{w(119)}},
- {"a\u0316\u0301\u035F", 7, ColElems{w(121), w(0, 220)}},
- {"a\u0301\u0315\u035Fb", 7, ColElems{w(121), w(0, 232)}},
- {"a\u0316\u0301\u0315\u035Db", 5, ColElems{w(102), w(0, 220)}},
- {"a\u0316\u0301\u0315\u035F", 9, ColElems{w(121), w(0, 220), w(0,
232)}},
- {"a\u0316\u0301\u0315\u035Fb", 9, ColElems{w(121), w(0, 220), w(0,
232)}},
- {"a\u0316\u0301\u0315\u035F\u035D", 9, ColElems{w(121), w(0, 220), w(0,
232)}},
- {"a\u0316\u0301\u0315\u035F\u035Db", 9, ColElems{w(121), w(0, 220),
w(0, 232)}},
-
- // handling of segment overflow
- { // just fits within segment
- "a" + string(modSeq[:30]) + "\u0301",
- 3 + len(string(modSeq[:30])),
- append(ColElems{w(102)}, modW[:30]...),
- },
- {"a" + string(modSeq[:31]) + "\u0301", 1, ColElems{w(100)}}, // overflow
- {"a" + string(modSeq) + "\u0301", 1, ColElems{w(100)}},
- { // just fits within segment with two interstitial runes
- "a" + string(modSeq[:28]) + "\u0301\u0315\u035F",
- 7 + len(string(modSeq[:28])),
- append(append(ColElems{w(121)}, modW[:28]...), w(0, 232)),
- },
- { // second half does not fit within segment
- "a" + string(modSeq[:29]) + "\u0301\u0315\u035F",
- 3 + len(string(modSeq[:29])),
- append(ColElems{w(102)}, modW[:29]...),
- },
-
- // discontinuity can only occur in last normalization segment
- {"a\u035Eb\u035E", 6, ColElems{w(115)}},
- {"a\u0316\u035Eb\u035E", 5, ColElems{w(110), w(0, 220)}},
- {"a\u035Db\u035D", 6, ColElems{w(117)}},
- {"a\u0316\u035Db\u035D", 1, ColElems{w(100)}},
- {"a\u035Eb\u0316\u035E", 8, ColElems{w(115), w(0, 220)}},
- {"a\u035Db\u0316\u035D", 8, ColElems{w(117), w(0, 220)}},
- {"ac\u035Eaca\u035E", 9, ColElems{w(116)}},
- {"a\u0316c\u035Eaca\u035E", 1, ColElems{w(100)}},
- {"ac\u035Eac\u0316a\u035E", 1, ColElems{w(100)}},
-
- // expanding contraction
- {"\u03B1\u0345", 4, ColElems{w(901), w(902)}},
-
- // Theoretical possibilities
- // contraction within a gap
- {"a\u302F\u18A9\u0301", 9, ColElems{w(102), w(0, 130)}},
- // expansion within a gap
- {"a\u0317\u0301", 5, ColElems{w(102), w(0, 220), w(0, 220)}},
- // repeating CCC blocks last modifier
- {"a\u302E\u302F\u0301", 1, ColElems{w(100)}},
- // The trailing combining characters (with lower CCC) should block the
first one.
- // TODO: make the following pass.
- // {"a\u035E\u0316\u0316", 1, ColElems{w(100)}},
- {"a\u035F\u035Eb", 5, ColElems{w(110), w(0, 233)}},
- // Last combiner should match after normalization.
- // TODO: make the following pass.
- // {"a\u035D\u0301", 3, ColElems{w(102), w(0, 234)}},
- // The first combiner is blocking the second one as they have the same
CCC.
- {"a\u035D\u035Eb", 1, ColElems{w(100)}},
- },
- },
-}
-
-func TestAppendNext(t *testing.T) {
- for i, tt := range appendNextTests {
- c, err := makeTable(
tt.in)
- if err != nil {
- t.Errorf("%d: error creating table: %v", i, err)
- continue
- }
- for j, chk := range tt.chk {
- ws, n := c.t.AppendNext(nil, []byte(
chk.in))
- if n != chk.n {
- t.Errorf("%d:%d: bytes consumed was %d; want %d", i, j, n, chk.n)
- }
- out := convertFromWeights(chk.out)
- if len(ws) != len(out) {
- t.Errorf("%d:%d: len(ws) was %d; want %d (%X vs %X)\n%X", i, j,
len(ws), len(out), ws, out,
chk.in)
- continue
- }
- for k, w := range ws {
- w, _ = colltab.MakeElem(w.Primary(), w.Secondary(), int(w.Tertiary()),
0)
- if w != out[k] {
- t.Errorf("%d:%d: Weights %d was %X; want %X", i, j, k, w, out[k])
- }
- }
- }
- }
-}
=======================================
--- /src/pkg/exp/locale/collate/tables.go Tue Feb 12 06:59:55 2013
+++ /dev/null
File is too large to display a diff.
=======================================
--- /src/pkg/exp/locale/collate/tools/colcmp/Makefile Sun Oct 7 17:59:33
2012
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright 2012 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-chars:
- go run ../maketables.go -tables=chars -package=main > chars.go
- gofmt -w -s chars.go
=======================================
--- /src/pkg/exp/locale/collate/tools/colcmp/chars.go Sun Oct 7 17:59:33
2012
+++ /dev/null
@@ -1,937 +0,0 @@
-// Generated by running
-// maketables
-root=
http://unicode.org/Public/UCA/6.0.0/CollationAuxiliary.zip
-cldr=
http://www.unicode.org/Public/cldr/2.0.1/core.zip
-// DO NOT EDIT
-
-package main
-
-type exemplarType int
-
-const (
- exCharacters exemplarType = iota
- exContractions
- exPunctuation
- exAuxiliary
- exCurrency
- exIndex
- exN
-)
-
-var exemplarCharacters = map[string][exN]string{
- "af": {
- 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",
- 3: "á à â ä ã æ ç é è ê ë í ì î ï ó ò ô ö ú ù û ü ý",
- 4: "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",
- },
- "agq": {
- 0: "a à â ǎ ā b c d e è ê ě ē ɛ ɛ̀ ɛ̂ ɛ̌ ɛ̄ f g h i ì î ǐ ī ɨ ɨ̀ ɨ̂ ɨ̌
ɨ̄ k l m n ŋ o ò ô ǒ ō ɔ ɔ̀ ɔ̂ ɔ̌ ɔ̄ p s t u ù û ǔ ū ʉ ʉ̀ ʉ̂ ʉ̌ ʉ̄ v w y z
ʔ",
- 3: "q r x",
- 5: "A B C D E Ɛ F G H I Ɨ K L M N Ŋ O Ɔ P S T U Ʉ V W Y Z ʔ",
- },
- "ak": {
- 0: "a b d e ɛ f g h i k l m n o ɔ p r s t u w y",
- 3: "c j q v z",
- 5: "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",
- },
- "am": {
- 0: "፟ ሀ ሀ ሁ ሂ ሃ ሄ ህ ሆ ለ ለ ሉ ሊ ላ ሌ ል ሎ ሏ ሐ ሑ ሒ ሓ ሔ ሕ ሖ ሗ መ ሙ ሚ ማ ሜ ም ሞ ሟ
ሠ ሡ ሢ ሣ ሤ ሥ ሦ ሧ ረ ሩ ሪ ራ ሬ ር ሮ ሯ ሰ ሱ ሲ ሳ ሴ ስ ሶ ሷ ሸ ሹ ሺ ሻ ሼ ሽ ሾ ሿ ቀ ቁ ቂ ቃ ቄ ቅ
ቆ ቈ ቊ ቊ ቋ ቌ ቍ በ በ ቡ ቢ ባ ቤ ብ ቦ ቧ ቨ ቩ ቪ ቫ ቬ ቭ ቮ ቯ ተ ቱ ቲ ታ ቴ ት ቶ ቷ ቸ ቹ ቺ ቻ ቼ ች
ቾ ቿ ኀ ኁ ኂ ኃ ኄ ኅ ኆ ኈ ኊ ኊ ኋ ኌ ኍ ነ ነ ኑ ኒ ና ኔ ን ኖ ኗ ኘ ኙ ኚ ኛ ኜ ኝ ኞ ኟ አ ኡ ኢ ኣ ኤ እ
ኦ ኧ ከ ኩ ኪ ካ ኬ ክ ኮ ኰ ኲ ኲ ኳ ኴ ኵ ኸ ኸ ኹ ኺ ኻ ኼ ኽ ኾ ወ ወ ዉ ዊ ዋ ዌ ው ዎ ዐ ዐ ዑ ዒ ዓ ዔ ዕ
ዖ ዘ ዘ ዙ ዚ ዛ ዜ ዝ ዞ ዟ ዠ ዡ ዢ ዣ ዤ ዥ ዦ ዧ የ ዩ ዪ ያ ዬ ይ ዮ ዯ ደ ዱ ዲ ዳ ዴ ድ ዶ ዷ ጀ ጀ ጁ ጂ
ጃ ጄ ጅ ጆ ጇ ገ ጉ ጊ ጋ ጌ ግ ጎ ጐ ጒ ጒ ጓ ጔ ጕ ጠ ጠ ጡ ጢ ጣ ጤ ጥ ጦ ጧ ጨ ጩ ጪ ጫ ጬ ጭ ጮ ጯ ጰ ጱ ጲ
ጳ ጴ ጵ ጶ ጷ ጸ ጹ ጺ ጻ ጼ ጽ ጾ ጿ ፀ ፁ ፂ ፃ ፄ ፅ ፆ ፇ ፈ ፉ ፊ ፋ ፌ ፍ ፎ ፏ ፐ ፑ ፒ ፓ ፔ ፕ ፖ ፗ ፘ
ፙ ፚ",
- },
- "ar": {
- 0: "ً ٌ ٍ َ ُ ِ ّ ْ ء آ أ ؤ إ ئ ا ب ت ة ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ
ف ق ك ل م ن ه و ي ى",
- 3: "\u200c \u200d \u200e \u200f",
- },
- "as": {
- 0: "অ আ ই ঈ উ ঊ ঋ এ ঐ ও ঔ ং ঁ ঃ ক খ গ ঘ ঙ চ ছ জ ঝ ঞ ট ঠ ড ড় ড় ঢ ঢ় ঢ় ণ
ত থ দ ধ ন প ফ ব ভ ম য য় ৰ ল ৱ শ ষ স হ া ি ী ু ূ ৃ ে ৈ ো ৌ ্",
- 3: "\u200c \u200d ৲",
- },
- "asa": {
- 0: "a b c d e f g h i j k l m n o p r s t u v w y z",
- 3: "q x",
- 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z",
- },
- "az": {
- 0: "a b c ç d e ə f g ğ h x ı i i̇ j k q l m n o ö p r s ş t u ü v y z",
- 3: "w",
- },
- "az_Cyrl": {
- 0: "а ә б в г ғ д е ж з и й ј к ҝ л м н о ө п р с т у ү ф х һ ч ҹ ш ы",
- 3: "ц щ ъ ь э ю я",
- },
- "bas": {
- 0: "a á à â ǎ ā a᷆ a᷇ b ɓ c d e é è ê ě ē e᷆ e᷇ ɛ ɛ́ ɛ̀ ɛ̂ ɛ̌ ɛ̄ ɛ᷆ ɛ᷇ f
g h i í ì î ǐ ī i᷆ i᷇ j k l m n ń ǹ ŋ o ó ò ô ǒ ō o᷆ o᷇ ɔ ɔ́ ɔ̀ ɔ̂ ɔ̌ ɔ̄ ɔ᷆
ɔ᷇ p r s t u ú ù û ǔ ū u᷆ u᷇ v w y z",
- 3: "q x",
- 5: "A B Ɓ C D E Ɛ F G H I J K L M N Ŋ O Ɔ P R S T U V W Y Z",
- },
- "be": {
- 0: "а б в г д дж дз е ё ж з і й к л м н о п р с т у ў ф х ц ч ш ы ь э ю
я",
- 4: "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",
- },
- "bem": {
- 0: "a b c e f g i j k l m n o p s sh t u w y",
- 3: "d h q r v x z",
- 5: "A B C E F G I J K L M N O P S SH T U W Y",
- },
- "bez": {
- 0: "a b c d e f g h i j k l m n o p q r s t u v w y z",
- 3: "x",
- 5: "A B C D E F G H I J K L M N O P Q R S T U V W Y Z",
- },
- "bg": {
- 0: "а б в г д е ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ь ю я",
- 3: "а̀ ѐ ѝ о̀ у̀ ъ ѣ ю̀ я̀ ѫ",
- },
- "bm": {
- 0: "a b c d e ɛ f g h i j k l m n ɲ ŋ o ɔ p r s t u w y z",
- 3: "q v x",
- 5: "A B C D E Ɛ F G H I J K L M N Ɲ Ŋ O Ɔ P R S T U W Y Z",
- },
- "bn": {
- 0: "৺ অ আ ই ঈ উ ঊ ঋ ৠ ঌ ৡ এ ঐ ও ঔ ় ং ঃ ঁ ক ক্ষ খ গ ঘ ঙ চ ছ জ ঝ ঞ ট ঠ ড
ড় ঢ ঢ় ণ ৎ ত থ দ ধ ন প ফ ব ভ ম য য় র ল শ ষ স হ ঽ া ি ী ু ূ ৃ ৄ ৢ ৣ ে ৈ ো
ৌ ্ ৗ",
- 3: "\u200c \u200d ৸ ৹ ৲ ৳ ৰ ৱ ৴ ৵ ৶ ৷",
- 4: "৳",
- },
- "bo": {
- 0: "ཾ ཿ ཀ ཀྵ ྐ ྐྵ ཁ ྑ ག གྷ ྒ ྒྷ ང ྔ ཅ ྕ ཆ ྖ ཇ ྗ ཉ ྙ ཊ ྚ ཋ ྛ ཌ ཌྷ ྜ ྜྷ ཎ
ྞ ཏ ྟ ཐ ྠ ད དྷ ྡ ྡྷ ན ྣ པ ྤ ཕ ྥ བ བྷ ྦ ྦྷ མ ྨ ཙ ྩ ཚ ྪ ཛ ཛྷ ྫ ྫྷ ཝ ྭ ྺ ཞ ྮ ཟ
ྯ འ ྰ ཡ ྱ ྻ ར ཪ ྲ ྼ ལ ླ ཤ ྴ ཥ ྵ ས ྶ ཧ ྷ ཨ ྸ ི ཱི ྀ ཱྀ ུ ཱུ ྲྀ ཷ ླྀ ཹ ཹ ེ ཻ
ོ ཽ ྄",
- 3: "ༀ",
- },
- "br": {
- 0: "a b ch cʼh d e ê f g h i j k l m n ñ o p r s t u ù v w x y z",
- 3: "á à ă â å ä ã ā æ c ç é è ĕ ë ē í ì ĭ î ï ī ó ò ŏ ô ö ø ō œ q ú ŭ û
ü ū ÿ",
- 4: "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",
- 5: "A B C D E F G H I J K L M N O P R S T U V W X Y Z",
- },
- "brx": {
- 0: "़ ँ ं अ आ इ ई उ ऊ ऍ ए ऐ ऑ ओ औ क ख ग घ च छ ज झ ञ ट ठ ड ड़ ढ ण त थ द ध
न प फ ब भ म य र ल ळ व श ष स ह ा ि ी ु ू ृ ॅ े ै ॉ ो ौ ्",
- 3: "\u200c \u200d",
- 5: "अ आ इ ई उ ऊ ऍ ए ऐ ऑ ओ औ क ख ग घ च छ ज झ ञ ट ठ ड ड़ ढ ण त थ द ध न प फ
ब भ म य र ल ळ व श ष स ह",
- },
- "bs": {
- 0: "a b c č ć d dž đ e f g h i j k l lj m n nj o p r s š t u v z ž",
- 3: "q w x y",
- },
- "byn": {
- 0: "፟ ሀ ሀ ሁ ሂ ሃ ሄ ህ ሆ ለ ለ ሉ ሊ ላ ሌ ል ሎ ሏ ሐ ሑ ሒ ሓ ሔ ሕ ሖ ሗ መ ሙ ሚ ማ ሜ ም ሞ ሟ
ረ ረ ሩ ሪ ራ ሬ ር ሮ ሯ ሰ ሱ ሲ ሳ ሴ ስ ሶ ሷ ሸ ሹ ሺ ሻ ሼ ሽ ሾ ሿ ቀ ቁ ቂ ቃ ቄ ቅ ቆ ቈ ቊ ቊ ቋ ቌ ቍ
ቐ ቐ ቑ ቒ ቓ ቔ ቕ ቖ ቘ ቚ ቚ ቛ ቜ ቝ በ በ ቡ ቢ ባ ቤ ብ ቦ ቧ ቨ ቩ ቪ ቫ ቬ ቭ ቮ ቯ ተ ቱ ቲ ታ ቴ ት ቶ
ቷ ቸ ቹ ቺ ቻ ቼ ች ቾ ቿ ኀ ኁ ኂ ኃ ኄ ኅ ኆ ኈ ኊ ኊ ኋ ኌ ኍ ነ ነ ኑ ኒ ና ኔ ን ኖ ኗ ኘ ኙ ኚ ኛ ኜ ኝ ኞ
ኟ አ ኡ ኢ ኣ ኤ እ ኦ ኧ ከ ኩ ኪ ካ ኬ ክ ኮ ኰ ኲ ኲ ኳ ኴ ኵ ኸ ኸ ኹ ኺ ኻ ኼ ኽ ኾ ዀ ዂ ዂ ዃ ዄ ዅ ወ ወ
ዉ ዊ ዋ ዌ ው ዎ ዐ ዐ ዑ ዒ ዓ ዔ ዕ ዖ ዘ ዘ ዙ ዚ ዛ ዜ ዝ ዞ ዟ ዠ ዡ ዢ ዣ ዤ ዥ ዦ ዧ የ ዩ ዪ ያ ዬ ይ ዮ
ደ ደ ዱ ዲ ዳ ዴ ድ ዶ ዷ ጀ ጀ ጁ ጂ ጃ ጄ ጅ ጆ ጇ ገ ጉ ጊ ጋ ጌ ግ ጎ ጐ ጒ ጒ ጓ ጔ ጕ ጘ ጘ ጙ ጚ ጛ ጜ ጝ
ጞ ጟ ⶓ ⶓ ⶔ ⶕ ⶖ ጠ ጠ ጡ ጢ ጣ ጤ ጥ ጦ ጧ ጨ ጩ ጪ ጫ ጬ ጭ ጮ ጯ ጸ ጸ ጹ ጺ ጻ ጼ ጽ ጾ ጿ ፈ ፈ ፉ ፊ ፋ
ፌ ፍ ፎ ፏ ፐ ፑ ፒ ፓ ፔ ፕ ፖ ፗ",
- },
- "ca": {
- 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",
- 3: "á ă â å ä ã ā æ ĕ ê ë ē ì ĭ î ī ñ º ŏ ô ö ø ō œ ù ŭ û ū ÿ",
- 4: "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",
- 5: "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",
- },
- "cgg": {
- 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",
- 5: "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",
- },
- "chr": {
- 0: "Ꭰ Ꭱ Ꭲ Ꭳ Ꭴ Ꭵ Ꭶ Ꭷ Ꭸ Ꭹ Ꭺ Ꭻ Ꭼ Ꭽ Ꭾ Ꭿ Ꮀ Ꮁ Ꮂ Ꮃ Ꮄ Ꮅ Ꮆ Ꮇ Ꮈ Ꮉ Ꮊ Ꮋ Ꮌ Ꮍ Ꮎ Ꮏ Ꮐ Ꮑ
Ꮒ Ꮓ Ꮔ Ꮕ Ꮖ Ꮗ Ꮘ Ꮙ Ꮚ Ꮛ Ꮜ Ꮝ Ꮞ Ꮟ Ꮠ Ꮡ Ꮢ Ꮣ Ꮤ Ꮥ Ꮦ Ꮧ Ꮨ Ꮩ Ꮪ Ꮫ Ꮬ Ꮭ Ꮮ Ꮯ Ꮰ Ꮱ Ꮲ Ꮳ Ꮴ Ꮵ Ꮶ Ꮷ
Ꮸ Ꮹ Ꮺ Ꮻ Ꮼ Ꮽ Ꮾ Ꮿ Ᏸ Ᏹ Ᏺ Ᏻ Ᏼ",
- 5: "Ꭰ Ꭶ Ꭽ Ꮃ Ꮉ Ꮎ Ꮖ Ꮜ Ꮣ Ꮬ Ꮳ Ꮹ Ꮿ",
- },
- "cs": {
- 0: "a á b c č d ď e é ě f g h ch i í j k l m n ň o ó p q r ř s š t ť u ú
ů v w x y ý z ž",
- },
- "cy": {
- 0: "a á à â ä b c ch d dd e é è ê ë f ff g ng h i í ì î ï l ll m n o ó ò
ô ö p ph r rh s t th u ú ù û ü w ẃ ẁ ŵ ẅ y ý ỳ ŷ ÿ",
- 3: "j k q v x z",
- },
- "da": {
- 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 æ ø å",
- 2: "- ‐ – , ; : ! ? . … ' ‘ ’ \" “ ” ( ) [ ] @ * / & # † ′ ″ §",
- 3: "á é è ê ë ü ä ö",
- 4: "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",
- 5: "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 Æ Ø Å",
- },
- "dav": {
- 0: "a b c d e f g h i j k l m n o p r s t u v w y z",
- 3: "q x",
- 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z",
- },
- "de": {
- 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",
- 2: "- ‐ – — , ; : ! ? . … ' ‘ ‚ \" “ „ « » ( ) [ ] { } @ * / & # §",
- 3: "á à ă â å ã ā æ ç é è ĕ ê ë ē í ì ĭ î ï ī ñ ó ò ŏ ô ø ō œ ú ù ŭ û ū
ÿ",
- 4: "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",
- 5: "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",
- },
- "dje": {
- 0: "a ã b c d e ẽ f g h i j k l m n ɲ ŋ o õ p q r s š t u w x y z ž",
- 3: "v",
- 5: "A B C D E F G H I J K L M N Ɲ Ŋ O P Q R S T U W X Y Z",
- },
- "dua": {
- 0: "a á b ɓ c d ɗ e é ɛ ɛ́ f g i í j k l m n ny ŋ o ó ɔ ɔ́ p r s t u ú ū
w y",
- 3: "h q v x z",
- 5: "A B Ɓ C D Ɗ E Ɛ F G I J K L M N Ŋ O Ɔ P S T U W Y",
- },
- "dyo": {
- 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",
- 3: "z",
- 5: "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",
- },
- "dz": {
- 0: "ཀ ྐ ཁ ྑ ག ྒ ང ྔ ཅ ཆ ཇ ྗ ཉ ྙ ཏ ྟ ཐ ད ྡ ན ྣ པ ྤ ཕ བ ྦ མ ྨ ཙ ྩ ཚ ཛ ྫ ཝ
ྭ ཞ ཟ འ ཡ ྱ ར ྲ ལ ླ ཤ ྵ ས ཧ ྷ ཨ ི ུ ེ ོ",
- 3: "ཊ ཋ ཌ ཎ ཥ",
- },
- "ebu": {
- 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",
- 5: "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",
- },
- "ee": {
- 0: "a á à ã b d ɖ e é è ẽ ɛ ɛ́ ɛ̀ ɛ̃ f ƒ g ɣ h i í ì ĩ k l m n ŋ o ó ò õ
ɔ ɔ́ ɔ̀ ɔ̃ p r s t u ú ù ũ v ʋ w x y z",
- 3: "c j q",
- 5: "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",
- },
- "el": {
- 0: "α ά β γ δ ε έ ζ η ή θ ι ί ϊ ΐ κ λ μ ν ξ ο ό π ρ σ ς τ υ ύ ϋ ΰ φ χ ψ
ω ώ",
- 2: "- ‐ – — , ; : ! . … \" ( ) [ ] @ * / \\ & §",
- 4: "α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω",
- 5: "Α Β Γ Δ Ε Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο Π Ρ Σ Τ Υ Φ Χ Ψ Ω",
- },
- "el_POLYTON": {
- 0: "α ἀ ἄ ἂ ἆ ἁ ἅ ἃ ἇ ά ὰ ᾶ β γ δ ε ἐ ἔ ἒ ἑ ἕ ἓ έ ὲ ζ η ἠ ἤ ἢ ἦ ἡ ἥ ἣ ἧ
ή ὴ ῆ θ ι ἰ ἴ ἲ ἶ ἱ ἵ ἳ ἷ ί ὶ ῖ ϊ ΐ ῒ ῗ κ λ μ ν ξ ο ὄ ὂ ὃ ό ὸ π ρ σ ς τ υ ὐ
ὔ ὒ ὖ ὑ ὕ ὓ ὗ ύ ὺ ῦ ϋ ΰ ῢ ῧ φ χ ψ ω ὤ ὢ ὦ ὥ ὣ ὧ ώ ὼ ῶ",
- },
- "en": {
- 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",
- 2: "- ‐ – — , ; : ! ? . … ' ‘ ’ \" “ ” ( ) [ ] @ * / & # † ‡ ′ ″ §",
- 3: "á à ă â å ä ã ā æ ç é è ĕ ê ë ē í ì ĭ î ï ī ñ ó ò ŏ ô ö ø ō œ ú ù ŭ
û ü ū ÿ",
- 4: "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",
- 5: "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",
- },
- "en_Dsrt": {
-
0: "𐐨 𐐩 𐐪 𐐫 𐐬 𐐭 𐐮 𐐯 𐐰 𐐱 𐐲 𐐳 𐐴 𐐵 𐐶 𐐷 𐐸 𐐹 𐐺 𐐻 𐐼 𐐽 𐐾 𐐿 𐑀 𐑁 𐑂 𐑃 𐑄 𐑅 𐑆 𐑇 𐑈 𐑉 𐑊 𐑋 𐑌 𐑍 𐑎 𐑏",
- 4: "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",
- },
- "en_GB": {
- 4: "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",
- },
- "en_Shaw": {
-
0: "𐑐 𐑑 𐑒 𐑓 𐑔 𐑕 𐑖 𐑗 𐑘 𐑙 𐑚 𐑛 𐑜 𐑝 𐑞 𐑟 𐑠 𐑡 𐑢 𐑣 𐑤 𐑥 𐑦 𐑧 𐑨 𐑩 𐑪 𐑫 𐑬 𐑭 𐑮 𐑯 𐑰 𐑱 𐑲 𐑳 𐑴 𐑵 𐑶 𐑷 𐑸 𐑹 𐑺 𐑻 𐑼 𐑽 𐑾 𐑿",
- 4: "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",
- },
- "eo": {
- 0: "a b c ĉ d e f g ĝ h ĥ i j ĵ k l m n o p r s ŝ t u ŭ v z",
- 3: "q w x y",
- 5: "A B C Ĉ D E F G Ĝ H Ĥ I J Ĵ K L M N O P R S Ŝ T U Ŭ V Z",
- },
- "es": {
- 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",
- 2: "- ‐ – — , ; : ! ¡ ? ¿ . … ' ‘ ’ \" “ ” « » ( ) [ ] @ * / \\ & # †
‡ ′ ″ §",
- 3: "à ă â å ä ã ā æ ç è ĕ ê ë ē ì ĭ î ï ī º ò ŏ ô ö ø ō œ ù ŭ û ū ÿ",
- 4: "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",
- 5: "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",
- },
- "et": {
- 0: "a b c d e f g h i j k l m n o p q r s š z ž t u v w õ ä ö ü x y",
- 3: "á à â å ā æ ç é è ê ë ē í ì î ï ī ñ ó ò ŏ ô ø ō œ ú ù û ū",
- 4: "a b c d e f g h i j k l m n o p q r s š z ž t u v w õ ä ö ü x y",
- 5: "A B C D E F G H I J K L M N O P Q R S Š Z Ž T U V Õ Ä Ö Ü X Y",
- },
- "eu": {
- 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",
- 4: "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",
- 5: "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",
- },
- "ewo": {
- 0: "a á à â ǎ b d dz e é è ê ě ǝ ǝ́ ǝ̀ ǝ̂ ǝ̌ ɛ ɛ́ ɛ̀ ɛ̂ ɛ̌ f g h i í ì î
ǐ k kp l m n ń ǹ ng nk ŋ o ó ò ô ǒ ɔ ɔ́ ɔ̀ ɔ̂ ɔ̌ p r s t ts u ú ù û ǔ v w y
z",
- 3: "c j q x",
- 5: "A B D E Ǝ Ɛ F G H I K L M N Ŋ O Ɔ P R S T U V W Y Z",
- },
- "fa": {
- 0: "ً ٍ ٌ ّ ٔ آ ا ء أ ؤ ئ ب پ ت ث ج چ ح خ د ذ ر ز ژ س ش ص ض ط ظ ع غ ف ق
ک گ ل م ن و ه ة ی",
- 2: "- ‐ ، ٫ ٬ ؛ : ! ؟ . … « » ( ) [ ] * / \\",
- 3: "\u200c \u200d \u200e \u200f َ ِ ُ ْ ٖ ٰ ۰ ۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹",
- 4: "﷼ 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",
- 5: "آ ا ب پ ت ث ج چ ح خ د ذ ر ز ژ س ش ص ض ط ظ ع غ ف ق ک گ ل م ن و ه ی",
- },
- "fa_AF": {
- 3: "ٖ ٰ \u200c \u200d ټ ځ څ ډ ړ ږ ښ ګ ڼ ي",
- },
- "ff": {
- 0: "a b ɓ c d ɗ e f g h i j k l m n ñ ŋ o p r s t u w y ƴ",
- 3: "q v x z",
- 5: "A B Ɓ C D Ɗ E F G H I J K L M N Ñ Ŋ O P R S T U W Y Ƴ",
- },
- "fi": {
- 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 ž å ä ö",
- 3: "á à â ã č ç đ é è ë ǧ ǥ ȟ í ï ǩ ń ñ ŋ ô õ œ ř ŧ ú ü ʒ ǯ æ ø",
- 4: "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",
- 5: "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 Å Ä Ö",
- },
- "fil": {
- 0: "a b c d e f g h i j k l m n ñ ng o p q r s t u v w x y z",
- 3: "á à â é è ê í ì î ó ò ô ú ù û",
- 5: "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",
- },
- "fo": {
- 0: "a á b d ð e f g h i í j k l m n o ó p r s t u ú v x y ý æ ø",
- 3: "c q w z",
- },
- "fr": {
- 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",
- 2: "- ‐ – — , ; : ! ? . … ’ « » ( ) [ ] @ * / & # † ‡ §",
- 3: "á å ä ã ā ē í ì ī ñ ó ò ö ø ú ǔ",
- 4: "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",
- },
- "fur": {
- 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",
- 3: "å č é ë ğ ï ñ ó š ü",
- },
- "ga": {
- 0: "a á b c d e é f g h i í l m n o ó p r s t u ú",
- 3: "ḃ ċ ḋ ḟ ġ j k ṁ ṗ q ṡ ṫ v w x y z",
- },
- "gl": {
- 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",
- 5: "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",
- },
- "gsw": {
- 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",
- 3: "á à ă â å ā æ ç é è ĕ ê ë ē í ì ĭ î ï ī ñ ó ò ŏ ô ø ō œ ú ù ŭ û ū ÿ",
- 4: "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",
- },
- "gu": {
- 0: "઼ ૐ ં ઁ ઃ અ આ ઇ ઈ ઉ ઊ ઋ ૠ ઍ એ ઐ ઑ ઓ ઔ ક ખ ગ ઘ ઙ ચ છ જ ઝ ઞ ટ ઠ ડ ઢ ણ
ત થ દ ધ ન પ ફ બ ભ મ ય ર લ વ શ ષ સ હ ળ ઽ ા િ ી ુ ૂ ૃ ૄ ૅ ે ૈ ૉ ો ૌ ્",
- 3: "\u200c \u200d",
- 4: "ર ૂ",
- 5: "અ આ ઇ ઈ ઉ ઊ ઋ એ ઐ ઓ ઔ ક ખ ગ ઘ ઙ ચ છ જ ઝ ઞ ટ ઠ ડ ઢ ણ ત થ દ ધ ન પ ફ બ
ભ મ ય ર લ વ શ ષ સ હ ળ",
- },
- "guz": {
- 0: "a b c d e f g h i j k l m n o p r s t u v w y z",
- 3: "q x",
- 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z",
- },
- "gv": {
- 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",
- },
- "ha": {
- 0: "a b ɓ c d ɗ e f g h i j k ƙ l m n o r s sh t ts u w y ʼy z ʼ",
- 3: "á à â é è ê í ì î ó ò ô p q r̃ ú ù û v x ƴ",
- 4: "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",
- },
- "haw": {
- 0: "a ā e ē i ī o ō u ū h k l m n p w ʻ",
- 3: "b c d f g j q r s t v x y z",
- },
- "he": {
- 0: "א ב ג ד ה ו ז ח ט י כ ך ל מ ם נ ן ס ע פ ף צ ץ ק ר ש ת",
- 3: "ֽ ׄ \u200e \u200f ְ ֱ ֲ ֳ ִ ֵ ֶ ַ ָ ֹ ֻ ׂ ׁ ּ ֿ ־ ׳ ״",
- 5: "א ב ג ד ה ו ז ח ט י כ ל מ נ ס ע פ צ ק ר ש ת",
- },
- "hi": {
- 0: "़ ॐ ं ँ ः अ आ इ ई उ ऊ ऋ ऌ ऍ ए ऐ ऑ ओ औ क ख ग घ ङ च छ ज झ ञ ट ठ ड ढ ण
त थ द ध न प फ ब भ म य र ल ळ व श ष स ह ऽ ा ि ी ु ू ृ ॄ ॅ े ै ॉ ो ौ ्",
- 3: "\u200c \u200d",
- 4: "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",
- },
- "hr": {
- 0: "a b c č ć d dž đ e f g h i j k l lj m n nj o p r s š t u v z ž",
- 3: "q w x y",
- 4: "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",
- 5: "A B C Č Ć D DŽ Đ E F G H I J K L LJ M N NJ O P Q R S Š T U V W X Y Z
Ž",
- },
- "hu": {
- 0: "a á b c cs ccs d dz ddz dzs ddzs e é f g gy ggy h i í j k l ly lly m
n ny nny o ó ö ő p r s sz ssz t ty tty u ú ü ű v z zs zzs",
- 2: "- – , ; : ! ? . … ' ’ \" ” „ « » ( ) [ ] { } 〈 〉 @ * / & # ⸓ § ~",
- 3: "à ă â å ä ã ā æ ç è ĕ ê ë ē ì ĭ î ï ī ñ ò ŏ ô ø ō œ q ù ŭ û ū w x y
ÿ",
- 5: "A Á B C CS D DZ DZS E É F G GY H I Í J K L LY M N NY O Ó Ö Ő P Q R S
SZ T TY U Ú Ü Ű V W X Y Z ZS",
- },
- "hy": {
- 0: "֊ ՝ ՜ ՞ ՚ ՛ ՟ ա բ գ դ ե զ է ը թ ժ ի լ խ ծ կ հ ձ ղ ճ մ յ ն շ ո չ պ ջ
ռ ս վ տ ր ց ւ փ ք և օ ֆ",
- },
- "ia": {
- 0: "a b c ch d e f g h i j k l m n o p ph q r s t u v w x y z",
- },
- "id": {
- 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",
- 4: "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",
- 5: "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",
- },
- "ig": {
- 0: "a b ch d e ẹ f g gb gh gw h i ị j k kp kw l m n ṅ nw ny o ọ p r s sh
t u ụ v w y z",
- 5: "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",
- },
- "ii": {
- 0: "ꀀ ꀀ ꀁ ꀂ ꀃ ꀄ ꀅ ꀆ ꀇ ꀈ ꀉ ꀊ ꀋ ꀌ ꀍ ꀎ ꀏ ꀐ ꀑ ꀒ ꀓ ꀔ ꀕ
ꀖ ꀗ ꀘ ꀙ ꀚ ꀛ ꀜ ꀝ ꀞ ꀟ ꀠ ꀡ ꀢ ꀣ ꀤ ꀥ ꀦ ꀧ ꀨ ꀩ ꀪ ꀫ ꀬ ꀭ ꀮ
ꀯ ꀰ ꀱ ꀲ ꀳ ꀴ ꀵ ꀶ ꀷ ꀸ ꀹ ꀺ ꀻ ꀼ ꀽ ꀾ ꀿ ꁀ ꁁ ꁂ ꁃ ꁄ ꁅ ꁆ ꁇ
ꁈ ꁉ ꁊ ꁋ ꁌ ꁍ ꁎ ꁏ ꁐ ꁑ ꁒ ꁓ ꁔ ꁕ ꁖ ꁗ ꁘ ꁙ ꁚ ꁛ ꁜ ꁝ ꁞ ꁟ ꁠ
ꁡ ꁢ ꁣ ꁤ ꁥ ꁦ ꁧ ꁨ ꁩ ꁪ ꁫ ꁬ ꁭ ꁮ ꁯ ꁰ ꁱ ꁲ ꁳ ꁴ ꁵ ꁶ ꁷ ꁸ ꁹ
ꁺ ꁻ ꁼ ꁽ ꁾ ꁿ ꂀ ꂁ ꂂ ꂃ ꂄ ꂅ ꂆ ꂇ ꂈ ꂉ ꂊ ꂋ ꂌ ꂍ ꂎ ꂏ ꂐ ꂑ ꂒ
ꂓ ꂔ ꂕ ꂖ ꂗ ꂘ ꂙ ꂚ ꂛ ꂜ ꂝ ꂞ ꂟ ꂠ ꂡ ꂢ ꂣ ꂤ ꂥ ꂦ ꂧ ꂨ ꂩ ꂪ ꂫ
ꂬ ꂭ ꂮ ꂯ ꂰ ꂱ ꂲ ꂳ ꂴ ꂵ ꂶ ꂷ ꂸ ꂹ ꂺ ꂻ ꂼ ꂽ ꂾ ꂿ ꃀ ꃁ ꃂ ꃃ ꃄ
ꃅ ꃆ ꃇ ꃈ ꃉ ꃊ ꃋ ꃌ ꃍ ꃎ ꃏ ꃐ ꃑ ꃒ ꃓ ꃔ ꃕ ꃖ ꃗ ꃘ ꃙ ꃚ ꃛ ꃜ ꃝ
ꃞ ꃟ ꃠ ꃡ ꃢ ꃣ ꃤ ꃥ ꃦ ꃧ ꃨ ꃩ ꃪ ꃫ ꃬ ꃭ ꃮ ꃯ ꃰ ꃱ ꃲ ꃳ ꃴ ꃵ ꃶ
ꃷ ꃸ ꃹ ꃺ ꃻ ꃼ ꃽ ꃾ ꃿ ꄀ ꄁ ꄂ ꄃ ꄄ ꄅ ꄆ ꄇ ꄈ ꄉ ꄊ ꄋ ꄌ ꄍ ꄎ ꄏ
ꄐ ꄑ ꄒ ꄓ ꄔ ꄕ ꄖ ꄗ ꄘ ꄙ ꄚ ꄛ ꄜ ꄝ ꄞ ꄟ ꄠ ꄡ ꄢ ꄣ ꄤ ꄥ ꄦ ꄧ ꄨ
ꄩ ꄪ ꄫ ꄬ ꄭ ꄮ ꄯ ꄰ ꄱ ꄲ ꄳ ꄴ ꄵ ꄶ ꄷ ꄸ ꄹ ꄺ ꄻ ꄼ ꄽ ꄾ ꄿ ꅀ ꅁ
ꅂ ꅃ ꅄ ꅅ ꅆ ꅇ ꅈ ꅉ ꅊ ꅋ ꅌ ꅍ ꅎ ꅏ ꅐ ꅑ ꅒ ꅓ ꅔ ꅕ ꅖ ꅗ ꅘ ꅙ ꅚ
ꅛ ꅜ ꅝ ꅞ ꅟ ꅠ ꅡ ꅢ ꅣ ꅤ ꅥ ꅦ ꅧ ꅨ ꅩ ꅪ ꅫ ꅬ ꅭ ꅮ ꅯ ꅰ ꅱ ꅲ ꅳ
ꅴ ꅵ ꅶ ꅷ ꅸ ꅹ ꅺ ꅻ ꅼ ꅽ ꅾ ꅿ ꆀ ꆁ ꆂ ꆃ ꆄ ꆅ ꆆ ꆇ ꆈ ꆉ ꆊ ꆋ ꆌ
ꆍ ꆎ ꆏ ꆐ ꆑ ꆒ ꆓ ꆔ ꆕ ꆖ ꆗ ꆘ ꆙ ꆚ ꆛ ꆜ ꆝ ꆞ ꆟ ꆠ ꆡ ꆢ ꆣ ꆤ ꆥ
ꆦ ꆧ ꆨ ꆩ ꆪ ꆫ ꆬ ꆭ ꆮ ꆯ ꆰ ꆱ ꆲ ꆳ ꆴ ꆵ ꆶ ꆷ ꆸ ꆹ ꆺ ꆻ ꆼ ꆽ ꆾ
ꆿ ꇀ ꇁ ꇂ ꇃ ꇄ ꇅ ꇆ ꇇ ꇈ ꇉ ꇊ ꇋ ꇌ ꇍ ꇎ ꇏ ꇐ ꇑ ꇒ ꇓ ꇔ ꇕ ꇖ ꇗ
ꇘ ꇙ ꇚ ꇛ ꇜ ꇝ ꇞ ꇟ ꇠ ꇡ ꇢ ꇣ ꇤ ꇥ ꇦ ꇧ ꇨ ꇩ ꇪ ꇫ ꇬ ꇭ ꇮ ꇯ ꇰ
ꇱ ꇲ ꇳ ꇴ ꇵ ꇶ ꇷ ꇸ ꇹ ꇺ ꇻ ꇼ ꇽ ꇾ ꇿ ꈀ ꈁ ꈂ ꈃ ꈄ ꈅ ꈆ ꈇ ꈈ ꈉ
ꈊ ꈋ ꈌ ꈍ ꈎ ꈏ ꈐ ꈑ ꈒ ꈓ ꈔ ꈕ ꈖ ꈗ ꈘ ꈙ ꈚ ꈛ ꈜ ꈝ ꈞ ꈟ ꈠ ꈡ ꈢ
ꈣ ꈤ ꈥ ꈦ ꈧ ꈨ ꈩ ꈪ ꈫ ꈬ ꈭ ꈮ ꈯ ꈰ ꈱ ꈲ ꈳ ꈴ ꈵ ꈶ ꈷ ꈸ ꈹ ꈺ ꈻ
ꈼ ꈽ ꈾ ꈿ ꉀ ꉁ ꉂ ꉃ ꉄ ꉅ ꉆ ꉇ ꉈ ꉉ ꉊ ꉋ ꉌ ꉍ ꉎ ꉏ ꉐ ꉑ ꉒ ꉓ ꉔ
ꉕ ꉖ ꉗ ꉘ ꉙ ꉚ ꉛ ꉜ ꉝ ꉞ ꉟ ꉠ ꉡ ꉢ ꉣ ꉤ ꉥ ꉦ ꉧ ꉨ ꉩ ꉪ ꉫ ꉬ ꉭ
ꉮ ꉯ ꉰ ꉱ ꉲ ꉳ ꉴ ꉵ ꉶ ꉷ ꉸ ꉹ ꉺ ꉻ ꉼ ꉽ ꉾ ꉿ ꊀ ꊁ ꊂ ꊃ ꊄ ꊅ ꊆ
ꊇ ꊈ ꊉ ꊊ ꊋ ꊌ ꊍ ꊎ ꊏ ꊐ ꊑ ꊒ ꊓ ꊔ ꊕ ꊖ ꊗ ꊘ ꊙ ꊚ ꊛ ꊜ ꊝ ꊞ ꊟ
ꊠ ꊡ ꊢ ꊣ ꊤ ꊥ ꊦ ꊧ ꊨ ꊩ ꊪ ꊫ ꊬ ꊭ ꊮ ꊯ ꊰ ꊱ ꊲ ꊳ ꊴ ꊵ ꊶ ꊷ ꊸ
ꊹ ꊺ ꊻ ꊼ ꊽ ꊾ ꊿ ꋀ ꋁ ꋂ ꋃ ꋄ ꋅ ꋆ ꋇ ꋈ ꋉ ꋊ ꋋ ꋌ ꋍ ꋎ ꋏ ꋐ ꋑ
ꋒ ꋓ ꋔ ꋕ ꋖ ꋗ ꋘ ꋙ ꋚ ꋛ ꋜ ꋝ ꋞ ꋟ ꋠ ꋡ ꋢ ꋣ ꋤ ꋥ ꋦ ꋧ ꋨ ꋩ ꋪ
ꋫ ꋬ ꋭ ꋮ ꋯ ꋰ ꋱ ꋲ ꋳ ꋴ ꋵ ꋶ ꋷ ꋸ ꋹ ꋺ ꋻ ꋼ ꋽ ꋾ ꋿ ꌀ ꌁ ꌂ ꌃ
ꌄ ꌅ ꌆ ꌇ ꌈ ꌉ ꌊ ꌋ ꌌ ꌍ ꌎ ꌏ ꌐ ꌑ ꌒ ꌓ ꌔ ꌕ ꌖ ꌗ ꌘ ꌙ ꌚ ꌛ ꌜ
ꌝ ꌞ ꌟ ꌠ ꌡ ꌢ ꌣ ꌤ ꌥ ꌦ ꌧ ꌨ ꌩ ꌪ ꌫ ꌬ ꌭ ꌮ ꌯ ꌰ ꌱ ꌲ ꌳ ꌴ ꌵ
ꌶ ꌷ ꌸ ꌹ ꌺ ꌻ ꌼ ꌽ ꌾ ꌿ ꍀ ꍁ ꍂ ꍃ ꍄ ꍅ ꍆ ꍇ ꍈ ꍉ ꍊ ꍋ ꍌ ꍍ ꍎ
ꍏ ꍐ ꍑ ꍒ ꍓ ꍔ ꍕ ꍖ ꍗ ꍘ ꍙ ꍚ ꍛ ꍜ ꍝ ꍞ ꍟ ꍠ ꍡ ꍢ ꍣ ꍤ ꍥ ꍦ ꍧ
ꍨ ꍩ ꍪ ꍫ ꍬ ꍭ ꍮ ꍯ ꍰ ꍱ ꍲ ꍳ ꍴ ꍵ ꍶ ꍷ ꍸ ꍹ ꍺ ꍻ ꍼ ꍽ ꍾ ꍿ ꎀ
ꎁ ꎂ ꎃ ꎄ ꎅ ꎆ ꎇ ꎈ ꎉ ꎊ ꎋ ꎌ ꎍ ꎎ ꎏ ꎐ ꎑ ꎒ ꎓ ꎔ ꎕ ꎖ ꎗ ꎘ ꎙ
ꎚ ꎛ ꎜ ꎝ ꎞ ꎟ ꎠ ꎡ ꎢ ꎣ ꎤ ꎥ ꎦ ꎧ ꎨ ꎩ ꎪ ꎫ ꎬ ꎭ ꎮ ꎯ ꎰ ꎱ ꎲ
ꎳ ꎴ ꎵ ꎶ ꎷ ꎸ ꎹ ꎺ ꎻ ꎼ ꎽ ꎾ ꎿ ꏀ ꏁ ꏂ ꏃ ꏄ ꏅ ꏆ ꏇ ꏈ ꏉ ꏊ ꏋ
ꏌ ꏍ ꏎ ꏏ ꏐ ꏑ ꏒ ꏓ ꏔ ꏕ ꏖ ꏗ ꏘ ꏙ ꏚ ꏛ ꏜ ꏝ ꏞ ꏟ ꏠ ꏡ ꏢ ꏣ ꏤ
ꏥ ꏦ ꏧ ꏨ ꏩ ꏪ ꏫ ꏬ ꏭ ꏮ ꏯ ꏰ ꏱ ꏲ ꏳ ꏴ ꏵ ꏶ ꏷ ꏸ ꏹ ꏺ ꏻ ꏼ ꏽ
ꏾ ꏿ ꐀ ꐁ ꐂ ꐃ ꐄ ꐅ ꐆ ꐇ ꐈ ꐉ ꐊ ꐋ ꐌ ꐍ ꐎ ꐏ ꐐ ꐑ ꐒ ꐓ ꐔ ꐕ ꐖ
ꐗ ꐘ ꐙ ꐚ ꐛ ꐜ ꐝ ꐞ ꐟ ꐠ ꐡ ꐢ ꐣ ꐤ ꐥ ꐦ ꐧ ꐨ ꐩ ꐪ ꐫ ꐬ ꐭ ꐮ ꐯ
ꐰ ꐱ ꐲ ꐳ ꐴ ꐵ ꐶ ꐷ ꐸ ꐹ ꐺ ꐻ ꐼ ꐽ ꐾ ꐿ ꑀ ꑁ ꑂ ꑃ ꑄ ꑅ ꑆ ꑇ ꑈ
ꑉ ꑊ ꑋ ꑌ ꑍ ꑎ ꑏ ꑐ ꑑ ꑒ ꑓ ꑔ ꑕ ꑖ ꑗ ꑘ ꑙ ꑚ ꑛ ꑜ ꑝ ꑞ ꑟ ꑠ ꑡ
ꑢ ꑣ ꑤ ꑥ ꑦ ꑧ ꑨ ꑩ ꑪ ꑫ ꑬ ꑭ ꑮ ꑯ ꑰ ꑱ ꑲ ꑳ ꑴ ꑵ ꑶ ꑷ ꑸ ꑹ ꑺ
ꑻ ꑼ ꑽ ꑾ ꑿ ꒀ ꒁ ꒂ ꒃ ꒄ ꒅ ꒆ ꒇ ꒈ ꒉ ꒊ ꒋ ꒌ",
- },
- "is": {
- 0: "a á b d ð e é f g h i í j k l m n o ó p r s t u ú v y ý þ æ ö",
- 3: "c q w x z",
- },
- "it": {
- 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",
- 2: "- — , ; : ! ? . … “ ” ( ) [ ] { } @ /",
- 3: "í ï ú",
- 4: "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",
- 5: "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",
- },
- "ja": {
- 0: "ゞ ゝ ヽ ヾ ぁ ァ あ ア ぃ ィ い イ ぅ ゥ う ウ ヴ ぇ ェ え エ ぉ ォ
お オ ヵ か カ が ガ き キ ぎ ギ く ク ぐ グ ヶ け ケ げ ゲ こ コ ご ゴ さ
サ ざ ザ し シ じ ジ す ス ず ズ せ セ ぜ ゼ そ ソ ぞ ゾ た タ だ ダ ち チ
ぢ ヂ っ ッ つ ツ づ ヅ て テ で デ と ト ど ド な ナ に ニ ぬ ヌ ね ネ の
ノ は ハ ば バ ぱ パ ひ ヒ び ビ ぴ ピ ふ フ ぶ ブ ぷ プ へ ヘ べ ベ ぺ ペ
ほ ホ ぼ ボ ぽ ポ ま マ み ミ む ム め メ も モ ゃ ャ や ヤ ゅ ュ ゆ ユ ょ
ョ よ ヨ ら ラ り リ る ル れ レ ろ ロ ゎ ヮ わ ワ ゐ ヰ ゑ ヱ を ヲ ん ン
一 丁 七 万 万 丈 三 上 下 不 与 且 世 丘 丙 両 並 中 丸 丹 主 久 乏 乗 乙
九 乱 乳 乾 亀 了 予 争 事 二 互 五 井 亜 亡 交 亨 享 享 京 亭 人 仁 今 介
仏 仕 他 付 仙 代 代 令 以 仮 仰 仲 件 任 企 伏 伏 伐 休 会 伝 伯 伴 伸 伺
似 但 位 位 低 住 佐 体 何 余 作 佳 併 使 例 侍 供 依 価 侮 侯 侵 便 係 促
俊 俗 保 信 修 俳 俵 俸 倉 個 倍 倒 候 借 倣 値 倫 倹 偉 偏 停 健 側 側 偵
偶 偽 傍 傑 傘 備 催 債 傷 傾 働 像 僕 僚 僧 儀 億 儒 償 優 元 元 兄 充 兆
先 光 克 免 児 党 入 全 八 八 公 六 共 兵 具 典 兼 内 円 冊 再 冒 冗 写 冠
冬 冷 准 凍 凝 凡 処 凶 凸 凸 凹 出 刀 刃 分 分 切 刈 刊 刑 列 初 判 別 利
到 制 制 刷 券 刺 刻 則 削 前 剖 剛 剣 剤 副 剰 割 創 劇 力 功 加 劣 助 努
励 労 効 劾 勅 勇 勉 動 勘 務 勝 募 勢 勤 勧 勲 勺 匁 包 化 北 匠 匹 匹 区
医 匿 十 千 升 午 半 卑 卑 卒 卓 協 南 単 博 占 印 危 即 即 却 卵 卸 厄 厘
厚 原 厳 去 参 又 及 及 友 双 反 収 叔 取 受 叙 口 口 古 句 叫 召 可 台 史
右 号 司 各 合 吉 同 同 名 后 吏 吐 向 君 吟 否 含 吸 吹 呈 呈 呉 告 周 味
呼 命 和 咲 哀 品 員 哲 唆 唇 唐 唯 唱 商 問 啓 善 喚 喜 喝 喪 喫 営 嗣 嘆
嘉 嘱 器 噴 嚇 囚 四 回 因 団 困 囲 図 固 国 圏 園 土 圧 在 地 坂 均 坊 坑
坪 垂 型 垣 埋 城 域 執 培 基 堀 堂 堅 堕 堤 堪 報 場 塀 塁 塊 塑 塔 塗 塚
塩 塾 境 墓 増 墜 墨 墳 墾 壁 壇 壊 壌 士 壮 声 声 壱 売 変 夏 夕 外 多 夜
夢 大 天 天 太 夫 央 失 奇 奉 奏 契 奔 奥 奨 奪 奮 女 奴 好 如 如 妃 妄 妊
妙 妥 妨 妹 妻 姉 始 姓 委 姫 姻 姿 威 娘 娠 娯 婆 婚 婦 婿 媒 嫁 嫌 嫡 嬢
子 孔 字 存 孝 季 孤 学 孫 宅 宇 宇 守 安 完 宗 宗 官 宙 定 宜 宝 実 客 客
宣 室 宮 宰 害 害 宴 宵 家 容 宿 寂 寄 密 富 寒 寛 寝 察 寡 寧 審 寮 寸 寺
対 寿 封 専 射 将 尉 尉 尊 尋 導 小 少 尚 就 尺 尼 尼 尽 尾 尿 局 居 屈 届
屋 展 属 層 履 屯 山 岐 岩 岬 岳 岸 峠 峡 峰 島 崇 崎 崩 川 州 巡 巣 工 工
左 巧 巨 差 己 巻 市 布 帆 希 帝 帥 師 席 帯 帰 帳 常 帽 幅 幕 幣 干 干 平
年 幸 幹 幻 幻 幼 幽 幾 庁 広 床 序 底 店 府 度 座 庫 庭 庶 庶 康 庸 廃 廉
廊 延 廷 建 弁 弊 式 弐 弓 弓 弔 引 弘 弟 弦 弧 弱 張 強 弾 当 形 彩 彫 彰
影 役 彼 往 征 径 待 律 後 徐 徒 従 得 御 復 循 微 徳 徴 徹 心 必 忌 忍 志
志 忘 忙 応 忠 快 念 怒 怖 思 怠 急 性 怪 恋 恐 恒 恥 恨 恩 恭 息 恵 悔 悟
悠 患 悦 悩 悪 悲 悼 情 惑 惜 惨 惰 想 愁 愉 意 愚 愛 感 慈 態 慌 慎 慕 慢
慣 慨 慮 慰 慶 憂 憎 憤 憩 憲 憶 憾 懇 懐 懲 懸 成 成 我 戒 戦 戯 戸 戻 房
所 扇 扉 手 才 打 払 扱 扶 批 承 技 抄 把 抑 投 抗 折 抜 択 披 抱 抵 抹 押
抽 担 拍 拐 拒 拓 拘 拙 招 拝 拠 拡 括 拷 拾 持 指 挑 挙 挟 振 挿 捕 捜 捨
据 掃 授 掌 排 掘 掛 採 探 接 控 推 措 掲 描 提 揚 換 握 揮 援 揺 損 搬 搭
携 搾 摂 摘 摩 撃 撤 撮 撲 擁 操 擦 擬 支 改 攻 放 政 故 敏 救 敗 教 敢 散
敬 数 整 敵 敷 文 斉 斎 斗 料 斜 斤 斥 断 新 方 施 旅 旋 族 旗 既 日 旧 旧
旨 早 旬 昆 昇 昌 明 易 昔 星 映 春 昨 昭 是 昼 時 晩 普 景 晴 晶 暁 暇 暑
暖 暗 暦 暫 暮 暴 曇 曜 曲 更 書 曹 替 最 月 有 服 朕 朗 望 朝 期 木 未 未
末 本 札 朱 朴 机 朽 杉 材 村 束 条 来 杯 東 松 板 析 林 枚 果 枝 枠 枢 枯
架 柄 某 染 柔 柱 柳 査 栄 栓 校 株 核 根 格 栽 桃 案 桑 桜 桟 梅 械 棄 棋
棒 棚 棟 森 棺 植 検 業 極 楼 楽 概 構 様 槽 標 模 権 横 樹 橋 機 欄 欠 次
欧 欲 欺 款 歌 歓 止 正 武 歩 歯 歳 歴 死 殉 殉 殊 残 殖 殴 段 殺 殻 殿 母
毎 毒 比 毛 氏 民 気 水 氷 永 汁 求 汎 汗 汚 江 池 決 汽 沈 沖 没 沢 河 沸
油 治 沼 沿 況 泉 泊 泌 法 泡 泡 波 泣 泥 注 泰 泳 洋 洗 洞 津 洪 活 派 流
浄 浅 浜 浦 浪 浮 浴 海 浸 消 涙 涯 液 涼 淑 淡 深 混 添 清 渇 渇 済 渉 渋
渓 減 渡 渦 温 測 港 湖 湯 湾 湾 湿 満 源 準 溝 溶 滅 滋 滑 滝 滞 滴 漁 漂
漆 漏 演 漠 漢 漫 漬 漸 潔 潜 潟 潤 潮 澄 激 濁 濃 濫 濯 瀬 火 灯 灰 災 炉
炊 炎 炭 点 為 烈 無 焦 然 焼 煙 照 煩 煮 熟 熱 燃 燥 爆 爵 父 片 版 牙 牛
牧 物 牲 特 犠 犬 犯 状 狂 狩 独 狭 猛 猟 猫 献 猶 猿 獄 獣 獲 玄 率 玉 王
珍 珠 班 現 球 理 琴 環 璽 瓶 甘 甚 生 産 用 田 田 由 甲 申 男 町 画 界 畑
畔 留 畜 畝 略 番 異 畳 疎 疑 疫 疲 疾 病 症 痘 痛 痢 痴 療 癒 癖 発 登 白
百 的 皆 皇 皮 皿 盆 益 盗 盛 盟 監 盤 目 盲 直 相 盾 省 看 県 真 眠 眺 眼
着 睡 督 瞬 矛 矢 知 短 矯 石 砂 研 砕 砲 破 硝 硫 硬 碁 碑 確 磁 磨 礁 礎
示 礼 社 祈 祉 祖 祚 祝 神 祥 票 祭 禁 禄 禅 禍 禍 禎 福 秀 私 秋 科 秒 秘
租 秩 称 移 程 税 稚 種 稲 稼 稿 穀 穂 積 穏 穫 穴 究 空 突 窃 窒 窓 窮 窯
立 竜 章 童 端 競 竹 笑 笛 符 第 筆 等 筋 筒 答 策 箇 算 管 箱 節 範 築 篤
簡 簿 籍 米 粉 粋 粒 粗 粘 粛 粧 精 糖 糧 糸 系 糾 紀 約 紅 紋 納 純 紙 紙
級 紛 素 素 紡 索 紫 累 細 紳 紹 紺 終 組 経 結 絞 絡 給 統 絵 絶 絹 継 続
維 綱 網 綿 緊 総 緑 緒 線 締 編 緩 緯 練 縁 縄 縛 縦 縫 縮 績 繁 繊 織 繕
繭 繰 缶 罪 置 罰 署 罷 羅 羊 美 群 義 羽 翁 翌 習 翻 翼 老 考 者 耐 耕 耗
耳 聖 聞 聴 職 肉 肌 肖 肝 肢 肥 肩 肪 肯 育 肺 胃 胆 背 胎 胞 胴 胸 能 脂
脅 脈 脚 脱 脳 脹 腐 腕 腰 腸 腹 膚 膜 膨 臓 臣 臨 自 臭 至 致 興 舌 舎 舗
舞 舟 航 般 舶 船 艇 艦 良 色 芋 芝 花 芳 芸 芽 苗 若 苦 英 茂 茎 茶 草 荒
荘 荷 菊 菌 菓 菜 華 落 葉 著 葬 蒸 蓄 蔵 薄 薦 薪 薪 薫 薬 藩 藻 虐 虚 虜
虞 虫 蚊 蚕 蛇 蛍 蛮 融 血 衆 行 術 街 衛 衝 衡 衣 表 衰 衷 袋 被 裁 裂 装
裏 裕 補 裸 製 複 褐 褒 襟 襲 西 要 覆 覇 見 規 視 覚 覧 親 観 角 解 触 言
訂 計 討 訓 託 記 訟 訪 設 許 訳 訴 診 証 詐 詔 評 詞 詠 試 詩 詰 詰 話 該
詳 誇 誉 誌 認 誓 誕 誘 語 誠 誤 説 読 課 調 談 請 論 諭 諮 諸 諾 謀 謁 謄
謙 講 謝 謡 謹 識 譜 警 議 譲 護 谷 豆 豊 豚 象 豪 貝 貞 負 負 財 貢 貧 貧
貨 販 貫 責 貯 貴 買 貸 費 貿 賀 賃 賄 資 賊 賓 賛 賜 賞 賠 賢 賦 質 購 贈
赤 赦 走 赴 起 超 越 趣 足 距 跡 路 跳 践 踊 踏 躍 身 車 軌 軍 軒 軟 転 軸
軽 較 載 輝 輩 輪 輸 轄 辛 辞 辱 農 辺 込 迅 迎 近 返 迫 迭 述 迷 追 退 送
逃 逆 透 逐 逓 途 通 逝 速 造 連 逮 週 進 逸 遂 遅 遇 遊 運 遍 過 道 道 達
違 遠 遣 適 遭 遮 遵 遷 選 遺 避 還 邦 邪 邸 郊 郎 郡 部 郭 郵 郷 都 酌 配
酒 酔 酢 酪 酬 酵 酷 酸 醜 醸 釈 里 里 重 野 量 金 針 釣 鈍 鈴 鉄 鉛 鉢 鉱
銀 銃 銅 銑 銘 銭 鋭 鋳 鋼 錘 錠 錬 錯 録 鍛 鎖 鎮 鏡 鐘 鑑 長 門 閉 開 閑
間 関 閣 閥 閲 闘 防 阻 附 降 限 陛 院 院 陣 除 陥 陪 陰 陳 陵 陶 陸 険 陽
隅 隆 隊 階 随 隔 際 障 隠 隣 隷 隻 雄 雄 雅 集 雇 雉 雌 雑 離 難 雨 雪 雰
雲 零 雷 電 需 震 霊 霜 霧 露 青 静 非 面 革 靴 韓 音 韻 響 頂 項 順 預 預
頑 頒 領 頭 頻 頼 題 額 顔 顕 願 類 顧 風 飛 食 飢 飯 飲 飼 飼 飽 飾 養 餓
館 首 香 馬 駄 駄 駅 駆 駐 騎 騒 験 騰 驚 骨 髄 高 髪 鬼 魂 魅 魔 魚 鮮 鯨
鳥 鳴 鶏 麗 麦 麻 黄 黒 黙 鼓 鼻 齢",
- 3: "兌 拼 楔 錄 鳯",
- 4: "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",
- },
- "jmc": {
- 0: "a b c d e f g h i j k l m n o p r s t u v w y z",
- 3: "q x",
- 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z",
- },
- "ka": {
- 0: "ა ბ გ დ ე ვ ზ ჱ თ ი კ ლ მ ნ ჲ ო პ ჟ რ ს ტ ჳ უ ფ ქ ღ ყ შ ჩ ც ძ წ ჭ ხ
ჴ ჯ ჰ ჵ ჶ ჷ ჸ ჹ ჺ",
- 3: "ⴀ ⴁ ⴂ ⴃ ⴄ ⴅ ⴆ ⴡ ⴇ ⴈ ⴉ ⴊ ⴋ ⴌ ⴢ ⴍ ⴎ ⴏ ⴐ ⴑ ⴒ ⴣ ⴓ ⴔ ⴕ ⴖ ⴗ ⴘ ⴙ ⴚ ⴛ ⴜ ⴝ ⴞ
ⴤ ⴟ ⴠ ⴥ",
- 4: "ა ბ გ დ ე ვ ზ თ ი კ ლ მ ნ ო პ ჟ რ ს ტ უ ფ ქ ღ ყ შ ჩ ც ძ წ ჭ ხ ჯ ჰ",
- 5: "ა ბ გ დ ე ვ ზ თ ი კ ლ მ ნ ო პ ჟ რ ს ტ უ ფ ქ ღ ყ შ ჩ ც ძ წ ჭ ხ ჯ ჰ",
- },
- "kab": {
- 0: "a b c č d ḍ e ɛ f g ǧ ɣ h ḥ i j k l m n p q r ṛ s ṣ t ṭ u w x y z ẓ",
- 3: "o v",
- 5: "A B C Č D Ḍ E Ɛ F G Ǧ Ɣ H Ḥ I J K L M N P Q R Ṛ S Ṣ T Ṭ U W X Y Z Ẓ",
- },
- "kam": {
- 0: "a b c d e f g h i ĩ j k l m n o p q r s t u ũ v w y z",
- 5: "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",
- },
- "kde": {
- 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",
- 5: "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",
- },
- "kea": {
- 0: "a b d dj e f g i j k l lh m n nh o p r s t tx u v x z",
- 3: "á à â ã c ç é ê h í ñ ó ô q ú w y",
- 5: "A B D E F G H I J K L M N O P R S T U V X Z",
- },
- "khq": {
- 0: "a ã b c d e ẽ f g h i j k l m n ɲ ŋ o õ p q r s š t u w x y z ž",
- 3: "v",
- 5: "A Ã B C D E Ẽ F G H I J K L M N Ɲ Ŋ O Õ P Q R S Š T U W X Y Z Ž",
- },
- "ki": {
- 0: "a b c d e g h i ĩ j k m n o r t u ũ w y",
- 3: "f l p q s v x z",
- 5: "A B C D E G H I J K M N O R T U W Y",
- },
- "kk": {
- 0: "а ә б в г ғ д е ё ж з и й к қ л м н ң о ө п р с т у ұ ү ф х һ ц ч ш
щ ъ ы і ь э ю я",
- 5: "А Ә Б В Г Ғ Д Е Ё Ж З И Й К Қ Л М Н Ң О Ө П Р С Т У Ұ Ү Ф Х Һ Ц Ч Ш
Щ Ъ Ы І Ь Э Ю Я",
- },
- "kl": {
- 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 æ ø å",
- },
- "kln": {
- 0: "a b c d e g h i j k l m n o p r s t u w y",
- 3: "f q v x z",
- 5: "A B C D E G H I J K L M N O P R S T U W Y",
- },
- "km": {
- 0: "៌ ៎ ៏ ៑ ័ ៈ ់ ៉ ៊ ៍ ក ខ គ ឃ ង ច ឆ ជ ឈ ញ ដ ឋ ឌ ឍ ណ ត ថ ទ ធ ន ប ផ ព ភ
ម យ រ ឫ ឬ ល ឭ ឮ វ ស ហ ឡ អ អា ឥ ឦ ឧ ឧក ឪ ឩ ឯ ឰ ឱ ឲ ឳ ា ិ ី ឹ ឺ ុ ូ ួ ើ ឿ ៀ េ
ែ ៃ ោ ៅ ំ ះ ្",
- 3: "\u17b4 \u17b5 \u200b ឝ ឞ",
- },
- "kn": {
- 0: "಼ ೦ ೧ ೨ ೩ ೪ ೫ ೬ ೭ ೮ ೯ ಅ ಆ ಇ ಈ ಉ ಊ ಋ ೠ ಌ ೡ ಎ ಏ ಐ ಒ ಓ ಔ ಂ ಃ ಕ ಖ ಗ ಘ ಙ
ಚ ಛ ಜ ಝ ಞ ಟ ಠ ಡ ಢ ಣ ತ ಥ ದ ಧ ನ ಪ ಫ ಬ ಭ ಮ ಯ ರ ಱ ಲ ವ ಶ ಷ ಸ ಹ ಳ ೞ ಽ ಾ ಿ ೀ ು ೂ ೃ
ೄ ೆ ೇ ೈ ೊ ೋ ೌ ್ ೕ ೖ",
- 4: "ರ ೂ",
- },
- "ko": {
- 0: "가 가 각 갂 갃 간 갅 갆 갇 갈 갉 갊 갋 갌 갍 갎 갏 감 갑 값 갓 갔 강
갖 갗 갘 같 갚 갛 개 객 갞 갟 갠 갡 갢 갣 갤 갥 갦 갧 갨 갩 갪 갫 갬 갭 갮
갯 갰 갱 갲 갳 갴 갵 갶 갷 갸 갹 갺 갻 갼 갽 갾 갿 걀 걁 걂 걃 걄 걅 걆 걇
걈 걉 걊 걋 걌 걍 걎 걏 걐 걑 걒 걓 걔 걕 걖 걗 걘 걙 걚 걛 걜 걝 걞 걟 걠
걡 걢 걣 걤 걥 걦 걧 걨 걩 걪 걫 걬 걭 걮 걯 거 걱 걲 걳 건 걵 걶 걷 걸 걹
걺 걻 걼 걽 걾 걿 검 겁 겂 것 겄 겅 겆 겇 겈 겉 겊 겋 게 겍 겎 겏 겐 겑 겒
겓 겔 겕 겖 겗 겘 겙 겚 겛 겜 겝 겞 겟 겠 겡 겢 겣 겤 겥 겦 겧 겨 격 겪 겫
견 겭 겮 겯 결 겱 겲 겳 겴 겵 겶 겷 겸 겹 겺 겻 겼 경 겾 겿 곀 곁 곂 곃 계
곅 곆 곇 곈 곉 곊 곋 곌 곍 곎 곏 곐 곑 곒 곓 곔 곕 곖 곗 곘 곙 곚 곛 곜 곝
곞 곟 고 곡 곢 곣 곤 곥 곦 곧 골 곩 곪 곫 곬 곭 곮 곯 곰 곱 곲 곳 곴 공 곶
곷 곸 곹 곺 곻 과 곽 곾 곿 관 괁 괂 괃 괄 괅 괆 괇 괈 괉 괊 괋 괌 괍 괎 괏
괐 광 괒 괓 괔 괕 괖 괗 괘 괙 괚 괛 괜 괝 괞 괟 괠 괡 괢 괣 괤 괥 괦 괧 괨
괩 괪 괫 괬 괭 괮 괯 괰 괱 괲 괳 괴 괵 괶 괷 괸 괹 괺 괻 괼 괽 괾 괿 굀 굁
굂 굃 굄 굅 굆 굇 굈 굉 굊 굋 굌 굍 굎 굏 교 굑 굒 굓 굔 굕 굖 굗 굘 굙 굚
굛 굜 굝 굞 굟 굠 굡 굢 굣 굤 굥 굦 굧 굨 굩 굪 굫 구 국 굮 굯 군 굱 굲 굳
굴 굵 굶 굷 굸 굹 굺 굻 굼 굽 굾 굿 궀 궁 궂 궃 궄 궅 궆 궇 궈 궉 궊 궋 권
궍 궎 궏 궐 궑 궒 궓 궔 궕 궖 궗 궘 궙 궚 궛 궜 궝 궞 궟 궠 궡 궢 궣 궤 궥
궦 궧 궨 궩 궪 궫 궬 궭 궮 궯 궰 궱 궲 궳 궴 궵 궶 궷 궸 궹 궺 궻 궼 궽 궾
궿 귀 귁 귂 귃 귄 귅 귆 귇 귈 귉 귊 귋 귌 귍 귎 귏 귐 귑 귒 귓 귔 귕 귖 귗
귘 귙 귚 귛 규 귝 귞 귟 균 귡 귢 귣 귤 귥 귦 귧 귨 귩 귪 귫 귬 귭 귮 귯 귰
귱 귲 귳 귴 귵 귶 귷 그 극 귺 귻 근 귽 귾 귿 글 긁 긂 긃 긄 긅 긆 긇 금 급
긊 긋 긌 긍 긎 긏 긐 긑 긒 긓 긔 긕 긖 긗 긘 긙 긚 긛 긜 긝 긞 긟 긠 긡 긢
긣 긤 긥 긦 긧 긨 긩 긪 긫 긬 긭 긮 긯 기 긱 긲 긳 긴 긵 긶 긷 길 긹 긺 긻
긼 긽 긾 긿 김 깁 깂 깃 깄 깅 깆 깇 깈 깉 깊 깋 까 깍 깎 깏 깐 깑 깒 깓 깔
깕 깖 깗 깘 깙 깚 깛 깜 깝 깞 깟 깠 깡 깢 깣 깤 깥 깦 깧 깨 깩 깪 깫 깬 깭
깮 깯 깰 깱 깲 깳 깴 깵 깶 깷 깸 깹 깺 깻 깼 깽 깾 깿 꺀 꺁 꺂 꺃 꺄 꺅 꺆
꺇 꺈 꺉 꺊 꺋 꺌 꺍 꺎 꺏 꺐 꺑 꺒 꺓 꺔 꺕 꺖 꺗 꺘 꺙 꺚 꺛 꺜 꺝 꺞 꺟
꺠 꺡 꺢 꺣 꺤 꺥 꺦 꺧 꺨 꺩 꺪 꺫 꺬 꺭 꺮 꺯 꺰 꺱 꺲 꺳 꺴 꺵 꺶 꺷 꺸
꺹 꺺 꺻 꺼 꺽 꺾 꺿 껀 껁 껂 껃 껄 껅 껆 껇 껈 껉 껊 껋 껌 껍 껎 껏 껐 껑
껒 껓 껔 껕 껖 껗 께 껙 껚 껛 껜 껝 껞 껟 껠 껡 껢 껣 껤 껥 껦 껧 껨 껩 껪
껫 껬 껭 껮 껯 껰 껱 껲 껳 껴 껵 껶 껷 껸 껹 껺 껻 껼 껽 껾 껿 꼀 꼁 꼂 꼃
꼄 꼅 꼆 꼇 꼈 꼉 꼊 꼋 꼌 꼍 꼎 꼏 꼐 꼑 꼒 꼓 꼔 꼕 꼖 꼗 꼘 꼙 꼚 꼛 꼜
꼝 꼞 꼟 꼠 꼡 꼢 꼣 꼤 꼥 꼦 꼧 꼨 꼩 꼪 꼫 꼬 꼭 꼮 꼯 꼰 꼱 꼲 꼳 꼴 꼵
꼶 꼷 꼸 꼹 꼺 꼻 꼼 꼽 꼾 꼿 꽀 꽁 꽂 꽃 꽄 꽅 꽆 꽇 꽈 꽉 꽊 꽋 꽌 꽍 꽎
꽏 꽐 꽑 꽒 꽓 꽔 꽕 꽖 꽗 꽘 꽙 꽚 꽛 꽜 꽝 꽞 꽟 꽠 꽡 꽢 꽣 꽤 꽥 꽦 꽧
꽨 꽩 꽪 꽫 꽬 꽭 꽮 꽯 꽰 꽱 꽲 꽳 꽴 꽵 꽶 꽷 꽸 꽹 꽺 꽻 꽼 꽽 꽾 꽿 꾀
꾁 꾂 꾃 꾄 꾅 꾆 꾇 꾈 꾉 꾊 꾋 꾌 꾍 꾎 꾏 꾐 꾑 꾒 꾓 꾔 꾕 꾖 꾗 꾘 꾙
꾚 꾛 꾜 꾝 꾞 꾟 꾠 꾡 꾢 꾣 꾤 꾥 꾦 꾧 꾨 꾩 꾪 꾫 꾬 꾭 꾮 꾯 꾰 꾱 꾲
꾳 꾴 꾵 꾶 꾷 꾸 꾹 꾺 꾻 꾼 꾽 꾾 꾿 꿀 꿁 꿂 꿃 꿄 꿅 꿆 꿇 꿈 꿉 꿊 꿋
꿌 꿍 꿎 꿏 꿐 꿑 꿒 꿓 꿔 꿕 꿖 꿗 꿘 꿙 꿚 꿛 꿜 꿝 꿞 꿟 꿠 꿡 꿢 꿣 꿤
꿥 꿦 꿧 꿨 꿩 꿪 꿫 꿬 꿭 꿮 꿯 꿰 꿱 꿲 꿳 꿴 꿵 꿶 꿷 꿸 꿹 꿺 꿻 꿼 꿽
꿾 꿿 뀀 뀁 뀂 뀃 뀄 뀅 뀆 뀇 뀈 뀉 뀊 뀋 뀌 뀍 뀎 뀏 뀐 뀑 뀒 뀓 뀔 뀕 뀖
뀗 뀘 뀙 뀚 뀛 뀜 뀝 뀞 뀟 뀠 뀡 뀢 뀣 뀤 뀥 뀦 뀧 뀨 뀩 뀪 뀫 뀬 뀭 뀮 뀯
뀰 뀱 뀲 뀳 뀴 뀵 뀶 뀷 뀸 뀹 뀺 뀻 뀼 뀽 뀾 뀿 끀 끁 끂 끃 끄 끅 끆 끇 끈
끉 끊 끋 끌 끍 끎 끏 끐 끑 끒 끓 끔 끕 끖 끗 끘 끙 끚 끛 끜 끝 끞 끟 끠 끡
끢 끣 끤 끥 끦 끧 끨 끩 끪 끫 끬 끭 끮 끯 끰 끱 끲 끳 끴 끵 끶 끷 끸 끹 끺
끻 끼 끽 끾 끿 낀 낁 낂 낃 낄 낅 낆 낇 낈 낉 낊 낋 낌 낍 낎 낏 낐 낑 낒 낓
낔 낕 낖 낗 나 낙 낚 낛 난 낝 낞 낟 날 낡 낢 낣 낤 낥 낦 낧 남 납 낪 낫 났
낭 낮 낯 낰 낱 낲 낳 내 낵 낶 낷 낸 낹 낺 낻 낼 낽 낾 낿 냀 냁 냂 냃 냄 냅
냆 냇 냈 냉 냊 냋 냌 냍 냎 냏 냐 냑 냒 냓 냔 냕 냖 냗 냘 냙 냚 냛 냜 냝 냞
냟 냠 냡 냢 냣 냤 냥 냦 냧 냨 냩 냪 냫 냬 냭 냮 냯 냰 냱 냲 냳 냴 냵 냶 냷
냸 냹 냺 냻 냼 냽 냾 냿 넀 넁 넂 넃 넄 넅 넆 넇 너 넉 넊 넋 넌 넍 넎 넏 널
넑 넒 넓 넔 넕 넖 넗 넘 넙 넚 넛 넜 넝 넞 넟 넠 넡 넢 넣 네 넥 넦 넧 넨 넩
넪 넫 넬 넭 넮 넯 넰 넱 넲 넳 넴 넵 넶 넷 넸 넹 넺 넻 넼 넽 넾 넿 녀 녁 녂
녃 년 녅 녆 녇 녈 녉 녊 녋 녌 녍 녎 녏 념 녑 녒 녓 녔 녕 녖 녗 녘 녙 녚 녛
녜 녝 녞 녟 녠 녡 녢 녣 녤 녥 녦 녧 녨 녩 녪 녫 녬 녭 녮 녯 녰 녱 녲 녳 녴
녵 녶 녷 노 녹 녺 녻 논 녽 녾 녿 놀 놁 놂 놃 놄 놅 놆 놇 놈 놉 놊 놋 놌 농
놎 놏 놐 놑 높 놓 놔 놕 놖 놗 놘 놙 놚 놛 놜 놝 놞 놟 놠 놡 놢 놣 놤 놥 놦
놧 놨 놩 놪 놫 놬 놭 놮 놯 놰 놱 놲 놳 놴 놵 놶 놷 놸 놹 놺 놻 놼 놽 놾 놿
뇀 뇁 뇂 뇃 뇄 뇅 뇆 뇇 뇈 뇉 뇊 뇋 뇌 뇍 뇎 뇏 뇐 뇑 뇒 뇓 뇔 뇕 뇖 뇗 뇘
뇙 뇚 뇛 뇜 뇝 뇞 뇟 뇠 뇡 뇢 뇣 뇤 뇥 뇦 뇧 뇨 뇩 뇪 뇫 뇬 뇭 뇮 뇯 뇰 뇱
뇲 뇳 뇴 뇵 뇶 뇷 뇸 뇹 뇺 뇻 뇼 뇽 뇾 뇿 눀 눁 눂 눃 누 눅 눆 눇 눈 눉 눊
눋 눌 눍 눎 눏 눐 눑 눒 눓 눔 눕 눖 눗 눘 눙 눚 눛 눜 눝 눞 눟 눠 눡 눢 눣
눤 눥 눦 눧 눨 눩 눪 눫 눬 눭 눮 눯 눰 눱 눲 눳 눴 눵 눶 눷 눸 눹 눺 눻 눼
눽 눾 눿 뉀 뉁 뉂 뉃 뉄 뉅 뉆 뉇 뉈 뉉 뉊 뉋 뉌 뉍 뉎 뉏 뉐 뉑 뉒 뉓 뉔 뉕
뉖 뉗 뉘 뉙 뉚 뉛 뉜 뉝 뉞 뉟 뉠 뉡 뉢 뉣 뉤 뉥 뉦 뉧 뉨 뉩 뉪 뉫 뉬 뉭 뉮
뉯 뉰 뉱 뉲 뉳 뉴 뉵 뉶 뉷 뉸 뉹 뉺 뉻 뉼 뉽 뉾 뉿 늀 늁 늂 늃 늄 늅 늆 늇
늈 늉 늊 늋 늌 늍 늎 늏 느 늑 늒 늓 는 늕 늖 늗 늘 늙 늚 늛 늜 늝 늞 늟 늠
늡 늢 늣 늤 능 늦 늧 늨 늩 늪 늫 늬 늭 늮 늯 늰 늱 늲 늳 늴 늵 늶 늷 늸 늹
늺 늻 늼 늽 늾 늿 닀 닁 닂 닃 닄 닅 닆 닇 니 닉 닊 닋 닌 닍 닎 닏 닐 닑 닒
닓 닔 닕 닖 닗 님 닙 닚 닛 닜 닝 닞 닟 닠 닡 닢 닣 다 닥 닦 닧 단 닩 닪 닫
달 닭 닮 닯 닰 닱 닲 닳 담 답 닶 닷 닸 당 닺 닻 닼 닽 닾 닿 대 댁 댂 댃 댄
댅 댆 댇 댈 댉 댊 댋 댌 댍 댎 댏 댐 댑 댒 댓 댔 댕 댖 댗 댘 댙 댚 댛 댜 댝
댞 댟 댠 댡 댢 댣 댤 댥 댦 댧 댨 댩 댪 댫 댬 댭 댮 댯 댰 댱 댲 댳 댴 댵 댶
댷 댸 댹 댺 댻 댼 댽 댾 댿 덀 덁 덂 덃 덄 덅 덆 덇 덈 덉 덊 덋 덌 덍 덎 덏
덐 덑 덒 덓 더 덕 덖 덗 던 덙 덚 덛 덜 덝 덞 덟 덠 덡 덢 덣 덤 덥 덦 덧 덨
덩 덪 덫 덬 덭 덮 덯 데 덱 덲 덳 덴 덵 덶 덷 델 덹 덺 덻 덼 덽 덾 덿 뎀 뎁
뎂 뎃 뎄 뎅 뎆 뎇 뎈 뎉 뎊 뎋 뎌 뎍 뎎 뎏 뎐 뎑 뎒 뎓 뎔 뎕 뎖 뎗 뎘 뎙 뎚
뎛 뎜 뎝 뎞 뎟 뎠 뎡 뎢 뎣 뎤 뎥 뎦 뎧 뎨 뎩 뎪 뎫 뎬 뎭 뎮 뎯 뎰 뎱 뎲 뎳
뎴 뎵 뎶 뎷 뎸 뎹 뎺 뎻 뎼 뎽 뎾 뎿 돀 돁 돂 돃 도 독 돆 돇 돈 돉 돊 돋 돌
돍 돎 돏 돐 돑 돒 돓 돔 돕 돖 돗 돘 동 돚 돛 돜 돝 돞 돟 돠 돡 돢 돣 돤 돥
돦 돧 돨 돩 돪 돫 돬 돭 돮 돯 돰 돱 돲 돳 돴 돵 돶 돷 돸 돹 돺 돻 돼 돽 돾
돿 됀 됁 됂 됃 됄 됅 됆 됇 됈 됉 됊 됋 됌 됍 됎 됏 됐 됑 됒 됓 됔 됕 됖 됗
되 됙 됚 됛 된 됝 됞 됟 될 됡 됢 됣 됤 됥 됦 됧 됨 됩 됪 됫 됬 됭 됮 됯 됰
됱 됲 됳 됴 됵 됶 됷 됸 됹 됺 됻 됼 됽 됾 됿 둀 둁 둂 둃 둄 둅 둆 둇 둈 둉
둊 둋 둌 둍 둎 둏 두 둑 둒 둓 둔 둕 둖 둗 둘 둙 둚 둛 둜 둝 둞 둟 둠 둡 둢
둣 둤 둥 둦 둧 둨 둩 둪 둫 둬 둭 둮 둯 둰 둱 둲 둳 둴 둵 둶 둷 둸 둹 둺 둻
둼 둽 둾 둿 뒀 뒁 뒂 뒃 뒄 뒅 뒆 뒇 뒈 뒉 뒊 뒋 뒌 뒍 뒎 뒏 뒐 뒑 뒒 뒓 뒔
뒕 뒖 뒗 뒘 뒙 뒚 뒛 뒜 뒝 뒞 뒟 뒠 뒡 뒢 뒣 뒤 뒥 뒦 뒧 뒨 뒩 뒪 뒫 뒬 뒭
뒮 뒯 뒰 뒱 뒲 뒳 뒴 뒵 뒶 뒷 뒸 뒹 뒺 뒻 뒼 뒽 뒾 뒿 듀 듁 듂 듃 듄 듅 듆
듇 듈 듉 듊 듋 듌 듍 듎 듏 듐 듑 듒 듓 듔 듕 듖 듗 듘 듙 듚 듛 드 득 듞 듟
든 듡 듢 듣 들 듥 듦 듧 듨 듩 듪 듫 듬 듭 듮 듯 듰 등 듲 듳 듴 듵 듶 듷 듸
듹 듺 듻 듼 듽 듾 듿 딀 딁 딂 딃 딄 딅 딆 딇 딈 딉 딊 딋 딌 딍 딎 딏 딐 딑
딒 딓 디 딕 딖 딗 딘 딙 딚 딛 딜 딝 딞 딟 딠 딡 딢 딣 딤 딥 딦 딧 딨 딩 딪
딫 딬 딭 딮 딯 따 딱 딲 딳 딴 딵 딶 딷 딸 딹 딺 딻 딼 딽 딾 딿 땀 땁 땂 땃
땄 땅 땆 땇 땈 땉 땊 땋 때 땍 땎 땏 땐 땑 땒 땓 땔 땕 땖 땗 땘 땙 땚 땛 땜
땝 땞 땟 땠 땡 땢 땣 땤 땥 땦 땧 땨 땩 땪 땫 땬 땭 땮 땯 땰 땱 땲 땳 땴 땵
땶 땷 땸 땹 땺 땻 땼 땽 땾 땿 떀 떁 떂 떃 떄 떅 떆 떇 떈 떉 떊 떋 떌 떍 떎
떏 떐 떑 떒 떓 떔 떕 떖 떗 떘 떙 떚 떛 떜 떝 떞 떟 떠 떡 떢 떣 떤 떥 떦 떧
떨 떩 떪 떫 떬 떭 떮 떯 떰 떱 떲 떳 떴 떵 떶 떷 떸 떹 떺 떻 떼 떽 떾 떿 뗀
뗁 뗂 뗃 뗄 뗅 뗆 뗇 뗈 뗉 뗊 뗋 뗌 뗍 뗎 뗏 뗐 뗑 뗒 뗓 뗔 뗕 뗖 뗗 뗘 뗙
뗚 뗛 뗜 뗝 뗞 뗟 뗠 뗡 뗢 뗣 뗤 뗥 뗦 뗧 뗨 뗩 뗪 뗫 뗬 뗭 뗮 뗯 뗰 뗱 뗲
뗳 뗴 뗵 뗶 뗷 뗸 뗹 뗺 뗻 뗼 뗽 뗾 뗿 똀 똁 똂 똃 똄 똅 똆 똇 똈 똉 똊 똋
똌 똍 똎 똏 또 똑 똒 똓 똔 똕 똖 똗 똘 똙 똚 똛 똜 똝 똞 똟 똠 똡 똢 똣 똤
똥 똦 똧 똨 똩 똪 똫 똬 똭 똮 똯 똰 똱 똲 똳 똴 똵 똶 똷 똸 똹 똺 똻 똼 똽
똾 똿 뙀 뙁 뙂 뙃 뙄 뙅 뙆 뙇 뙈 뙉 뙊 뙋 뙌 뙍 뙎 뙏 뙐 뙑 뙒 뙓 뙔 뙕 뙖
뙗 뙘 뙙 뙚 뙛 뙜 뙝 뙞 뙟 뙠 뙡 뙢 뙣 뙤 뙥 뙦 뙧 뙨 뙩 뙪 뙫 뙬 뙭 뙮 뙯
뙰 뙱 뙲 뙳 뙴 뙵 뙶 뙷 뙸 뙹 뙺 뙻 뙼 뙽 뙾 뙿 뚀 뚁 뚂 뚃 뚄 뚅 뚆 뚇 뚈
뚉 뚊 뚋 뚌 뚍 뚎 뚏 뚐 뚑 뚒 뚓 뚔 뚕 뚖 뚗 뚘 뚙 뚚 뚛 뚜 뚝 뚞 뚟 뚠 뚡
뚢 뚣 뚤 뚥 뚦 뚧 뚨 뚩 뚪 뚫 뚬 뚭 뚮 뚯 뚰 뚱 뚲 뚳 뚴 뚵 뚶 뚷 뚸 뚹 뚺
뚻 뚼 뚽 뚾 뚿 뛀 뛁 뛂 뛃 뛄 뛅 뛆 뛇 뛈 뛉 뛊 뛋 뛌 뛍 뛎 뛏 뛐 뛑 뛒 뛓
뛔 뛕 뛖 뛗 뛘 뛙 뛚 뛛 뛜 뛝 뛞 뛟 뛠 뛡 뛢 뛣 뛤 뛥 뛦 뛧 뛨 뛩 뛪 뛫 뛬
뛭 뛮 뛯 뛰 뛱 뛲 뛳 뛴 뛵 뛶 뛷 뛸 뛹 뛺 뛻 뛼 뛽 뛾 뛿 뜀 뜁 뜂 뜃 뜄 뜅
뜆 뜇 뜈 뜉 뜊 뜋 뜌 뜍 뜎 뜏 뜐 뜑 뜒 뜓 뜔 뜕 뜖 뜗 뜘 뜙 뜚 뜛 뜜 뜝 뜞
뜟 뜠 뜡 뜢 뜣 뜤 뜥 뜦 뜧 뜨 뜩 뜪 뜫 뜬 뜭 뜮 뜯 뜰 뜱 뜲 뜳 뜴 뜵 뜶 뜷
뜸 뜹 뜺 뜻 뜼 뜽 뜾 뜿 띀 띁 띂 띃 띄 띅 띆 띇 띈 띉 띊 띋 띌 띍 띎 띏 띐
띑 띒 띓 띔 띕 띖 띗 띘 띙 띚 띛 띜 띝 띞 띟 띠 띡 띢 띣 띤 띥 띦 띧 띨 띩
띪 띫 띬 띭 띮 띯 띰 띱 띲 띳 띴 띵 띶 띷 띸 띹 띺 띻 라 락 띾 띿 란 랁 랂
랃 랄 랅 랆 랇 랈 랉 랊 랋 람 랍 랎 랏 랐 랑 랒 랓 랔 랕 랖 랗 래 랙 랚 랛
랜 랝 랞 랟 랠 랡 랢 랣 랤 랥 랦 랧 램 랩 랪 랫 랬 랭 랮 랯 랰 랱 랲 랳 랴
략 랶 랷 랸 랹 랺 랻 랼 랽 랾 랿 럀 럁 럂 럃 럄 럅 럆 럇 럈 량 럊 럋 럌 럍
럎 럏 럐 럑 럒 럓 럔 럕 럖 럗 럘 럙 럚 럛 럜 럝 럞 럟 럠 럡 럢 럣 럤 럥 럦
럧 럨 럩 럪 럫 러 럭 럮 럯 런 럱 럲 럳 럴 럵 럶 럷 럸 럹 럺 럻 럼 럽 럾 럿
렀 렁 렂 렃 렄 렅 렆 렇 레 렉 렊 렋 렌 렍 렎 렏 렐 렑 렒 렓 렔 렕 렖 렗 렘
렙 렚 렛 렜 렝 렞 렟 렠 렡 렢 렣 려 력 렦 렧 련 렩 렪 렫 렬 렭 렮 렯 렰 렱
렲 렳 렴 렵 렶 렷 렸 령 렺 렻 렼 렽 렾 렿 례 롁 롂 롃 롄 롅 롆 롇 롈 롉 롊
롋 롌 롍 롎 롏 롐 롑 롒 롓 롔 롕 롖 롗 롘 롙 롚 롛 로 록 롞 롟 론 롡 롢 롣
롤 롥 롦 롧 롨 롩 롪 롫 롬 롭 롮 롯 롰 롱 롲 롳 롴 롵 롶 롷 롸 롹 롺 롻 롼
롽 롾 롿 뢀 뢁 뢂 뢃 뢄 뢅 뢆 뢇 뢈 뢉 뢊 뢋 뢌 뢍 뢎 뢏 뢐 뢑 뢒 뢓 뢔 뢕
뢖 뢗 뢘 뢙 뢚 뢛 뢜 뢝 뢞 뢟 뢠 뢡 뢢 뢣 뢤 뢥 뢦 뢧 뢨 뢩 뢪 뢫 뢬 뢭 뢮
뢯 뢰 뢱 뢲 뢳 뢴 뢵 뢶 뢷 뢸 뢹 뢺 뢻 뢼 뢽 뢾 뢿 룀 룁 룂 룃 룄 룅 룆 룇
룈 룉 룊 룋 료 룍 룎 룏 룐 룑 룒 룓 룔 룕 룖 룗 룘 룙 룚 룛 룜 룝 룞 룟 룠
룡 룢 룣 룤 룥 룦 룧 루 룩 룪 룫 룬 룭 룮 룯 룰 룱 룲 룳 룴 룵 룶 룷 룸 룹
룺 룻 룼 룽 룾 룿 뤀 뤁 뤂 뤃 뤄 뤅 뤆 뤇 뤈 뤉 뤊 뤋 뤌 뤍 뤎 뤏 뤐 뤑 뤒
뤓 뤔 뤕 뤖 뤗 뤘 뤙 뤚 뤛 뤜 뤝 뤞 뤟 뤠 뤡 뤢 뤣 뤤 뤥 뤦 뤧 뤨 뤩 뤪 뤫
뤬 뤭 뤮 뤯 뤰 뤱 뤲 뤳 뤴 뤵 뤶 뤷 뤸 뤹 뤺 뤻 뤼 뤽 뤾 뤿 륀 륁 륂 륃 륄
륅 륆 륇 륈 륉 륊 륋 륌 륍 륎 륏 륐 륑 륒 륓 륔 륕 륖 륗 류 륙 륚 륛 륜 륝
륞 륟 률 륡 륢 륣 륤 륥 륦 륧 륨 륩 륪 륫 륬 륭 륮 륯 륰 륱 륲 륳 르 륵 륶
륷 른 륹 륺 륻 를 륽 륾 륿 릀 릁 릂 릃 름 릅 릆 릇 릈 릉 릊 릋 릌 릍 릎 릏
릐 릑 릒 릓 릔 릕 릖 릗 릘 릙 릚 릛 릜 릝 릞 릟 릠 릡 릢 릣 릤 릥 릦 릧 릨
릩 릪 릫 리 릭 릮 릯 린 릱 릲 릳 릴 릵 릶 릷 릸 릹 릺 릻 림 립 릾 릿 맀 링
맂 맃 맄 맅 맆 맇 마 막 맊 맋 만 맍 많 맏 말 맑 맒 맓 맔 맕 맖 맗 맘 맙 맚
맛 맜 망 맞 맟 맠 맡 맢 맣 매 맥 맦 맧 맨 맩 맪 맫 맬 맭 맮 맯 맰 맱 맲 맳
맴 맵 맶 맷 맸 맹 맺 맻 맼 맽 맾 맿 먀 먁 먂 먃 먄 먅 먆 먇 먈 먉 먊 먋 먌
먍 먎 먏 먐 먑 먒 먓 먔 먕 먖 먗 먘 먙 먚 먛 먜 먝 먞 먟 먠 먡 먢 먣 먤 먥
먦 먧 먨 먩 먪 먫 먬 먭 먮 먯 먰 먱 먲 먳 먴 먵 먶 먷 머 먹 먺 먻 먼 먽 먾
먿 멀 멁 멂 멃 멄 멅 멆 멇 멈 멉 멊 멋 멌 멍 멎 멏 멐 멑 멒 멓 메 멕 멖 멗
멘 멙 멚 멛 멜 멝 멞 멟 멠 멡 멢 멣 멤 멥 멦 멧 멨 멩 멪 멫 멬 멭 멮 멯 며
멱 멲 멳 면 멵 멶 멷 멸 멹 멺 멻 멼 멽 멾 멿 몀 몁 몂 몃 몄 명 몆 몇 몈 몉
몊 몋 몌 몍 몎 몏 몐 몑 몒 몓 몔 몕 몖 몗 몘 몙 몚 몛 몜 몝 몞 몟 몠 몡 몢
몣 몤 몥 몦 몧 모 목 몪 몫 몬 몭 몮 몯 몰 몱 몲 몳 몴 몵 몶 몷 몸 몹 몺 못
몼 몽 몾 몿 뫀 뫁 뫂 뫃 뫄 뫅 뫆 뫇 뫈 뫉 뫊 뫋 뫌 뫍 뫎 뫏 뫐 뫑 뫒 뫓 뫔
뫕 뫖 뫗 뫘 뫙 뫚 뫛 뫜 뫝 뫞 뫟 뫠 뫡 뫢 뫣 뫤 뫥 뫦 뫧 뫨 뫩 뫪 뫫 뫬 뫭
뫮 뫯 뫰 뫱 뫲 뫳 뫴 뫵 뫶 뫷 뫸 뫹 뫺 뫻 뫼 뫽 뫾 뫿 묀 묁 묂 묃 묄 묅 묆
묇 묈 묉 묊 묋 묌 묍 묎 묏 묐 묑 묒 묓 묔 묕 묖 묗 묘 묙 묚 묛 묜 묝 묞 묟
묠 묡 묢 묣 묤 묥 묦 묧 묨 묩 묪 묫 묬 묭 묮 묯 묰 묱 묲 묳 무 묵 묶 묷 문
묹 묺 묻 물 묽 묾 묿 뭀 뭁 뭂 뭃 뭄 뭅 뭆 뭇 뭈 뭉 뭊 뭋 뭌 뭍 뭎 뭏 뭐 뭑
뭒 뭓 뭔 뭕 뭖 뭗 뭘 뭙 뭚 뭛 뭜 뭝 뭞 뭟 뭠 뭡 뭢 뭣 뭤 뭥 뭦 뭧 뭨 뭩 뭪
뭫 뭬 뭭 뭮 뭯 뭰 뭱 뭲 뭳 뭴 뭵 뭶 뭷 뭸 뭹 뭺 뭻 뭼 뭽 뭾 뭿 뮀 뮁 뮂 뮃
뮄 뮅 뮆 뮇 뮈 뮉 뮊 뮋 뮌 뮍 뮎 뮏 뮐 뮑 뮒 뮓 뮔 뮕 뮖 뮗 뮘 뮙 뮚 뮛 뮜
뮝 뮞 뮟 뮠 뮡 뮢 뮣 뮤 뮥 뮦 뮧 뮨 뮩 뮪 뮫 뮬 뮭 뮮 뮯 뮰 뮱 뮲 뮳 뮴 뮵
뮶 뮷 뮸 뮹 뮺 뮻 뮼 뮽 뮾 뮿 므 믁 믂 믃 믄 믅 믆 믇 믈 믉 믊 믋 믌 믍 믎
믏 믐 믑 믒 믓 믔 믕 믖 믗 믘 믙 믚 믛 믜 믝 믞 믟 믠 믡 믢 믣 믤 믥 믦 믧
믨 믩 믪 믫 믬 믭 믮 믯 믰 믱 믲 믳 믴 믵 믶 믷 미 믹 믺 믻 민 믽 믾 믿 밀
밁 밂 밃 밄 밅 밆 밇 밈 밉 밊 밋 밌 밍 밎 및 밐 밑 밒 밓 바 박 밖 밗 반 밙
밚 받 발 밝 밞 밟 밠 밡 밢 밣 밤 밥 밦 밧 밨 방 밪 밫 밬 밭 밮 밯 배 백 밲
밳 밴 밵 밶 밷 밸 밹 밺 밻 밼 밽 밾 밿 뱀 뱁 뱂 뱃 뱄 뱅 뱆 뱇 뱈 뱉 뱊 뱋
뱌 뱍 뱎 뱏 뱐 뱑 뱒 뱓 뱔 뱕 뱖 뱗 뱘 뱙 뱚 뱛 뱜 뱝 뱞 뱟 뱠 뱡 뱢 뱣 뱤
뱥 뱦 뱧 뱨 뱩 뱪 뱫 뱬 뱭 뱮 뱯 뱰 뱱 뱲 뱳 뱴 뱵 뱶 뱷 뱸 뱹 뱺 뱻 뱼 뱽
뱾 뱿 벀 벁 벂 벃 버 벅 벆 벇 번 벉 벊 벋 벌 벍 벎 벏 벐 벑 벒 벓 범 법 벖
벗 벘 벙 벚 벛 벜 벝 벞 벟 베 벡 벢 벣 벤 벥 벦 벧 벨 벩 벪 벫 벬 벭 벮 벯
벰 벱 벲 벳 벴 벵 벶 벷 벸 벹 벺 벻 벼 벽 벾 벿 변 볁 볂 볃 별 볅 볆 볇 볈
볉 볊 볋 볌 볍 볎 볏 볐 병 볒 볓 볔 볕 볖 볗 볘 볙 볚 볛 볜 볝 볞 볟 볠 볡
볢 볣 볤 볥 볦 볧 볨 볩 볪 볫 볬 볭 볮 볯 볰 볱 볲 볳 보 복 볶 볷 본 볹 볺
볻 볼 볽 볾 볿 봀 봁 봂 봃 봄 봅 봆 봇 봈 봉 봊 봋 봌 봍 봎 봏 봐 봑 봒 봓
봔 봕 봖 봗 봘 봙 봚 봛 봜 봝 봞 봟 봠 봡 봢 봣 봤 봥 봦 봧 봨 봩 봪 봫 봬
봭 봮 봯 봰 봱 봲 봳 봴 봵 봶 봷 봸 봹 봺 봻 봼 봽 봾 봿 뵀 뵁 뵂 뵃 뵄 뵅
뵆 뵇 뵈 뵉 뵊 뵋 뵌 뵍 뵎 뵏 뵐 뵑 뵒 뵓 뵔 뵕 뵖 뵗 뵘 뵙 뵚 뵛 뵜 뵝 뵞
뵟 뵠 뵡 뵢 뵣 뵤 뵥 뵦 뵧 뵨 뵩 뵪 뵫 뵬 뵭 뵮 뵯 뵰 뵱 뵲 뵳 뵴 뵵 뵶 뵷
뵸 뵹 뵺 뵻 뵼 뵽 뵾 뵿 부 북 붂 붃 분 붅 붆 붇 불 붉 붊 붋 붌 붍 붎 붏 붐
붑 붒 붓 붔 붕 붖 붗 붘 붙 붚 붛 붜 붝 붞 붟 붠 붡 붢 붣 붤 붥 붦 붧 붨 붩
붪 붫 붬 붭 붮 붯 붰 붱 붲 붳 붴 붵 붶 붷 붸 붹 붺 붻 붼 붽 붾 붿 뷀 뷁 뷂
뷃 뷄 뷅 뷆 뷇 뷈 뷉 뷊 뷋 뷌 뷍 뷎 뷏 뷐 뷑 뷒 뷓 뷔 뷕 뷖 뷗 뷘 뷙 뷚 뷛
뷜 뷝 뷞 뷟 뷠 뷡 뷢 뷣 뷤 뷥 뷦 뷧 뷨 뷩 뷪 뷫 뷬 뷭 뷮 뷯 뷰 뷱 뷲 뷳 뷴
뷵 뷶 뷷 뷸 뷹 뷺 뷻 뷼 뷽 뷾 뷿 븀 븁 븂 븃 븄 븅 븆 븇 븈 븉 븊 븋 브 븍
븎 븏 븐 븑 븒 븓 블 븕 븖 븗 븘 븙 븚 븛 븜 븝 븞 븟 븠 븡 븢 븣 븤 븥 븦
븧 븨 븩 븪 븫 븬 븭 븮 븯 븰 븱 븲 븳 븴 븵 븶 븷 븸 븹 븺 븻 븼 븽 븾 븿
빀 빁 빂 빃 비 빅 빆 빇 빈 빉 빊 빋 빌 빍 빎 빏 빐 빑 빒 빓 빔 빕 빖 빗 빘
빙 빚 빛 빜 빝 빞 빟 빠 빡 빢 빣 빤 빥 빦 빧 빨 빩 빪 빫 빬 빭 빮 빯 빰 빱
빲 빳 빴 빵 빶 빷 빸 빹 빺 빻 빼 빽 빾 빿 뺀 뺁 뺂 뺃 뺄 뺅 뺆 뺇 뺈 뺉 뺊
뺋 뺌 뺍 뺎 뺏 뺐 뺑 뺒 뺓 뺔 뺕 뺖 뺗 뺘 뺙 뺚 뺛 뺜 뺝 뺞 뺟 뺠 뺡 뺢 뺣
뺤 뺥 뺦 뺧 뺨 뺩 뺪 뺫 뺬 뺭 뺮 뺯 뺰 뺱 뺲 뺳 뺴 뺵 뺶 뺷 뺸 뺹 뺺 뺻 뺼
뺽 뺾 뺿 뻀 뻁 뻂 뻃 뻄 뻅 뻆 뻇 뻈 뻉 뻊 뻋 뻌 뻍 뻎 뻏 뻐 뻑 뻒 뻓 뻔 뻕
뻖 뻗 뻘 뻙 뻚 뻛 뻜 뻝 뻞 뻟 뻠 뻡 뻢 뻣 뻤 뻥 뻦 뻧 뻨 뻩 뻪 뻫 뻬 뻭 뻮
뻯 뻰 뻱 뻲 뻳 뻴 뻵 뻶 뻷 뻸 뻹 뻺 뻻 뻼 뻽 뻾 뻿 뼀 뼁 뼂 뼃 뼄 뼅 뼆 뼇
뼈 뼉 뼊 뼋 뼌 뼍 뼎 뼏 뼐 뼑 뼒 뼓 뼔 뼕 뼖 뼗 뼘 뼙 뼚 뼛 뼜 뼝 뼞 뼟 뼠
뼡 뼢 뼣 뼤 뼥 뼦 뼧 뼨 뼩 뼪 뼫 뼬 뼭 뼮 뼯 뼰 뼱 뼲 뼳 뼴 뼵 뼶 뼷 뼸 뼹
뼺 뼻 뼼 뼽 뼾 뼿 뽀 뽁 뽂 뽃 뽄 뽅 뽆 뽇 뽈 뽉 뽊 뽋 뽌 뽍 뽎 뽏 뽐 뽑 뽒
뽓 뽔 뽕 뽖 뽗 뽘 뽙 뽚 뽛 뽜 뽝 뽞 뽟 뽠 뽡 뽢 뽣 뽤 뽥 뽦 뽧 뽨 뽩 뽪 뽫
뽬 뽭 뽮 뽯 뽰 뽱 뽲 뽳 뽴 뽵 뽶 뽷 뽸 뽹 뽺 뽻 뽼 뽽 뽾 뽿 뾀 뾁 뾂 뾃 뾄
뾅 뾆 뾇 뾈 뾉 뾊 뾋 뾌 뾍 뾎 뾏 뾐 뾑 뾒 뾓 뾔 뾕 뾖 뾗 뾘 뾙 뾚 뾛 뾜 뾝
뾞 뾟 뾠 뾡 뾢 뾣 뾤 뾥 뾦 뾧 뾨 뾩 뾪 뾫 뾬 뾭 뾮 뾯 뾰 뾱 뾲 뾳 뾴 뾵 뾶
뾷 뾸 뾹 뾺 뾻 뾼 뾽 뾾 뾿 뿀 뿁 뿂 뿃 뿄 뿅 뿆 뿇 뿈 뿉 뿊 뿋 뿌 뿍 뿎 뿏
뿐 뿑 뿒 뿓 뿔 뿕 뿖 뿗 뿘 뿙 뿚 뿛 뿜 뿝 뿞 뿟 뿠 뿡 뿢 뿣 뿤 뿥 뿦 뿧 뿨
뿩 뿪 뿫 뿬 뿭 뿮 뿯 뿰 뿱 뿲 뿳 뿴 뿵 뿶 뿷 뿸 뿹 뿺 뿻 뿼 뿽 뿾 뿿 쀀 쀁
쀂 쀃 쀄 쀅 쀆 쀇 쀈 쀉 쀊 쀋 쀌 쀍 쀎 쀏 쀐 쀑 쀒 쀓 쀔 쀕 쀖 쀗 쀘 쀙 쀚
쀛 쀜 쀝 쀞 쀟 쀠 쀡 쀢 쀣 쀤 쀥 쀦 쀧 쀨 쀩 쀪 쀫 쀬 쀭 쀮 쀯 쀰 쀱 쀲 쀳
쀴 쀵 쀶 쀷 쀸 쀹 쀺 쀻 쀼 쀽 쀾 쀿 쁀 쁁 쁂 쁃 쁄 쁅 쁆 쁇 쁈 쁉 쁊 쁋 쁌
쁍 쁎 쁏 쁐 쁑 쁒 쁓 쁔 쁕 쁖 쁗 쁘 쁙 쁚 쁛 쁜 쁝 쁞 쁟 쁠 쁡 쁢 쁣 쁤 쁥
쁦 쁧 쁨 쁩 쁪 쁫 쁬 쁭 쁮 쁯 쁰 쁱 쁲 쁳 쁴 쁵 쁶 쁷 쁸 쁹 쁺 쁻 쁼 쁽 쁾
쁿 삀 삁 삂 삃 삄 삅 삆 삇 삈 삉 삊 삋 삌 삍 삎 삏 삐 삑 삒 삓 삔 삕 삖 삗
삘 삙 삚 삛 삜 삝 삞 삟 삠 삡 삢 삣 삤 삥 삦 삧 삨 삩 삪 삫 사 삭 삮 삯 산
삱 삲 삳 살 삵 삶 삷 삸 삹 삺 삻 삼 삽 삾 삿 샀 상 샂 샃 샄 샅 샆 샇 새 색
샊 샋 샌 샍 샎 샏 샐 샑 샒 샓 샔 샕 샖 샗 샘 샙 샚 샛 샜 생 샞 샟 샠 샡 샢
샣 샤 샥 샦 샧 샨 샩 샪 샫 샬 샭 샮 샯 샰 샱 샲 샳 샴 샵 샶 샷 샸 샹 샺 샻
샼 샽 샾 샿 섀 섁 섂 섃 섄 섅 섆 섇 섈 섉 섊 섋 섌 섍 섎 섏 섐 섑 섒 섓 섔
섕 섖 섗 섘 섙 섚 섛 서 석 섞 섟 선 섡 섢 섣 설 섥 섦 섧 섨 섩 섪 섫 섬 섭
섮 섯 섰 성 섲 섳 섴 섵 섶 섷 세 섹 섺 섻 센 섽 섾 섿 셀 셁 셂 셃 셄 셅 셆
셇 셈 셉 셊 셋 셌 셍 셎 셏 셐 셑 셒 셓 셔 셕 셖 셗 션 셙 셚 셛 셜 셝 셞 셟
셠 셡 셢 셣 셤 셥 셦 셧 셨 셩 셪 셫 셬 셭 셮 셯 셰 셱 셲 셳 셴 셵 셶 셷 셸
셹 셺 셻 셼 셽 셾 셿 솀 솁 솂 솃 솄 솅 솆 솇 솈 솉 솊 솋 소 속 솎 솏 손 솑
솒 솓 솔 솕 솖 솗 솘 솙 솚 솛 솜 솝 솞 솟 솠 송 솢 솣 솤 솥 솦 솧 솨 솩 솪
솫 솬 솭 솮 솯 솰 솱 솲 솳 솴 솵 솶 솷 솸 솹 솺 솻 솼 솽 솾 솿 쇀 쇁 쇂 쇃
쇄 쇅 쇆 쇇 쇈 쇉 쇊 쇋 쇌 쇍 쇎 쇏 쇐 쇑 쇒 쇓 쇔 쇕 쇖 쇗 쇘 쇙 쇚 쇛 쇜
쇝 쇞 쇟 쇠 쇡 쇢 쇣 쇤 쇥 쇦 쇧 쇨 쇩 쇪 쇫 쇬 쇭 쇮 쇯 쇰 쇱 쇲 쇳 쇴 쇵
쇶 쇷 쇸 쇹 쇺 쇻 쇼 쇽 쇾 쇿 숀 숁 숂 숃 숄 숅 숆 숇 숈 숉 숊 숋 숌 숍 숎
숏 숐 숑 숒 숓 숔 숕 숖 숗 수 숙 숚 숛 순 숝 숞 숟 술 숡 숢 숣 숤 숥 숦 숧
숨 숩 숪 숫 숬 숭 숮 숯 숰 숱 숲 숳 숴 숵 숶 숷 숸 숹 숺 숻 숼 숽 숾 숿 쉀
쉁 쉂 쉃 쉄 쉅 쉆 쉇 쉈 쉉 쉊 쉋 쉌 쉍 쉎 쉏 쉐 쉑 쉒 쉓 쉔 쉕 쉖 쉗 쉘 쉙
쉚 쉛 쉜 쉝 쉞 쉟 쉠 쉡 쉢 쉣 쉤 쉥 쉦 쉧 쉨 쉩 쉪 쉫 쉬 쉭 쉮 쉯 쉰 쉱 쉲
쉳 쉴 쉵 쉶 쉷 쉸 쉹 쉺 쉻 쉼 쉽 쉾 쉿 슀 슁 슂 슃 슄 슅 슆 슇 슈 슉 슊 슋
슌 슍 슎 슏 슐 슑 슒 슓 슔 슕 슖 슗 슘 슙 슚 슛 슜 슝 슞 슟 슠 슡 슢 슣 스
슥 슦 슧 슨 슩 슪 슫 슬 슭 슮 슯 슰 슱 슲 슳 슴 습 슶 슷 슸 승 슺 슻 슼 슽
슾 슿 싀 싁 싂 싃 싄 싅 싆 싇 싈 싉 싊 싋 싌 싍 싎 싏 싐 싑 싒 싓 싔 싕 싖
싗 싘 싙 싚 싛 시 식 싞 싟 신 싡 싢 싣 실 싥 싦 싧 싨 싩 싪 싫 심 십 싮 싯
싰 싱 싲 싳 싴 싵 싶 싷 싸 싹 싺 싻 싼 싽 싾 싿 쌀 쌁 쌂 쌃 쌄 쌅 쌆 쌇 쌈
쌉 쌊 쌋 쌌 쌍 쌎 쌏 쌐 쌑 쌒 쌓 쌔 쌕 쌖 쌗 쌘 쌙 쌚 쌛 쌜 쌝 쌞 쌟 쌠 쌡
쌢 쌣 쌤 쌥 쌦 쌧 쌨 쌩 쌪 쌫 쌬 쌭 쌮 쌯 쌰 쌱 쌲 쌳 쌴 쌵 쌶 쌷 쌸 쌹 쌺
쌻 쌼 쌽 쌾 쌿 썀 썁 썂 썃 썄 썅 썆 썇 썈 썉 썊 썋 썌 썍 썎 썏 썐 썑 썒 썓
썔 썕 썖 썗 썘 썙 썚 썛 썜 썝 썞 썟 썠 썡 썢 썣 썤 썥 썦 썧 써 썩 썪 썫 썬
썭 썮 썯 썰 썱 썲 썳 썴 썵 썶 썷 썸 썹 썺 썻 썼 썽 썾 썿 쎀 쎁 쎂 쎃 쎄 쎅
쎆 쎇 쎈 쎉 쎊 쎋 쎌 쎍 쎎 쎏 쎐 쎑 쎒 쎓 쎔 쎕 쎖 쎗 쎘 쎙 쎚 쎛 쎜 쎝 쎞
쎟 쎠 쎡 쎢 쎣 쎤 쎥 쎦 쎧 쎨 쎩 쎪 쎫 쎬 쎭 쎮 쎯 쎰 쎱 쎲 쎳 쎴 쎵 쎶 쎷
쎸 쎹 쎺 쎻 쎼 쎽 쎾 쎿 쏀 쏁 쏂 쏃 쏄 쏅 쏆 쏇 쏈 쏉 쏊 쏋 쏌 쏍 쏎 쏏 쏐
쏑 쏒 쏓 쏔 쏕 쏖 쏗 쏘 쏙 쏚 쏛 쏜 쏝 쏞 쏟 쏠 쏡 쏢 쏣 쏤 쏥 쏦 쏧 쏨 쏩
쏪 쏫 쏬 쏭 쏮 쏯 쏰 쏱 쏲 쏳 쏴 쏵 쏶 쏷 쏸 쏹 쏺 쏻 쏼 쏽 쏾 쏿 쐀 쐁 쐂
쐃 쐄 쐅 쐆 쐇 쐈 쐉 쐊 쐋 쐌 쐍 쐎 쐏 쐐 쐑 쐒 쐓 쐔 쐕 쐖 쐗 쐘 쐙 쐚 쐛
쐜 쐝 쐞 쐟 쐠 쐡 쐢 쐣 쐤 쐥 쐦 쐧 쐨 쐩 쐪 쐫 쐬 쐭 쐮 쐯 쐰 쐱 쐲 쐳 쐴
쐵 쐶 쐷 쐸 쐹 쐺 쐻 쐼 쐽 쐾 쐿 쑀 쑁 쑂 쑃 쑄 쑅 쑆 쑇 쑈 쑉 쑊 쑋 쑌 쑍
쑎 쑏 쑐 쑑 쑒 쑓 쑔 쑕 쑖 쑗 쑘 쑙 쑚 쑛 쑜 쑝 쑞 쑟 쑠 쑡 쑢 쑣 쑤 쑥 쑦
쑧 쑨 쑩 쑪 쑫 쑬 쑭 쑮 쑯 쑰 쑱 쑲 쑳 쑴 쑵 쑶 쑷 쑸 쑹 쑺 쑻 쑼 쑽 쑾 쑿
쒀 쒁 쒂 쒃 쒄 쒅 쒆 쒇 쒈 쒉 쒊 쒋 쒌 쒍 쒎 쒏 쒐 쒑 쒒 쒓 쒔 쒕 쒖 쒗 쒘
쒙 쒚 쒛 쒜 쒝 쒞 쒟 쒠 쒡 쒢 쒣 쒤 쒥 쒦 쒧 쒨 쒩 쒪 쒫 쒬 쒭 쒮 쒯 쒰 쒱
쒲 쒳 쒴 쒵 쒶 쒷 쒸 쒹 쒺 쒻 쒼 쒽 쒾 쒿 쓀 쓁 쓂 쓃 쓄 쓅 쓆 쓇 쓈 쓉 쓊
쓋 쓌 쓍 쓎 쓏 쓐 쓑 쓒 쓓 쓔 쓕 쓖 쓗 쓘 쓙 쓚 쓛 쓜 쓝 쓞 쓟 쓠 쓡 쓢 쓣
쓤 쓥 쓦 쓧 쓨 쓩 쓪 쓫 쓬 쓭 쓮 쓯 쓰 쓱 쓲 쓳 쓴 쓵 쓶 쓷 쓸 쓹 쓺 쓻 쓼
쓽 쓾 쓿 씀 씁 씂 씃 씄 씅 씆 씇 씈 씉 씊 씋 씌 씍 씎 씏 씐 씑 씒 씓 씔 씕
씖 씗 씘 씙 씚 씛 씜 씝 씞 씟 씠 씡 씢 씣 씤 씥 씦 씧 씨 씩 씪 씫 씬 씭 씮
씯 씰 씱 씲 씳 씴 씵 씶 씷 씸 씹 씺 씻 씼 씽 씾 씿 앀 앁 앂 앃 아 악 앆 앇
안 앉 않 앋 알 앍 앎 앏 앐 앑 앒 앓 암 압 앖 앗 았 앙 앚 앛 앜 앝 앞 앟 애
액 앢 앣 앤 앥 앦 앧 앨 앩 앪 앫 앬 앭 앮 앯 앰 앱 앲 앳 앴 앵 앶 앷 앸 앹
앺 앻 야 약 앾 앿 얀 얁 얂 얃 얄 얅 얆 얇 얈 얉 얊 얋 얌 얍 얎 얏 얐 양 얒
얓 얔 얕 얖 얗 얘 얙 얚 얛 얜 얝 얞 얟 얠 얡 얢 얣 얤 얥 얦 얧 얨 얩 얪 얫
얬 얭 얮 얯 얰 얱 얲 얳 어 억 얶 얷 언 얹 얺 얻 얼 얽 얾 얿 엀 엁 엂 엃 엄
업 없 엇 었 엉 엊 엋 엌 엍 엎 엏 에 엑 엒 엓 엔 엕 엖 엗 엘 엙 엚 엛 엜 엝
엞 엟 엠 엡 엢 엣 엤 엥 엦 엧 엨 엩 엪 엫 여 역 엮 엯 연 엱 엲 엳 열 엵 엶
엷 엸 엹 엺 엻 염 엽 엾 엿 였 영 옂 옃 옄 옅 옆 옇 예 옉 옊 옋 옌 옍 옎 옏
옐 옑 옒 옓 옔 옕 옖 옗 옘 옙 옚 옛 옜 옝 옞 옟 옠 옡 옢 옣 오 옥 옦 옧 온
옩 옪 옫 올 옭 옮 옯 옰 옱 옲 옳 옴 옵 옶 옷 옸 옹 옺 옻 옼 옽 옾 옿 와 왁
왂 왃 완 왅 왆 왇 왈 왉 왊 왋 왌 왍 왎 왏 왐 왑 왒 왓 왔 왕 왖 왗 왘 왙 왚
왛 왜 왝 왞 왟 왠 왡 왢 왣 왤 왥 왦 왧 왨 왩 왪 왫 왬 왭 왮 왯 왰 왱 왲 왳
왴 왵 왶 왷 외 왹 왺 왻 왼 왽 왾 왿 욀 욁 욂 욃 욄 욅 욆 욇 욈 욉 욊 욋 욌
욍 욎 욏 욐 욑 욒 욓 요 욕 욖 욗 욘 욙 욚 욛 욜 욝 욞 욟 욠 욡 욢 욣 욤 욥
욦 욧 욨 용 욪 욫 욬 욭 욮 욯 우 욱 욲 욳 운 욵 욶 욷 울 욹 욺 욻 욼 욽 욾
욿 움 웁 웂 웃 웄 웅 웆 웇 웈 웉 웊 웋 워 웍 웎 웏 원 웑 웒 웓 월 웕 웖 웗
웘 웙 웚 웛 웜 웝 웞 웟 웠 웡 웢 웣 웤 웥 웦 웧 웨 웩 웪 웫 웬 웭 웮 웯 웰
웱 웲 웳 웴 웵 웶 웷 웸 웹 웺 웻 웼 웽 웾 웿 윀 윁 윂 윃 위 윅 윆 윇 윈 윉
윊 윋 윌 윍 윎 윏 윐 윑 윒 윓 윔 윕 윖 윗 윘 윙 윚 윛 윜 윝 윞 윟 유 육 윢
윣 윤 윥 윦 윧 율 윩 윪 윫 윬 윭 윮 윯 윰 윱 윲 윳 윴 융 윶 윷 윸 윹 윺 윻
으 윽 윾 윿 은 읁 읂 읃 을 읅 읆 읇 읈 읉 읊 읋 음 읍 읎 읏 읐 응 읒 읓 읔
읕 읖 읗 의 읙 읚 읛 읜 읝 읞 읟 읠 읡 읢 읣 읤 읥 읦 읧 읨 읩 읪 읫 읬 읭
읮 읯 읰 읱 읲 읳 이 익 읶 읷 인 읹 읺 읻 일 읽 읾 읿 잀 잁 잂 잃 임 입 잆
잇 있 잉 잊 잋 잌 잍 잎 잏 자 작 잒 잓 잔 잕 잖 잗 잘 잙 잚 잛 잜 잝 잞 잟
잠 잡 잢 잣 잤 장 잦 잧 잨 잩 잪 잫 재 잭 잮 잯 잰 잱 잲 잳 잴 잵 잶 잷 잸
잹 잺 잻 잼 잽 잾 잿 쟀 쟁 쟂 쟃 쟄 쟅 쟆 쟇 쟈 쟉 쟊 쟋 쟌 쟍 쟎 쟏 쟐 쟑
쟒 쟓 쟔 쟕 쟖 쟗 쟘 쟙 쟚 쟛 쟜 쟝 쟞 쟟 쟠 쟡 쟢 쟣 쟤 쟥 쟦 쟧 쟨 쟩 쟪
쟫 쟬 쟭 쟮 쟯 쟰 쟱 쟲 쟳 쟴 쟵 쟶 쟷 쟸 쟹 쟺 쟻 쟼 쟽 쟾 쟿 저 적 젂 젃
전 젅 젆 젇 절 젉 젊 젋 젌 젍 젎 젏 점 접 젒 젓 젔 정 젖 젗 젘 젙 젚 젛 제
젝 젞 젟 젠 젡 젢 젣 젤 젥 젦 젧 젨 젩 젪 젫 젬 젭 젮 젯 젰 젱 젲 젳 젴 젵
젶 젷 져 젹 젺 젻 젼 젽 젾 젿 졀 졁 졂 졃 졄 졅 졆 졇 졈 졉 졊 졋 졌 졍 졎
졏 졐 졑 졒 졓 졔 졕 졖 졗 졘 졙 졚 졛 졜 졝 졞 졟 졠 졡 졢 졣 졤 졥 졦 졧
졨 졩 졪 졫 졬 졭 졮 졯 조 족 졲 졳 존 졵 졶 졷 졸 졹 졺 졻 졼 졽 졾 졿 좀
좁 좂 좃 좄 종 좆 좇 좈 좉 좊 좋 좌 좍 좎 좏 좐 좑 좒 좓 좔 좕 좖 좗 좘 좙
좚 좛 좜 좝 좞 좟 좠 좡 좢 좣 좤 좥 좦 좧 좨 좩 좪 좫 좬 좭 좮 좯 좰 좱 좲
좳 좴 좵 좶 좷 좸 좹 좺 좻 좼 좽 좾 좿 죀 죁 죂 죃 죄 죅 죆 죇 죈 죉 죊 죋
죌 죍 죎 죏 죐 죑 죒 죓 죔 죕 죖 죗 죘 죙 죚 죛 죜 죝 죞 죟 죠 죡 죢 죣 죤
죥 죦 죧 죨 죩 죪 죫 죬 죭 죮 죯 죰 죱 죲 죳 죴 죵 죶 죷 죸 죹 죺 죻 주 죽
죾 죿 준 줁 줂 줃 줄 줅 줆 줇 줈 줉 줊 줋 줌 줍 줎 줏 줐 중 줒 줓 줔 줕 줖
줗 줘 줙 줚 줛 줜 줝 줞 줟 줠 줡 줢 줣 줤 줥 줦 줧 줨 줩 줪 줫 줬 줭 줮 줯
줰 줱 줲 줳 줴 줵 줶 줷 줸 줹 줺 줻 줼 줽 줾 줿 쥀 쥁 쥂 쥃 쥄 쥅 쥆 쥇 쥈
쥉 쥊 쥋 쥌 쥍 쥎 쥏 쥐 쥑 쥒 쥓 쥔 쥕 쥖 쥗 쥘 쥙 쥚 쥛 쥜 쥝 쥞 쥟 쥠 쥡
쥢 쥣 쥤 쥥 쥦 쥧 쥨 쥩 쥪 쥫 쥬 쥭 쥮 쥯 쥰 쥱 쥲 쥳 쥴 쥵 쥶 쥷 쥸 쥹 쥺
쥻 쥼 쥽 쥾 쥿 즀 즁 즂 즃 즄 즅 즆 즇 즈 즉 즊 즋 즌 즍 즎 즏 즐 즑 즒 즓
즔 즕 즖 즗 즘 즙 즚 즛 즜 증 즞 즟 즠 즡 즢 즣 즤 즥 즦 즧 즨 즩 즪 즫 즬
즭 즮 즯 즰 즱 즲 즳 즴 즵 즶 즷 즸 즹 즺 즻 즼 즽 즾 즿 지 직 짂 짃 진 짅
짆 짇 질 짉 짊 짋 짌 짍 짎 짏 짐 집 짒 짓 짔 징 짖 짗 짘 짙 짚 짛 짜 짝 짞
짟 짠 짡 짢 짣 짤 짥 짦 짧 짨 짩 짪 짫 짬 짭 짮 짯 짰 짱 짲 짳 짴 짵 짶 짷
째 짹 짺 짻 짼 짽 짾 짿 쨀 쨁 쨂 쨃 쨄 쨅 쨆 쨇 쨈 쨉 쨊 쨋 쨌 쨍 쨎 쨏 쨐
쨑 쨒 쨓 쨔 쨕 쨖 쨗 쨘 쨙 쨚 쨛 쨜 쨝 쨞 쨟 쨠 쨡 쨢 쨣 쨤 쨥 쨦 쨧 쨨 쨩
쨪 쨫 쨬 쨭 쨮 쨯 쨰 쨱 쨲 쨳 쨴 쨵 쨶 쨷 쨸 쨹 쨺 쨻 쨼 쨽 쨾 쨿 쩀 쩁 쩂
쩃 쩄 쩅 쩆 쩇 쩈 쩉 쩊 쩋 쩌 쩍 쩎 쩏 쩐 쩑 쩒 쩓 쩔 쩕 쩖 쩗 쩘 쩙 쩚 쩛
쩜 쩝 쩞 쩟 쩠 쩡 쩢 쩣 쩤 쩥 쩦 쩧 쩨 쩩 쩪 쩫 쩬 쩭 쩮 쩯 쩰 쩱 쩲 쩳 쩴
쩵 쩶 쩷 쩸 쩹 쩺 쩻 쩼 쩽 쩾 쩿 쪀 쪁 쪂 쪃 쪄 쪅 쪆 쪇 쪈 쪉 쪊 쪋 쪌 쪍
쪎 쪏 쪐 쪑 쪒 쪓 쪔 쪕 쪖 쪗 쪘 쪙 쪚 쪛 쪜 쪝 쪞 쪟 쪠 쪡 쪢 쪣 쪤 쪥 쪦
쪧 쪨 쪩 쪪 쪫 쪬 쪭 쪮 쪯 쪰 쪱 쪲 쪳 쪴 쪵 쪶 쪷 쪸 쪹 쪺 쪻 쪼 쪽 쪾 쪿
쫀 쫁 쫂 쫃 쫄 쫅 쫆 쫇 쫈 쫉 쫊 쫋 쫌 쫍 쫎 쫏 쫐 쫑 쫒 쫓 쫔 쫕 쫖 쫗 쫘
쫙 쫚 쫛 쫜 쫝 쫞 쫟 쫠 쫡 쫢 쫣 쫤 쫥 쫦 쫧 쫨 쫩 쫪 쫫 쫬 쫭 쫮 쫯 쫰 쫱
쫲 쫳 쫴 쫵 쫶 쫷 쫸 쫹 쫺 쫻 쫼 쫽 쫾 쫿 쬀 쬁 쬂 쬃 쬄 쬅 쬆 쬇 쬈 쬉 쬊
쬋 쬌 쬍 쬎 쬏 쬐 쬑 쬒 쬓 쬔 쬕 쬖 쬗 쬘 쬙 쬚 쬛 쬜 쬝 쬞 쬟 쬠 쬡 쬢 쬣
쬤 쬥 쬦 쬧 쬨 쬩 쬪 쬫 쬬 쬭 쬮 쬯 쬰 쬱 쬲 쬳 쬴 쬵 쬶 쬷 쬸 쬹 쬺 쬻 쬼
쬽 쬾 쬿 쭀 쭁 쭂 쭃 쭄 쭅 쭆 쭇 쭈 쭉 쭊 쭋 쭌 쭍 쭎 쭏 쭐 쭑 쭒 쭓 쭔 쭕
쭖 쭗 쭘 쭙 쭚 쭛 쭜 쭝 쭞 쭟 쭠 쭡 쭢 쭣 쭤 쭥 쭦 쭧 쭨 쭩 쭪 쭫 쭬 쭭 쭮
쭯 쭰 쭱 쭲 쭳 쭴 쭵 쭶 쭷 쭸 쭹 쭺 쭻 쭼 쭽 쭾 쭿 쮀 쮁 쮂 쮃 쮄 쮅 쮆 쮇
쮈 쮉 쮊 쮋 쮌 쮍 쮎 쮏 쮐 쮑 쮒 쮓 쮔 쮕 쮖 쮗 쮘 쮙 쮚 쮛 쮜 쮝 쮞 쮟 쮠
쮡 쮢 쮣 쮤 쮥 쮦 쮧 쮨 쮩 쮪 쮫 쮬 쮭 쮮 쮯 쮰 쮱 쮲 쮳 쮴 쮵 쮶 쮷 쮸 쮹
쮺 쮻 쮼 쮽 쮾 쮿 쯀 쯁 쯂 쯃 쯄 쯅 쯆 쯇 쯈 쯉 쯊 쯋 쯌 쯍 쯎 쯏 쯐 쯑 쯒
쯓 쯔 쯕 쯖 쯗 쯘 쯙 쯚 쯛 쯜 쯝 쯞 쯟 쯠 쯡 쯢 쯣 쯤 쯥 쯦 쯧 쯨 쯩 쯪 쯫
쯬 쯭 쯮 쯯 쯰 쯱 쯲 쯳 쯴 쯵 쯶 쯷 쯸 쯹 쯺 쯻 쯼 쯽 쯾 쯿 찀 찁 찂 찃 찄
찅 찆 찇 찈 찉 찊 찋 찌 찍 찎 찏 찐 찑 찒 찓 찔 찕 찖 찗 찘 찙 찚 찛 찜 찝
찞 찟 찠 찡 찢 찣 찤 찥 찦 찧 차 착 찪 찫 찬 찭 찮 찯 찰 찱 찲 찳 찴 찵 찶
찷 참 찹 찺 찻 찼 창 찾 찿 챀 챁 챂 챃 채 책 챆 챇 챈 챉 챊 챋 챌 챍 챎 챏
챐 챑 챒 챓 챔 챕 챖 챗 챘 챙 챚 챛 챜 챝 챞 챟 챠 챡 챢 챣 챤 챥 챦 챧 챨
챩 챪 챫 챬 챭 챮 챯 챰 챱 챲 챳 챴 챵 챶 챷 챸 챹 챺 챻 챼 챽 챾 챿 첀 첁
첂 첃 첄 첅 첆 첇 첈 첉 첊 첋 첌 첍 첎 첏 첐 첑 첒 첓 첔 첕 첖 첗 처 척 첚
첛 천 첝 첞 첟 철 첡 첢 첣 첤 첥 첦 첧 첨 첩 첪 첫 첬 청 첮 첯 첰 첱 첲 첳
체 첵 첶 첷 첸 첹 첺 첻 첼 첽 첾 첿 쳀 쳁 쳂 쳃 쳄 쳅 쳆 쳇 쳈 쳉 쳊 쳋 쳌
쳍 쳎 쳏 쳐 쳑 쳒 쳓 쳔 쳕 쳖 쳗 쳘 쳙 쳚 쳛 쳜 쳝 쳞 쳟 쳠 쳡 쳢 쳣 쳤 쳥
쳦 쳧 쳨 쳩 쳪 쳫 쳬 쳭 쳮 쳯 쳰 쳱 쳲 쳳 쳴 쳵 쳶 쳷 쳸 쳹 쳺 쳻 쳼 쳽 쳾
쳿 촀 촁 촂 촃 촄 촅 촆 촇 초 촉 촊 촋 촌 촍 촎 촏 촐 촑 촒 촓 촔 촕 촖 촗
촘 촙 촚 촛 촜 총 촞 촟 촠 촡 촢 촣 촤 촥 촦 촧 촨 촩 촪 촫 촬 촭 촮 촯 촰
촱 촲 촳 촴 촵 촶 촷 촸 촹 촺 촻 촼 촽 촾 촿 쵀 쵁 쵂 쵃 쵄 쵅 쵆 쵇 쵈 쵉
쵊 쵋 쵌 쵍 쵎 쵏 쵐 쵑 쵒 쵓 쵔 쵕 쵖 쵗 쵘 쵙 쵚 쵛 최 쵝 쵞 쵟 쵠 쵡 쵢
쵣 쵤 쵥 쵦 쵧 쵨 쵩 쵪 쵫 쵬 쵭 쵮 쵯 쵰 쵱 쵲 쵳 쵴 쵵 쵶 쵷 쵸 쵹 쵺 쵻
쵼 쵽 쵾 쵿 춀 춁 춂 춃 춄 춅 춆 춇 춈 춉 춊 춋 춌 춍 춎 춏 춐 춑 춒 춓 추
축 춖 춗 춘 춙 춚 춛 출 춝 춞 춟 춠 춡 춢 춣 춤 춥 춦 춧 춨 충 춪 춫 춬 춭
춮 춯 춰 춱 춲 춳 춴 춵 춶 춷 춸 춹 춺 춻 춼 춽 춾 춿 췀 췁 췂 췃 췄 췅 췆
췇 췈 췉 췊 췋 췌 췍 췎 췏 췐 췑 췒 췓 췔 췕 췖 췗 췘 췙 췚 췛 췜 췝 췞 췟
췠 췡 췢 췣 췤 췥 췦 췧 취 췩 췪 췫 췬 췭 췮 췯 췰 췱 췲 췳 췴 췵 췶 췷 췸
췹 췺 췻 췼 췽 췾 췿 츀 츁 츂 츃 츄 츅 츆 츇 츈 츉 츊 츋 츌 츍 츎 츏 츐 츑
츒 츓 츔 츕 츖 츗 츘 츙 츚 츛 츜 츝 츞 츟 츠 측 츢 츣 츤 츥 츦 츧 츨 츩 츪
츫 츬 츭 츮 츯 츰 츱 츲 츳 츴 층 츶 츷 츸 츹 츺 츻 츼 츽 츾 츿 칀 칁 칂 칃
칄 칅 칆 칇 칈 칉 칊 칋 칌 칍 칎 칏 칐 칑 칒 칓 칔 칕 칖 칗 치 칙 칚 칛 친
칝 칞 칟 칠 칡 칢 칣 칤 칥 칦 칧 침 칩 칪 칫 칬 칭 칮 칯 칰 칱 칲 칳 카 칵
칶 칷 칸 칹 칺 칻 칼 칽 칾 칿 캀 캁 캂 캃 캄 캅 캆 캇 캈 캉 캊 캋 캌 캍 캎
캏 캐 캑 캒 캓 캔 캕 캖 캗 캘 캙 캚 캛 캜 캝 캞 캟 캠 캡 캢 캣 캤 캥 캦 캧
캨 캩 캪 캫 캬 캭 캮 캯 캰 캱 캲 캳 캴 캵 캶 캷 캸 캹 캺 캻 캼 캽 캾 캿 컀
컁 컂 컃 컄 컅 컆 컇 컈 컉 컊 컋 컌 컍 컎 컏 컐 컑 컒 컓 컔 컕 컖 컗 컘 컙
컚 컛 컜 컝 컞 컟 컠 컡 컢 컣 커 컥 컦 컧 컨 컩 컪 컫 컬 컭 컮 컯 컰 컱 컲
컳 컴 컵 컶 컷 컸 컹 컺 컻 컼 컽 컾 컿 케 켁 켂 켃 켄 켅 켆 켇 켈 켉 켊 켋
켌 켍 켎 켏 켐 켑 켒 켓 켔 켕 켖 켗 켘 켙 켚 켛 켜 켝 켞 켟 켠 켡 켢 켣 켤
켥 켦 켧 켨 켩 켪 켫 켬 켭 켮 켯 켰 켱 켲 켳 켴 켵 켶 켷 켸 켹 켺 켻 켼 켽
켾 켿 콀 콁 콂 콃 콄 콅 콆 콇 콈 콉 콊 콋 콌 콍 콎 콏 콐 콑 콒 콓 코 콕 콖
콗 콘 콙 콚 콛 콜 콝 콞 콟 콠 콡 콢 콣 콤 콥 콦 콧 콨 콩 콪 콫 콬 콭 콮 콯
콰 콱 콲 콳 콴 콵 콶 콷 콸 콹 콺 콻 콼 콽 콾 콿 쾀 쾁 쾂 쾃 쾄 쾅 쾆 쾇 쾈
쾉 쾊 쾋 쾌 쾍 쾎 쾏 쾐 쾑 쾒 쾓 쾔 쾕 쾖 쾗 쾘 쾙 쾚 쾛 쾜 쾝 쾞 쾟 쾠 쾡
쾢 쾣 쾤 쾥 쾦 쾧 쾨 쾩 쾪 쾫 쾬 쾭 쾮 쾯 쾰 쾱 쾲 쾳 쾴 쾵 쾶 쾷 쾸 쾹 쾺
쾻 쾼 쾽 쾾 쾿 쿀 쿁 쿂 쿃 쿄 쿅 쿆 쿇 쿈 쿉 쿊 쿋 쿌 쿍 쿎 쿏 쿐 쿑 쿒 쿓
쿔 쿕 쿖 쿗 쿘 쿙 쿚 쿛 쿜 쿝 쿞 쿟 쿠 쿡 쿢 쿣 쿤 쿥 쿦 쿧 쿨 쿩 쿪 쿫 쿬
쿭 쿮 쿯 쿰 쿱 쿲 쿳 쿴 쿵 쿶 쿷 쿸 쿹 쿺 쿻 쿼 쿽 쿾 쿿 퀀 퀁 퀂 퀃 퀄 퀅
퀆 퀇 퀈 퀉 퀊 퀋 퀌 퀍 퀎 퀏 퀐 퀑 퀒 퀓 퀔 퀕 퀖 퀗 퀘 퀙 퀚 퀛 퀜 퀝 퀞
퀟 퀠 퀡 퀢 퀣 퀤 퀥 퀦 퀧 퀨 퀩 퀪 퀫 퀬 퀭 퀮 퀯 퀰 퀱 퀲 퀳 퀴 퀵 퀶 퀷
퀸 퀹 퀺 퀻 퀼 퀽 퀾 퀿 큀 큁 큂 큃 큄 큅 큆 큇 큈 큉 큊 큋 큌 큍 큎 큏 큐
큑 큒 큓 큔 큕 큖 큗 큘 큙 큚 큛 큜 큝 큞 큟 큠 큡 큢 큣 큤 큥 큦 큧 큨 큩
큪 큫 크 큭 큮 큯 큰 큱 큲 큳 클 큵 큶 큷 큸 큹 큺 큻 큼 큽 큾 큿 킀 킁 킂
킃 킄 킅 킆 킇 킈 킉 킊 킋 킌 킍 킎 킏 킐 킑 킒 킓 킔 킕 킖 킗 킘 킙 킚 킛
킜 킝 킞 킟 킠 킡 킢 킣 키 킥 킦 킧 킨 킩 킪 킫 킬 킭 킮 킯 킰 킱 킲 킳 킴
킵 킶 킷 킸 킹 킺 킻 킼 킽 킾 킿 타 탁 탂 탃 탄 탅 탆 탇 탈 탉 탊 탋 탌 탍
탎 탏 탐 탑 탒 탓 탔 탕 탖 탗 탘 탙 탚 탛 태 택 탞 탟 탠 탡 탢 탣 탤 탥 탦
탧 탨 탩 탪 탫 탬 탭 탮 탯 탰 탱 탲 탳 탴 탵 탶 탷 탸 탹 탺 탻 탼 탽 탾 탿
턀 턁 턂 턃 턄 턅 턆 턇 턈 턉 턊 턋 턌 턍 턎 턏 턐 턑 턒 턓 턔 턕 턖 턗 턘
턙 턚 턛 턜 턝 턞 턟 턠 턡 턢 턣 턤 턥 턦 턧 턨 턩 턪 턫 턬 턭 턮 턯 터 턱
턲 턳 턴 턵 턶 턷 털 턹 턺 턻 턼 턽 턾 턿 텀 텁 텂 텃 텄 텅 텆 텇 텈 텉 텊
텋 테 텍 텎 텏 텐 텑 텒 텓 텔 텕 텖 텗 텘 텙 텚 텛 템 텝 텞 텟 텠 텡 텢 텣
텤 텥 텦 텧 텨 텩 텪 텫 텬 텭 텮 텯 텰 텱 텲 텳 텴 텵 텶 텷 텸 텹 텺 텻 텼
텽 텾 텿 톀 톁 톂 톃 톄 톅 톆 톇 톈 톉 톊 톋 톌 톍 톎 톏 톐 톑 톒 톓 톔 톕
톖 톗 톘 톙 톚 톛 톜 톝 톞 톟 토 톡 톢 톣 톤 톥 톦 톧 톨 톩 톪 톫 톬 톭 톮
톯 톰 톱 톲 톳 톴 통 톶 톷 톸 톹 톺 톻 톼 톽 톾 톿 퇀 퇁 퇂 퇃 퇄 퇅 퇆 퇇
퇈 퇉 퇊 퇋 퇌 퇍 퇎 퇏 퇐 퇑 퇒 퇓 퇔 퇕 퇖 퇗 퇘 퇙 퇚 퇛 퇜 퇝 퇞 퇟 퇠
퇡 퇢 퇣 퇤 퇥 퇦 퇧 퇨 퇩 퇪 퇫 퇬 퇭 퇮 퇯 퇰 퇱 퇲 퇳 퇴 퇵 퇶 퇷 퇸 퇹
퇺 퇻 퇼 퇽 퇾 퇿 툀 툁 툂 툃 툄 툅 툆 툇 툈 툉 툊 툋 툌 툍 툎 툏 툐 툑 툒
툓 툔 툕 툖 툗 툘 툙 툚 툛 툜 툝 툞 툟 툠 툡 툢 툣 툤 툥 툦 툧 툨 툩 툪 툫
투 툭 툮 툯 툰 툱 툲 툳 툴 툵 툶 툷 툸 툹 툺 툻 툼 툽 툾 툿 퉀 퉁 퉂 퉃 퉄
퉅 퉆 퉇 퉈 퉉 퉊 퉋 퉌 퉍 퉎 퉏 퉐 퉑 퉒 퉓 퉔 퉕 퉖 퉗 퉘 퉙 퉚 퉛 퉜 퉝
퉞 퉟 퉠 퉡 퉢 퉣 퉤 퉥 퉦 퉧 퉨 퉩 퉪 퉫 퉬 퉭 퉮 퉯 퉰 퉱 퉲 퉳 퉴 퉵 퉶
퉷 퉸 퉹 퉺 퉻 퉼 퉽 퉾 퉿 튀 튁 튂 튃 튄 튅 튆 튇 튈 튉 튊 튋 튌 튍 튎 튏
튐 튑 튒 튓 튔 튕 튖 튗 튘 튙 튚 튛 튜 튝 튞 튟 튠 튡 튢 튣 튤 튥 튦 튧 튨
튩 튪 튫 튬 튭 튮 튯 튰 튱 튲 튳 튴 튵 튶 튷 트 특 튺 튻 튼 튽 튾 튿 틀 틁
틂 틃 틄 틅 틆 틇 틈 틉 틊 틋 틌 틍 틎 틏 틐 틑 틒 틓 틔 틕 틖 틗 틘 틙 틚
틛 틜 틝 틞 틟 틠 틡 틢 틣 틤 틥 틦 틧 틨 틩 틪 틫 틬 틭 틮 틯 티 틱 틲 틳
틴 틵 틶 틷 틸 틹 틺 틻 틼 틽 틾 틿 팀 팁 팂 팃 팄 팅 팆 팇 팈 팉 팊 팋 파
팍 팎 팏 판 팑 팒 팓 팔 팕 팖 팗 팘 팙 팚 팛 팜 팝 팞 팟 팠 팡 팢 팣 팤 팥
팦 팧 패 팩 팪 팫 팬 팭 팮 팯 팰 팱 팲 팳 팴 팵 팶 팷 팸 팹 팺 팻 팼 팽 팾
팿 퍀 퍁 퍂 퍃 퍄 퍅 퍆 퍇 퍈 퍉 퍊 퍋 퍌 퍍 퍎 퍏 퍐 퍑 퍒 퍓 퍔 퍕 퍖 퍗
퍘 퍙 퍚 퍛 퍜 퍝 퍞 퍟 퍠 퍡 퍢 퍣 퍤 퍥 퍦 퍧 퍨 퍩 퍪 퍫 퍬 퍭 퍮 퍯 퍰
퍱 퍲 퍳 퍴 퍵 퍶 퍷 퍸 퍹 퍺 퍻 퍼 퍽 퍾 퍿 펀 펁 펂 펃 펄 펅 펆 펇 펈 펉
펊 펋 펌 펍 펎 펏 펐 펑 펒 펓 펔 펕 펖 펗 페 펙 펚 펛 펜 펝 펞 펟 펠 펡 펢
펣 펤 펥 펦 펧 펨 펩 펪 펫 펬 펭 펮 펯 펰 펱 펲 펳 펴 펵 펶 펷 편 펹 펺 펻
펼 펽 펾 펿 폀 폁 폂 폃 폄 폅 폆 폇 폈 평 폊 폋 폌 폍 폎 폏 폐 폑 폒 폓 폔
폕 폖 폗 폘 폙 폚 폛 폜 폝 폞 폟 폠 폡 폢 폣 폤 폥 폦 폧 폨 폩 폪 폫 포 폭
폮 폯 폰 폱 폲 폳 폴 폵 폶 폷 폸 폹 폺 폻 폼 폽 폾 폿 퐀 퐁 퐂 퐃 퐄 퐅 퐆
퐇 퐈 퐉 퐊 퐋 퐌 퐍 퐎 퐏 퐐 퐑 퐒 퐓 퐔 퐕 퐖 퐗 퐘 퐙 퐚 퐛 퐜 퐝 퐞 퐟
퐠 퐡 퐢 퐣 퐤 퐥 퐦 퐧 퐨 퐩 퐪 퐫 퐬 퐭 퐮 퐯 퐰 퐱 퐲 퐳 퐴 퐵 퐶 퐷 퐸
퐹 퐺 퐻 퐼 퐽 퐾 퐿 푀 푁 푂 푃 푄 푅 푆 푇 푈 푉 푊 푋 푌 푍 푎 푏 푐 푑
푒 푓 푔 푕 푖 푗 푘 푙 푚 푛 표 푝 푞 푟 푠 푡 푢 푣 푤 푥 푦 푧 푨 푩 푪
푫 푬 푭 푮 푯 푰 푱 푲 푳 푴 푵 푶 푷 푸 푹 푺 푻 푼 푽 푾 푿 풀 풁 풂 풃
풄 풅 풆 풇 품 풉 풊 풋 풌 풍 풎 풏 풐 풑 풒 풓 풔 풕 풖 풗 풘 풙 풚 풛 풜
풝 풞 풟 풠 풡 풢 풣 풤 풥 풦 풧 풨 풩 풪 풫 풬 풭 풮 풯 풰 풱 풲 풳 풴 풵
풶 풷 풸 풹 풺 풻 풼 풽 풾 풿 퓀 퓁 퓂 퓃 퓄 퓅 퓆 퓇 퓈 퓉 퓊 퓋 퓌 퓍 퓎
퓏 퓐 퓑 퓒 퓓 퓔 퓕 퓖 퓗 퓘 퓙 퓚 퓛 퓜 퓝 퓞 퓟 퓠 퓡 퓢 퓣 퓤 퓥 퓦 퓧
퓨 퓩 퓪 퓫 퓬 퓭 퓮 퓯 퓰 퓱 퓲 퓳 퓴 퓵 퓶 퓷 퓸 퓹 퓺 퓻 퓼 퓽 퓾 퓿 픀
픁 픂 픃 프 픅 픆 픇 픈 픉 픊 픋 플 픍 픎 픏 픐 픑 픒 픓 픔 픕 픖 픗 픘 픙
픚 픛 픜 픝 픞 픟 픠 픡 픢 픣 픤 픥 픦 픧 픨 픩 픪 픫 픬 픭 픮 픯 픰 픱 픲
픳 픴 픵 픶 픷 픸 픹 픺 픻 피 픽 픾 픿 핀 핁 핂 핃 필 핅 핆 핇 핈 핉 핊 핋
핌 핍 핎 핏 핐 핑 핒 핓 핔 핕 핖 핗 하 학 핚 핛 한 핝 핞 핟 할 핡 핢 핣 핤
핥 핦 핧 함 합 핪 핫 핬 항 핮 핯 핰 핱 핲 핳 해 핵 핶 핷 핸 핹 핺 핻 핼 핽
핾 핿 햀 햁 햂 햃 햄 햅 햆 햇 했 행 햊 햋 햌 햍 햎 햏 햐 햑 햒 햓 햔 햕 햖
햗 햘 햙 햚 햛 햜 햝 햞 햟 햠 햡 햢 햣 햤 향 햦 햧 햨 햩 햪 햫 햬 햭 햮 햯
햰 햱 햲 햳 햴 햵 햶 햷 햸 햹 햺 햻 햼 햽 햾 햿 헀 헁 헂 헃 헄 헅 헆 헇 허
헉 헊 헋 헌 헍 헎 헏 헐 헑 헒 헓 헔 헕 헖 헗 험 헙 헚 헛 헜 헝 헞 헟 헠 헡
헢 헣 헤 헥 헦 헧 헨 헩 헪 헫 헬 헭 헮 헯 헰 헱 헲 헳 헴 헵 헶 헷 헸 헹 헺
헻 헼 헽 헾 헿 혀 혁 혂 혃 현 혅 혆 혇 혈 혉 혊 혋 혌 혍 혎 혏 혐 협 혒 혓
혔 형 혖 혗 혘 혙 혚 혛 혜 혝 혞 혟 혠 혡 혢 혣 혤 혥 혦 혧 혨 혩 혪 혫 혬
혭 혮 혯 혰 혱 혲 혳 혴 혵 혶 혷 호 혹 혺 혻 혼 혽 혾 혿 홀 홁 홂 홃 홄 홅
홆 홇 홈 홉 홊 홋 홌 홍 홎 홏 홐 홑 홒 홓 화 확 홖 홗 환 홙 홚 홛 활 홝 홞
홟 홠 홡 홢 홣 홤 홥 홦 홧 홨 황 홪 홫 홬 홭 홮 홯 홰 홱 홲 홳 홴 홵 홶 홷
홸 홹 홺 홻 홼 홽 홾 홿 횀 횁 횂 횃 횄 횅 횆 횇 횈 횉 횊 횋 회 획 횎 횏 횐
횑 횒 횓 횔 횕 횖 횗 횘 횙 횚 횛 횜 횝 횞 횟 횠 횡 횢 횣 횤 횥 횦 횧 효 횩
횪 횫 횬 횭 횮 횯 횰 횱 횲 횳 횴 횵 횶 횷 횸 횹 횺 횻 횼 횽 횾 횿 훀 훁 훂
훃 후 훅 훆 훇 훈 훉 훊 훋 훌 훍 훎 훏 훐 훑 훒 훓 훔 훕 훖 훗 훘 훙 훚 훛
훜 훝 훞 훟 훠 훡 훢 훣 훤 훥 훦 훧 훨 훩 훪 훫 훬 훭 훮 훯 훰 훱 훲 훳 훴
훵 훶 훷 훸 훹 훺 훻 훼 훽 훾 훿 휀 휁 휂 휃 휄 휅 휆 휇 휈 휉 휊 휋 휌 휍
휎 휏 휐 휑 휒 휓 휔 휕 휖 휗 휘 휙 휚 휛 휜 휝 휞 휟 휠 휡 휢 휣 휤 휥 휦
휧 휨 휩 휪 휫 휬 휭 휮 휯 휰 휱 휲 휳 휴 휵 휶 휷 휸 휹 휺 휻 휼 휽 휾 휿
흀 흁 흂 흃 흄 흅 흆 흇 흈 흉 흊 흋 흌 흍 흎 흏 흐 흑 흒 흓 흔 흕 흖 흗 흘
흙 흚 흛 흜 흝 흞 흟 흠 흡 흢 흣 흤 흥 흦 흧 흨 흩 흪 흫 희 흭 흮 흯 흰 흱
흲 흳 흴 흵 흶 흷 흸 흹 흺 흻 흼 흽 흾 흿 힀 힁 힂 힃 힄 힅 힆 힇 히 힉 힊
힋 힌 힍 힎 힏 힐 힑 힒 힓 힔 힕 힖 힗 힘 힙 힚 힛 힜 힝 힞 힟 힠 힡 힢 힣",
- 3: "丘 串 乃 久 乖 九 乞 乫 乾 亂 亘 交 京 仇 今 介 件 价 企 伋 伎 伽 佳
佶 侃 來 侊 供 係 俓 俱 個 倞 倦 倨 假 偈 健 傀 傑 傾 僅 僑 價 儆 儉 儺 光
克 兢 內 公 共 其 具 兼 冀 冠 凱 刊 刮 券 刻 剋 剛 劇 劍 劒 功 加 劤 劫 勁
勍 勘 勤 勸 勻 勾 匡 匣 區 南 卦 却 卵 卷 卿 厥 去 及 口 句 叩 叫 可 各 吉
君 告 呱 呵 咎 咬 哥 哭 啓 喀 喇 喝 喫 喬 嗜 嘉 嘔 器 囊 困 固 圈 國 圭 圻
均 坎 坑 坤 坰 坵 垢 基 埼 堀 堅 堈 堪 堺 塊 塏 境 墾 壙 壞 夔 奇 奈 奎 契
奸 妓 妗 姑 姜 姦 娘 娜 嫁 嬌 孔 季 孤 宏 官 客 宮 家 寄 寇 寡 寬 尻 局 居
屆 屈 岐 岡 岬 崎 崑 崗 嵌 嵐 嶇 嶠 工 巧 巨 己 巾 干 幹 幾 庚 庫 康 廊 廐
廓 廣 建 弓 强 彊 徑 忌 急 怪 怯 恐 恝 恪 恭 悸 愆 感 愧 愷 愾 慊 慣 慤 慨
慶 慷 憩 憬 憾 懃 懇 懦 懶 懼 戈 戒 戟 戡 扱 技 抉 拉 拏 拐 拒 拘 括 拮 拱
拳 拷 拿 捏 据 捲 捺 掘 掛 控 揀 揆 揭 擊 擎 擒 據 擧 攪 攷 改 攻 故 敎 救
敢 敬 敲 斛 斤 旗 旣 昆 昑 景 晷 暇 暖 暠 暻 曠 曲 更 曷 朗 朞 期 机 杆 杞
杰 枏 果 枯 架 枸 柑 柩 柬 柯 校 根 格 桀 桂 桔 桿 梏 梗 械 梱 棄 棋 棍 棘
棨 棺 楗 楠 極 槁 構 槐 槨 槪 槻 槿 樂 橄 橋 橘 機 檄 檎 檢 櫃 欄 權 欺 款
歌 歐 歸 殼 毆 毬 氣 求 江 汨 汲 決 汽 沂 沽 洛 洸 浪 涇 淃 淇 減 渠 渴 湳
溝 溪 滑 滾 漑 潔 潰 澗 激 濫 灌 灸 炅 炚 炬 烙 烱 煖 爛 牽 犬 狂 狗 狡 狼
獗 玖 玘 珂 珏 珖 珙 珞 珪 球 琦 琨 琪 琯 琴 瑾 璂 璟 璣 璥 瓊 瓘 瓜 甄 甘
甲 男 畇 界 畸 畺 畿 疆 疥 疳 痂 痙 痼 癎 癩 癸 皆 皎 皐 盖 監 看 眷 睾 瞰
瞼 瞿 矜 矩 矯 硅 硬 碁 碣 磎 磬 磯 磵 祁 祇 祈 祛 祺 禁 禽 科 稈 稼 稽 稿
穀 究 穹 空 窘 窟 窮 窺 竅 竟 竭 競 竿 筋 筐 筠 箇 箕 箝 管 簡 粳 糠 系 糾
紀 納 紘 級 紺 絅 結 絞 給 絳 絹 絿 經 綱 綺 緊 繫 繭 繼 缺 罐 罫 羅 羈 羌
羔 群 羹 翹 考 耆 耉 耕 耭 耿 肌 肝 股 肩 肯 肱 胛 胱 脚 脛 腔 腱 膈 膏 膠
臘 臼 舅 舊 舡 艮 艱 芎 芥 芩 芹 苛 苟 苦 苽 茄 莖 菅 菊 菌 菓 菫 菰 落 葛
葵 蓋 蕎 蕨 薑 藁 藍 藿 蘭 蘿 虔 蚣 蛟 蝎 螺 蠟 蠱 街 衢 衲 衾 衿 袈 袞 袴
裙 裸 褐 襁 襟 襤 見 規 覡 覲 覺 觀 角 計 記 訣 訶 詭 誇 誡 誥 課 諫 諾 謙
講 謳 謹 譏 警 譴 谷 谿 豈 貢 貫 貴 賈 購 赳 起 跏 距 跨 踞 蹇 蹶 躬 軀 車
軌 軍 軻 較 輕 轎 轟 辜 近 迦 迲 适 逑 逕 逵 過 遣 遽 邏 那 邯 邱 郊 郎 郡
郭 酪 醵 金 鈐 鈞 鉀 鉅 鉗 鉤 銶 鋸 鋼 錡 錤 錦 錮 鍋 鍵 鎌 鎧 鏡 鑑 鑒 鑛
開 間 閘 閣 閨 闕 關 降 階 隔 隙 雇 難 鞏 鞠 鞨 鞫 頃 頸 顆 顧 飢 餃 館 饉
饋 饑 駒 駕 駱 騎 騏 騫 驅 驕 驚 驥 骨 高 鬼 魁 鮫 鯤 鯨 鱇 鳩 鵑 鵠 鷄 鷗
鸞 麒 麴 黔 鼓 龕 龜",
- 4: "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",
- },
- "kok": {
- 0: "़ ० १ २ ३ ४ ५ ६ ७ ८ ९ ॐ ं ँ ः अ आ इ ई उ ऊ ऋ ऌ ऍ ए ऐ ऑ ओ औ क क़ ख ख़
ग ग़ घ ङ च छ ज ज़ झ ञ ट ठ ड ड़ ढ ढ़ ण त थ द ध न प फ फ़ ब भ म य य़ र ल व श ष
स ह ळ ऽ ा ि ी ु ू ृ ॄ ॅ े ै ॉ ो ौ ्",
- 3: "\u200c \u200d",
- },
- "ksb": {
- 0: "a b c d e f g h i j k l m n o p s t u v w y z",
- 3: "q r x",
- 5: "A B C D E F G H I J K L M N O P S T U V W Y Z",
- },
- "ksf": {
- 0: "a á b c d e é ǝ ǝ́ ɛ ɛ́ f g h i í j k l m n ŋ o ó ɔ ɔ́ p r s t u ú v
w y z",
- 3: "q x",
- 5: "A B C D E Ǝ Ɛ F G H I J K L M N Ŋ O Ɔ P R S T U V W Y Z",
- },
- "ksh": {
- 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",
- 3: "á à ă â å ä ã ā æ ç é è ĕ ê ë ē ğ í ì ĭ î ï ī ij ı ł ñ ó ò ŏ ô ö ø ō
œ ú ù ŭ û ü ū ÿ",
- },
- "ku": {
- 0: "ئ ا ب پ ت ج چ ح خ د ر ز ڕ ژ س ش ع غ ف ڤ ق ک گ ل ڵ م ن ه ھ و ۆ ی ێ",
- 3: "ً ٌ ٍ َ ُ ِ ّ ْ ء آ أ ؤ إ ئ ا ب ة ث ذ ص ض ط ظ ك ى ي",
- },
- "ku_Latn": {
- 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",
- },
- "kw": {
- 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",
- },
- "ky": {
- 0: "а б г д е ё ж з и й к л м н ӊ о ө п р с т у ү х ч ш ъ ы э ю я",
- 3: "в ф ц щ ь",
- },
- "lag": {
- 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",
- 5: "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",
- },
- "lg": {
- 0: "a b c d e f g i j k l m n ny ŋ o p r s t u v w y z",
- 3: "h q x",
- 5: "A B C D E F G I J K L M N Ŋ O P R S T U V W Y Z",
- },
- "ln": {
- 0: "a á â ǎ b c d e é ê ě ɛ ɛ́ ɛ̂ ɛ̌ f g gb h i í î ǐ k l m mb mp n nd
ng nk ns nt ny nz o ó ô ǒ ɔ ɔ́ ɔ̂ ɔ̌ p r s t u ú v w y z",
- 3: "j q x",
- 5: "A B C D E Ɛ F G Gb H I K L M Mb Mp N Nd Ng Nk Ns Nt Ny Nz O Ɔ P R S
T U V W Y Z",
- },
- "lo": {
- 0: "່ ້ ໊ ໋ ໌ ໍ ໆ ກ ຂ ຄ ງ ຈ ສ ຊ ຍ ດ ຕ ຖ ທ ນ ບ ປ ຜ ຝ ພ ຟ ມ ຢ ຣ ລ ວ ຫ ໜ ໝ
ອ ຮ ຯ ະ ັ າ ຳ ິ ີ ຶ ື ຸ ູ ົ ຼ ຽ ເ ແ ໂ ໃ ໄ",
- 3: "\u200b ໐ ໑ ໒ ໓ ໔ ໕ ໖ ໗ ໘ ໙",
- },
- "lt": {
- 0: "a ą b c č d e ę ė f g h i į y j k l m n o p r s š t u ų ū v z ž",
- 3: "i̇́ i̇̀ i̇̃ i̇ į̇ j̇ q w x",
- 4: "a ą b c č d e ę ė f g h i į y j k l m n o p r s š t u ų ū v z ž",
- 5: "A Ą B C Č D E Ę Ė F G H I Į Y J K L M N O P R S Š T U Ų Ū V Z Ž",
- },
- "lu": {
- 0: "a á à b c d e é è ɛ ɛ́ ɛ̀ f h i í ì j k l m n ng ny o ó ò ɔ ɔ́ ɔ̀ p
ph q s shi t u ú ù v w y z",
- 3: "g r x",
- 5: "A B C D E F H I J K L M N O P Q S T U V W Y Z",
- },
- "luo": {
- 0: "a b c d e f g h i j k l m n o p r s t u v w y",
- 3: "q x z",
- 5: "A B C D E F G H I J K L M N O P R S T U V W Y",
- },
- "luy": {
- 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",
- 5: "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",
- },
- "lv": {
- 0: "a ā b c č d e ē f g ģ h i ī j k ķ l ļ m n ņ o p r s š t u ū v z ž",
- 2: "- ‐ – — , ; : ! ? . … ' ‘ ’ ‚ \" “ ” „ ( ) [ ] @ * / & # † ‡ ′ ″ §",
- 3: "q w x y",
- 4: "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",
- 5: "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 Ž",
- },
- "mas": {
- 0: "a á à â ā b c d e é è ê ē ɛ g h i í ì î ī ɨ j k l m n ny ŋ o ó ò ô ō
ɔ p r rr s sh t u ú ù û ū ʉ ʉ́ w wu y yi",
- 3: "f q v x z",
- 5: "A B C D E Ɛ G H I Ɨ J K L M N Ŋ O Ɔ P R S T U Ʉ W Y",
- },
- "mer": {
- 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",
- 5: "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",
- },
- "mfe": {
- 0: "a b c d e f g h i j k l m n o p r s t u v w x y z",
- 5: "A B C D E F G H I J K L M N O P R S T U V W X Y Z",
- },
- "mg": {
- 0: "a à â b d e é è ê ë f g h i ì î ï j k l m n ñ o ô p r s t v y z",
- 3: "c q u w x",
- 5: "A B D E F G H I J K L M N O P R S T V Y Z",
- },
- "mgh": {
- 0: "a b c d e f g h i j k l m n o p r s t u v w y z",
- 3: "q x",
- 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z",
- },
- "mk": {
- 0: "а б в г д ѓ е ж з ѕ и ј к л љ м н њ о п р с т ќ у ф х ц ч џ ш",
- 3: "ѐ ѝ",
- 4: "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",
- 5: "А Б В Г Д Ѓ Е Ж З Ѕ И Ј К Л Љ М Н Њ О П Р С Т Ќ У Ф Х Ц Ч Џ Ш",
- },
- "ml": {
- 0: "\u200c \u200d ഃ അ ആ ഇ ഈ ഉ ഊ ഋ ൠ ഌ ൡ എ ഏ ഐ ഒ ഓ ഔ ക ഖ ഗ ഘ ങ ച ഛ ജ ഝ ഞ
ട ഠ ഡ ഢ ണ ത ഥ ദ ധ ന പ ഫ ബ ഭ മ ം യ ര ല വ ശ ഷ സ ഹ ള ഴ റ ാ ി ീ ു ൂ ൃ െ േ ൈ ൊ ോ
ൗ ൌ ്",
- 4: "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",
- },
- "mn": {
- 0: "а б в г д е ё ж з и й к л м н о ө п р с т у ү ф х ц ч ш щ ъ ы ь э ю
я",
- 3: "ә җ ӊ һ",
- },
- "mn_Mong": {
- 0: "᠐ ᠑ ᠒ ᠓ ᠔ ᠕ ᠖ ᠗ ᠘ ᠙ ᠠ ᠡ ᠢ ᠣ ᠤ ᠥ ᠦ ᠧ ᠨ ᠩ ᠪ ᠫ ᠬ ᠭ ᠮ ᠯ ᠰ ᠱ ᠲ ᠳ ᠴ ᠵ ᠶ ᠷ
ᠸ ᠹ ᠺ ᠻ ᠼ ᠽ ᠾ ᠿ ᡀ ᡁ ᡂ",
- },
- "mr": {
- 0: "़ ० १ २ ३ ४ ५ ६ ७ ८ ९ ॐ ं ँ ः अ आ इ ई उ ऊ ऋ ऌ ऍ ए ऐ ऑ ओ औ क ख ग घ ङ
च छ ज झ ञ ट ठ ड ढ ण त थ द ध न प फ ब भ म य र ल व श ष स ह ळ ऽ ा ि ी ु ू ृ ॄ ॅ
े ै ॉ ो ौ ्",
- 3: "\u200c \u200d",
- 4: "र ु",
- 5: "\u200d ॐ ं ः अ आ इ ई उ ऊ ऋ ऌ ए ऐ ऑ ओ औ क ख ग घ ङ च छ ज झ ञ ट ठ ड ढ ण
त थ द ध न प फ ब भ म य र ल व श ष स ह ळ ऽ ॅ ्",
- },
- "ms": {
- 0: "a ai au b c d dz e f g h i j k kh l m n ng ngg ny o p q r s sy t ts
u ua v w x y z",
- 3: "á à ă â å ä ã ā æ ç é è ĕ ê ë ē í ì ĭ î ï ī ñ ó ò ŏ ô ö ø ō œ ú ù ŭ
û ü ū ÿ",
- 5: "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",
- },
- "mt": {
- 0: "a à b ċ d e è f ġ g għ h ħ i ì j k l m n o ò p q r s t u ù v w x ż
z",
- 3: "c y",
- },
- "mua": {
- 0: "a ã b ɓ c d ɗ e ë ǝ f g h i ĩ j k l m n ŋ o õ p r s t u v ṽ w y z",
- 3: "q x",
- 5: "A B Ɓ C D Ɗ E Ǝ F G H I J K L M N Ŋ O P R S T U V W Y Z",
- },
- "my": {
- 0: "က ခ ဂ ဃ င စ ဆ ဇ ဈ ဉ ည ဋ ဌ ဍ ဎ ဏ တ ထ ဒ ဓ န ပ ဖ ဗ ဘ မ ယ ရ လ ဝ သ ဟ ဠ အ
ဣ ဤ ဥ ဦ ဧ ဩ ဪ ာ ါ ိ ီ ု ူ ေ ဲ ံ ဿ ျ ြ ွ ှ ္ ် ့ း",
- 3: "ၐ ၑ ဨ ဢ ၒ ၓ ၔ ၕ ၖ ၗ ၘ ၙ",
- 4: "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",
- },
- "naq": {
- 0: "a â b c d e f g h i î k m n o ô p q r s t u û w x y z ǀ ǁ ǂ ǃ",
- 3: "j l v",
- 5: "A B C D E F G H I K M N O P Q R S T U W X Y Z",
- },
- "nb": {
- 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 æ ø å",
- 3: "á ǎ ã č ç đ è ê í ń ñ ŋ š ŧ ü ž ä ö",
- 4: "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",
- 5: "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 Æ Ø Å",
- },
- "nd": {
- 0: "a b c d e f g h i j k l m n o p q s t u v w x y z",
- 3: "r",
- 5: "A B C D E F G H I J K L M N O P Q S T U V W X Y Z",
- },
- "ne": {
- 0: "़ ँ ं ः ॐ अ आ इ ई उ ऊ ऋ ऌ ऍ ए ऐ ऑ ओ औ क ख ग घ ङ च छ ज झ ञ ट ठ ड ढ ण
त थ द ध न प फ ब भ म य र ल ळ व श ष स ह ऽ ा ि ी ु ू ृ ॄ ॅ े ै ॉ ो ौ ्",
- 3: "\u200c \u200d",
- },
- "nl": {
- 0: "a á ä b c d e é ë f g h i í ï ij j k l m n o ó ö p q r s t u ú ü v w
x y z",
- 2: "- ‐ – — , ; : ! ? . … ' ‘ ’ \" “ ” ( ) [ ] @ * / & # † ‡ ′ ″ §",
- 3: "å ã ç ñ ô",
- 4: "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",
- },
- "nmg": {
- 0: "a á ă â ä ā b ɓ c d e é ĕ ê ē ǝ ǝ́ ǝ̆ ǝ̂ ǝ̄ ɛ ɛ́ ɛ̆ ɛ̂ ɛ̄ f g h i í
ĭ î ï ī j k l m n ń ŋ o ó ŏ ô ö ō ɔ ɔ́ ɔ̆ ɔ̂ ɔ̄ p r ŕ s t u ú ŭ û ū v w y",
- 3: "q x z",
- 5: "A B Ɓ C D E Ǝ Ɛ F G H I J K L M N Ŋ O Ɔ P R S T U V W Y",
- },
- "nn": {
- 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 æ ø å",
- 3: "á ǎ č ç đ è ê ń ñ ŋ š ŧ ü ž ä ö",
- 4: "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",
- 5: "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 Æ Ø Å",
- },
- "nso": {
- 0: "a b d e ê f g h i j k l m n o ô p r s š t u w x y",
- 3: "c q v z",
- 4: "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",
- },
- "nus": {
- 0: "a ä a̱ b c d e ë e̱ ɛ ɛ̈ ɛ̱ ɛ̱̈ f g ɣ h i ï i̱ j k l m n ŋ o ö o̱ ɔ
ɔ̈ ɔ̱ p q r s t u v w x y z",
- 5: "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",
- },
- "nyn": {
- 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",
- 5: "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",
- },
- "om": {
- 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",
- 5: "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",
- },
- "or": {
- 0: "଼ ଅ ଆ ଇ ଈ ଉ ଊ ଋ ଏ ଐ ଓ ଔ ଁ ଂ ଃ କ ଖ ଗ ଘ ଙ ଚ ଛ ଜ ଝ ଞ ଟ ଠ ଡ ଡ଼ ଢ ଢ଼ ଣ ତ
ଥ ଦ ଧ ନ ପ ଫ ବ ଭ ମ ଯ ୟ ର ଲ ଳ ଵ ୱ ଶ ଷ ସ ହ ା ି ୀ ୁ ୂ ୃ େ ୈ ୋ ୌ ୍",
- 3: "\u200c \u200d",
- },
- "pa": {
- 0: "ੱ ੰ ਼ ੦ ੧ ੨ ੩ ੪ ੫ ੬ ੭ ੮ ੯ ੴ ੳ ਉ ਊ ਓ ਅ ਆ ਐ ਔ ੲ ਇ ਈ ਏ ਸ ਸ਼ ਹ ਕ ਖ ਖ਼ ਗ
ਗ਼ ਘ ਙ ਚ ਛ ਜ ਜ਼ ਝ ਞ ਟ ਠ ਡ ਢ ਣ ਤ ਥ ਦ ਧ ਨ ਪ ਫ ਫ਼ ਬ ਭ ਮ ਯ ਰ ਲ ਵ ੜ ੍ ਾ ਿ ੀ ੁ ੂ
ੇ ੈ ੋ ੌ",
- 3: "\u200c \u200d ਃ ਂ ਁ ਲ਼",
- },
- "pa_Arab": {
- 0: "ُ ء آ ؤ ئ ا ب پ ت ث ٹ ج چ ح خ د ذ ڈ ر ز ڑ ژ س ش ص ض ط ظ ع غ ف ق ک گ
ل م ن ں ه ھ ہ و ی ے",
- 3: "أ ٻ ة ٺ ټ ٽ",
- },
- "pl": {
- 0: "a ą b c ć d e ę f g h i j k l ł m n ń o ó p r s ś t u w y z ź ż",
- 3: "q v x",
- 4: "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",
- },
- "ps": {
- 0: "َ ِ ُ ً ٍ ٌ ّ ْ ٔ ٰ آ ا أ ء ب پ ت ټ ث ج ځ چ څ ح خ د ډ ذ ر ړ ز ژ ږ س
ش ښ ص ض ط ظ ع غ ف ق ک ګ ل م ن ڼ ه ة و ؤ ی ي ې ۍ ئ",
- 3: "\u200c \u200d",
- },
- "pt": {
- 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",
- 3: "ă å ä ā æ è ĕ ë ē ì ĭ î ï ī ñ ŏ ö ø ō œ ù ŭ û ü ū ÿ",
- 4: "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",
- 5: "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",
- },
- "pt_PT": {
- 3: "ª ă å ä ā æ è ĕ ë ē ì ĭ î ï ī ñ º ŏ ö ø ō œ ù ŭ û ü ū ÿ",
- },
- "rn": {
- 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",
- 5: "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",
- },
- "ro": {
- 0: "a ă â b c d e f g h i î j k l m n o p r s ș t ț u v x z",
- 3: "á à å ä ç é è ê ë ñ ö q ş ţ ü w y",
- 4: "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",
- 5: "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",
- },
- "rof": {
- 0: "a b c d e f g h i j k l m n o p r s t u v w y z",
- 3: "q x",
- 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z",
- },
- "root": {
- 2: "- , ; : ! ? . ( ) [ ] { }",
- 4: "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",
- },
- "ru": {
- 0: "а б в г д е ё ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я",
- 2: "- ‐ – — , ; : ! ? . … ' ‘ ‚ \" “ „ « » ( ) [ ] { } @ * / & # §",
- 4: "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",
- 5: "А Б В Г Д Е Ё Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ы Э Ю Я",
- },
- "rw": {
- 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",
- 5: "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",
- },
- "rwk": {
- 0: "a b c d e f g h i j k l m n o p r s t u v w y z",
- 3: "q x",
- 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z",
- },
- "sah": {
- 0: "а б г ҕ д дь и й к л м н нь ҥ о ө п р с т у ү х һ ч ы э",
- 3: "в е ё ж з ф ц ш щ ъ ь ю я",
- 5: "А Б Г Ҕ Д Дь И Й К Л М Н Нь Ҥ О Ө П Р С Т У Ү Х Һ Ч Ы Э",
- },
- "saq": {
- 0: "a b c d e g h i j k l m n o p r s t u v w y",
- 3: "f q x z",
- 5: "A B C D E G H I J K L M N O P R S T U V W Y",
- },
- "sbp": {
- 0: "a b c d e f g h i j k l m n o p s t u v w y",
- 3: "q r x z",
- 5: "A B C D E F G H I J K L M N O P S T U V W Y",
- },
- "se": {
- 0: "a á b c č d đ e f g h i j k l m n ŋ o p r s š t ŧ u v z ž",
- 3: "à å ä ã æ ç é è í ń ñ ó ò ö ø q ú ü w x y",
- },
- "seh": {
- 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",
- 5: "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",
- },
- "ses": {
- 0: "a ã b c d e ẽ f g h i j k l m n ɲ ŋ o õ p q r s š t u w x y z ž",
- 3: "v",
- 5: "A Ã B C D E Ẽ F G H I J K L M N Ɲ Ŋ O Õ P Q R S Š T U W X Y Z Ž",
- },
- "sg": {
- 0: "a â ä b d e ê ë f g h i î ï j k l m n o ô ö p r s t u ù û ü v w y z",
- 3: "c q x",
- 5: "A B D E F G H I J K L M N O P R S T U V W Y Z",
- },
- "shi": {
- 0: "a b c d ḍ e ɛ f g gʷ ɣ h ḥ i j k kʷ l m n q r ṛ s ṣ t ṭ u w x y z",
- 3: "o p v",
- 5: "A B C D Ḍ E Ɛ F G Gʷ Ɣ H Ḥ I J K Kʷ L M N Q R Ṛ S Ṣ T Ṭ U W X Y Z",
- },
- "shi_Tfng": {
- 0: "ⴰ ⴱ ⴳ ⴳⵯ ⴷ ⴹ ⴻ ⴼ ⴽ ⴽⵯ ⵀ ⵃ ⵄ ⵅ ⵇ ⵉ ⵊ ⵍ ⵎ ⵏ ⵓ ⵔ ⵕ ⵖ ⵙ ⵚ ⵛ ⵜ ⵟ ⵡ ⵢ ⵣ ⵥ",
- 5: "ⴰ ⴱ ⴳ ⴷ ⴹ ⴻ ⴼ ⴽ ⵀ ⵃ ⵄ ⵅ ⵇ ⵉ ⵊ ⵍ ⵎ ⵏ ⵓ ⵔ ⵕ ⵖ ⵙ ⵚ ⵛ ⵜ ⵟ ⵡ ⵢ ⵣ ⵥ",
- },
- "si": {
- 0: "අ ආ ඇ ඈ ඉ ඊ උ ඌ ඍ එ ඒ ඓ ඔ ඕ ඖ ං ඃ ක ඛ ග ඝ ඞ ඟ ච ඡ ජ ඣ ඥ ඤ ට ඨ ඩ ඪ ණ
ඬ ත ථ ද ධ න ඳ ප ඵ බ භ ම ඹ ය ර ල ව ශ ෂ ස හ ළ ෆ ා ැ ෑ ි ී ු ූ ෘ ෲ ෟ ෙ ේ ෛ ො ෝ
ෞ ්",
- 3: "\u200b \u200c \u200d ඎ ඏ ඐ ඦ ෳ",
- 4: "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",
- 5: "අ ආ ඇ ඈ ඉ ඊ උ ඌ ඍ එ ඒ ඓ ඔ ඕ ඖ ක ඛ ග ඝ ඞ ඟ ච ඡ ජ ඣ ඥ ඤ ට ඨ ඩ ඪ ණ ඬ ත
ථ ද ධ න ඳ ප ඵ බ භ ම ඹ ය ර ල ව ශ ෂ ස හ ළ ෆ",
- },
- "sk": {
- 0: "a á ä b c č d ď e é f g h ch i í j k l ĺ ľ m n ň o ó ô p q r ŕ s š t
ť u ú v w x y ý z ž",
- },
- "sl": {
- 0: "a b c č d e f g h i j k l m n o p r s š t u v z ž",
- 3: "á à ă â å ä ā æ ç ć đ é è ĕ ê ë ē í ì ĭ î ï ī ñ ó ò ŏ ô ö ø ō œ q ú
ù ŭ û ü ū w x y ÿ",
- 4: "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",
- 5: "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 Ž",
- },
- "sn": {
- 0: "a b c d e f g h i j k l m n o p r s t u v w y z",
- 3: "q x",
- 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z",
- },
- "so": {
- 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",
- },
- "sq": {
- 0: "a b c ç d dh e ë f g gj h i j k l ll m n nj o p q r rr s sh t th u v
x xh y z zh",
- 3: "w",
- },
- "sr": {
- 0: "а б в г д ђ е ж з и ј к л љ м н њ о п р с т ћ у ф х ц ч џ ш",
- 4: "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",
- },
- "sr_Latn": {
- 0: "a b c č ć d dž đ e f g h i j k l lj m n nj o p r s š t u v z ž",
- 3: "q w x y",
- },
- "ss": {
- 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",
- },
- "st": {
- 0: "a b d e f g h i j k l m n o p q r s t u w y",
- 3: "c v x z",
- 4: "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",
- },
- "sv": {
- 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 å ä ö",
- 2: "- ‐ – — , ; : ! ? . … ' ‘ ’ \" “ ” ( ) [ ] @ * / & # † ‡ ′ ″ §",
- 3: "á â ã ā ç ë í î ï ī ñ ó ú ÿ ü æ ø",
- 4: "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",
- 5: "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 Å Ä Ö",
- },
- "sv_FI": {
- 3: "ã ç ë í ñ ó š ÿ ü ž",
- },
- "sw": {
- 0: "a b ch d e f g h i j k l m n o p r s t u v w y z",
- 3: "c q x",
- 4: "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",
- },
- "swc": {
- 0: "a b c d e f g h i j k l m n o p r s t u v w y z",
- 3: "q x",
- 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z",
- },
- "ta": {
- 0: "அ ஆ இ ஈ உ ஊ எ ஏ ஐ ஒ ஓ ஔ ஃ க ங ச ஞ ட ண த ந ப ம ய ர ல வ ழ ள ற ன ஜ ஷ ஸ
ஹ ா ி ீ ு ூ ெ ே ை ொ ோ ௌ ்",
- 4: "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",
- },
- "te": {
- 0: "అ ఆ ఇ ఈ ఉ ఊ ఋ ౠ ఌ ౡ ఎ ఏ ఐ ఒ ఓ ఔ ఁ ం ః క ఖ గ ఘ ఙ చ ఛ జ ఝ ఞ ట ఠ డ ఢ ణ
త థ ద ధ న ప ఫ బ భ మ య ర ఱ ల వ శ ష స హ ళ ా ి ీ ు ూ ృ ౄ ె ే ై ొ ో ౌ ్ ౕ ౖ",
- 3: "\u200c \u200d ౦ ౧ ౨ ౩ ౪ ౫ ౬ ౭ ౮ ౯",
- 5: "అ ఆ ఇ ఈ ఉ ఊ ఋ ౠ ఎ ఏ ఐ ఒ ఓ ఔ క ఖ గ ఘ ఙ చ ఛ జ ఝ ఞ ట ఠ డ ఢ ణ త థ ద ధ న
ప ఫ బ భ మ య ర ఱ ల వ శ ష స హ ళ",
- },
- "teo": {
- 0: "a b c d e g h i j k l m n o p r s t u v w x y",
- 3: "f q z",
- 5: "A B C D E G H I J K L M N O P R S T U V W X Y",
- },
- "tg": {
- 0: "а б в г ғ д е ё ж з и ӣ й к қ л м н о п р с т у ӯ ф х ҳ ч ҷ ш ъ э ю
я",
- 3: "ц щ ы ь",
- },
- "th": {
- 0: "๎ ์ ็ ่ ้ ๊ ๋ ฯ ๆ ก ข ฃ ค ฅ ฆ ง จ ฉ ช ซ ฌ ญ ฎ ฏ ฐ ฑ ฒ ณ ด ต ถ ท ธ น
บ ป ผ ฝ พ ฟ ภ ม ย ร ฤ ล ฦ ว ศ ษ ส ห ฬ อ ฮ ํ ะ ั า ๅ ำ ิ ี ึ ื ุ ู เ แ โ ใ ไ
ฺ",
- 3: "\u200b",
- 4: "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",
- },
- "ti": {
- 0: "፟ ሀ ሀ ሁ ሂ ሃ ሄ ህ ሆ ለ ለ ሉ ሊ ላ ሌ ል ሎ ሏ ሐ ሑ ሒ ሓ ሔ ሕ ሖ ሗ መ ሙ ሚ ማ ሜ ም ሞ ሟ
ሠ ሡ ሢ ሣ ሤ ሥ ሦ ሧ ረ ሩ ሪ ራ ሬ ር ሮ ሯ ሰ ሱ ሲ ሳ ሴ ስ ሶ ሷ ሸ ሹ ሺ ሻ ሼ ሽ ሾ ሿ ቀ ቁ ቂ ቃ ቄ ቅ
ቆ ቈ ቊ ቊ ቋ ቌ ቍ ቐ ቐ ቑ ቒ ቓ ቔ ቕ ቖ ቘ ቚ ቚ ቛ ቜ ቝ በ በ ቡ ቢ ባ ቤ ብ ቦ ቧ ቨ ቩ ቪ ቫ ቬ ቭ ቮ ቯ
ተ ቱ ቲ ታ ቴ ት ቶ ቷ ቸ ቹ ቺ ቻ ቼ ች ቾ ቿ ኀ ኁ ኂ ኃ ኄ ኅ ኆ ኈ ኊ ኊ ኋ ኌ ኍ ነ ነ ኑ ኒ ና ኔ ን ኖ ኗ
ኘ ኙ ኚ ኛ ኜ ኝ ኞ ኟ አ ኡ ኢ ኣ ኤ እ ኦ ኧ ከ ኩ ኪ ካ ኬ ክ ኮ ኰ ኲ ኲ ኳ ኴ ኵ ኸ ኸ ኹ ኺ ኻ ኼ ኽ ኾ ዀ
ዂ ዂ ዃ ዄ ዅ ወ ወ ዉ ዊ ዋ ዌ ው ዎ ዐ ዐ ዑ ዒ ዓ ዔ ዕ ዖ ዘ ዘ ዙ ዚ ዛ ዜ ዝ ዞ ዟ ዠ ዡ ዢ ዣ ዤ ዥ ዦ ዧ
የ ዩ ዪ ያ ዬ ይ ዮ ደ ደ ዱ ዲ ዳ ዴ ድ ዶ ዷ ጀ ጀ ጁ ጂ ጃ ጄ ጅ ጆ ጇ ገ ጉ ጊ ጋ ጌ ግ ጎ ጐ ጒ ጒ ጓ ጔ ጕ
ጠ ጠ ጡ ጢ ጣ ጤ ጥ ጦ ጧ ጨ ጩ ጪ ጫ ጬ ጭ ጮ ጯ ጰ ጱ ጲ ጳ ጴ ጵ ጶ ጷ ጸ ጹ ጺ ጻ ጼ ጽ ጾ ጿ ፀ ፁ ፂ ፃ ፄ
ፅ ፆ ፇ ፈ ፉ ፊ ፋ ፌ ፍ ፎ ፏ ፐ ፑ ፒ ፓ ፔ ፕ ፖ ፗ",
- 3: "᎐ ᎐ ᎑ ᎒ ᎓ ᎔ ᎕ ᎖ ᎗ ᎘ ᎙ ሇ ⶀ ᎀ ᎀ ᎁ ᎂ ᎃ ⶁ ⶁ ⶂ ⶃ ⶄ ቇ ᎄ ᎄ ᎅ ᎆ ᎇ ⶅ ⶅ ⶆ ⶇ ኇ
ⶈ ⶈ ⶉ ⶊ ኯ ዏ ⶋ ዯ ⶌ ዸ ዸ ዹ ዺ ዻ ዼ ዽ ዾ ዿ ⶍ ⶎ ጏ ጘ ጘ ጙ ጚ ጛ ጜ ጝ ጞ ጟ ⶓ ⶓ ⶔ ⶕ ⶖ ⶏ ⶏ ⶐ
ⶑ ፇ ᎈ ᎈ ᎉ ᎊ ᎋ ᎌ ᎍ ᎎ ᎏ ⶒ ፘ ፘ ፙ ፚ ⶠ ⶠ ⶡ ⶢ ⶣ ⶤ ⶥ ⶦ ⶨ ⶨ ⶩ ⶪ ⶫ ⶬ ⶭ ⶮ ⶰ ⶰ ⶱ ⶲ ⶳ ⶴ
ⶵ ⶶ ⶸ ⶸ ⶹ ⶺ ⶻ ⶼ ⶽ ⶾ ⷀ ⷀ ⷁ ⷂ ⷃ ⷄ ⷅ ⷆ ⷈ ⷈ ⷉ ⷊ ⷋ ⷌ ⷍ ⷎ ⷐ ⷐ ⷑ ⷒ ⷓ ⷔ ⷕ ⷖ ⷘ ⷘ ⷙ ⷚ
ⷛ ⷜ ⷝ ⷞ",
- 5: "ሀ ለ ሐ መ ሠ ረ ሰ ሸ ቀ ቈ ቐ ቘ በ ቨ ተ ቸ ኀ ኈ ነ ኘ አ ከ ኰ ኸ ዀ ወ ዐ ዘ ዠ የ ደ ጀ ገ ጐ
ጠ ጨ ጰ ጸ ፀ ፈ ፐ",
- },
- "tn": {
- 0: "a b d e ê f g h i j k l m n o ô p r s t u w y",
- 3: "c q v x z",
- 4: "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",
- },
- "to": {
- 0: "a ā e ē f h ʻ i ī k l m n ng o ō p s t u ū v",
- 3: "à ă â å ä æ b c ç d è ĕ ê ë g ì ĭ î ï j ñ ò ŏ ô ö ø œ q r ù ŭ û ü w
x y ÿ z",
- 4: "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",
- 5: "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",
- },
- "tr": {
- 0: "a b c ç d e f g ğ h ı i i̇ j k l m n o ö p r s ş t u ü v y z",
- 2: "- ‐ – — , ; : ! ? . … ' ‘ ’ \" “ ” ( ) [ ] @ * / & # † ‡ ′ ″ §",
- 3: "á à ă â å ä ā æ é è ĕ ê ë ē í ì ĭ î ï ī ñ ó ò ŏ ô ø ō œ q ú ù ŭ û ū
w x ÿ",
- 4: "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",
- 5: "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",
- },
- "ts": {
- 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",
- },
- "twq": {
- 0: "a ã b c d e ẽ f g h i j k l m n ŋ ɲ o õ p q r s š t u w x y z ž",
- 3: "v",
- },
- "tzm": {
- 0: "a b c d ḍ e ɛ f g gʷ ɣ h ḥ i j k kʷ l m n q r ṛ s ṣ t ṭ u w x y z",
- 3: "o p v",
- 5: "A B C D Ḍ E Ɛ F G Ɣ H Ḥ I J K L M N Q R Ṛ S Ṣ T Ṭ U W X Y Z",
- },
- "uk": {
- 0: "ʼ а б в г ґ д е є ж з и і ї й к л м н о п р с т у ф х ц ч ш щ ю я ь",
- 4: "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",
- 5: "А Б В Г Ґ Д Е Є Ж З И І Ї Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ю Я",
- },
- "ur": {
- 0: "ا أ آ ب پ ت ٹ ث ج چ ح خ د ڈ ذ ر ڑ ز ژ س ش ص ض ط ظ ع غ ف ق ک گ ل م ن
ں و ؤ ہ ھ ء ی ئ ے ٻ ة ٺ ټ ٽ ه ي",
- },
- "uz": {
- 0: "а б в г ғ д е ё ж з и й к қ л м н о п р с т у ў ф х ҳ ч ш ъ э ю я",
- 3: "ц щ ы ь",
- },
- "uz_Arab": {
- 0: "ً ٌ ٍ َ ُ ِ ّ ْ ٔ ٰ ء آ أ ؤ ئ ا ب پ ة ت ث ټ ج چ ح خ ځ څ د ذ ډ ر ز ړ
ږ ژ س ش ښ ص ض ط ظ ع غ ف ق ک ګ گ ل م ن ڼ ه و ۇ ۉ ي ی ۍ ې",
- 3: "\u200c \u200d",
- },
- "uz_Latn": {
- 0: "a aʼ b ch d e eʼ f g gʼ h i iʼ j k l m n o oʼ p q r s sh t u uʼ v x
y z",
- 3: "c w",
- 5: "A B CH D E F G Gʼ H I J K L M N O Oʼ P Q R S SH T U V X Y Z",
- },
- "vai": {
- 0: "꘠ ꘠ ꘡ ꘢ ꘣ ꘤ ꘥ ꘦ ꘧ ꘨ ꘩ ꔀ ꔀ ꔁ ꔂ ꔃ ꔄ ꔅ ꔆ ꔇ ꔈ ꔉ ꔊ ꔋ ꔌ ꘓ ꔍ ꔍ ꔎ ꔏ ꔐ ꔑ ꔒ ꔓ
ꔔ ꔕ ꔖ ꔗ ꔘ ꔙ ꔚ ꔛ ꔜ ꔝ ꔞ ꘔ ꔟ ꔟ ꔠ ꔡ ꔢ ꔣ ꔤ ꔥ ꔦ ꔧ ꔨ ꔩ ꔪ ꔫ ꔬ ꔭ ꔮ ꔯ ꔰ ꔱ ꔲ ꔳ ꘕ ꔴ ꔴ ꔵ
ꔶ ꔷ ꔸ ꔹ ꔺ ꔻ ꔼ ꔽ ꔾ ꔿ ꕀ ꕁ ꕂ ꕃ ꕄ ꕅ ꕆ ꕇ ꘖ ꕈ ꕈ ꕉ ꕊ ꕋ ꕌ ꕍ ꕎ ꕏ ꕐ ꕑ ꕒ ꘗ ꕓ ꕓ ꕔ ꕕ ꕖ ꕗ
ꕘ ꘐ ꘘ ꕙ ꕚ ꘙ ꕛ ꕛ ꕜ ꕝ ꕞ ꕟ ꕠ ꘚ ꕡ ꕡ ꕢ ꕣ ꕤ ꕥ ꕦ ꕧ ꕨ ꕩ ꕪ ꘑ ꕫ ꕫ ꕬ ꕭ ꕮ ꘪ ꕯ ꕯ ꕰ ꕱ ꕲ ꕳ
ꕴ ꕵ ꕶ ꕷ ꕸ ꕹ ꕺ ꕻ ꕼ ꕽ ꕾ ꕿ ꖀ ꖁ ꖂ ꖃ ꖄ ꖅ ꘛ ꖆ ꖇ ꘒ ꖈ ꖈ ꖉ ꖊ ꖋ ꖌ ꖍ ꖎ ꖏ ꖐ ꖑ ꖒ ꖓ ꖔ ꖕ ꖖ
ꖗ ꖘ ꖙ ꖚ ꖛ ꖜ ꖝ ꖞ ꖟ ꖠ ꖡ ꖢ ꖣ ꖤ ꖥ ꖦ ꖧ ꖨ ꖩ ꖪ ꖫ ꖬ ꖭ ꖮ ꖯ ꖰ ꖱ ꖲ ꖳ ꖴ ꘜ ꖵ ꖵ ꖶ ꖷ ꖸ ꖹ ꖺ
ꖻ ꖼ ꖽ ꖾ ꖿ ꗀ ꗁ ꗂ ꗃ ꗄ ꗅ ꗆ ꗇ ꗈ ꗉ ꗊ ꗋ ꘝ ꗌ ꗌ ꗍ ꗎ ꗏ ꗐ ꗑ ꘫ ꘞ ꗒ ꗒ ꗓ ꗔ ꗕ ꗖ ꗗ ꗘ ꘟ ꗙ ꗙ
ꗚ ꗛ ꗜ ꗝ ꗞ ꗟ ꗠ ꗡ ꗢ ꗣ ꗤ ꗥ ꗦ ꗧ ꗨ ꗩ ꗪ ꗫ ꗬ ꗭ ꗮ ꗯ ꗰ ꗱ ꗲ ꗳ ꗴ ꗵ ꗶ ꗷ ꗸ ꗹ ꗺ ꗻ ꗼ ꗽ ꗾ ꗿ
ꘀ ꘁ ꘂ ꘃ ꘄ ꘅ ꘆ ꘇ ꘈ ꘉ ꘊ ꘋ ꘌ",
- },
- "vai_Latn": {
- 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",
- 5: "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",
- },
- "ve": {
- 0: "a b d ḓ e f g h i k l ḽ m n ṅ ṋ o p r s t ṱ u v w x y z",
- },
- "vi": {
- 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",
- 4: "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",
- },
- "vun": {
- 0: "a b c d e f g h i j k l m n o p r s t u v w y z",
- 3: "q x",
- 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z",
- },
- "wae": {
- 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",
- 3: "à ă â å ā æ ç è ĕ ê ë ē ì ĭ î ï ī ñ ò ŏ ô ø ō œ ß ù ŭ û ū ÿ",
- 5: "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",
- },
- "wal": {
- 0: "፟ ᎐ ᎐ ᎑ ᎒ ᎓ ᎔ ᎕ ᎖ ᎗ ᎘ ᎙ ሀ ሀ ሁ ሂ ሃ ሄ ህ ሆ ሇ ለ ሉ ሊ ላ ሌ ል ሎ ሏ ⶀ ሐ ሐ ሑ ሒ
ሓ ሔ ሕ ሖ ሗ መ ሙ ሚ ማ ሜ ም ሞ ሟ ᎀ ᎀ ᎁ ᎂ ᎃ ⶁ ሠ ሠ ሡ ሢ ሣ ሤ ሥ ሦ ሧ ረ ሩ ሪ ራ ሬ ር ሮ ሯ ⶂ ሰ
ሰ ሱ ሲ ሳ ሴ ስ ሶ ሷ ⶃ ሸ ሸ ሹ ሺ ሻ ሼ ሽ ሾ ሿ ⶄ ቀ ቀ ቁ ቂ ቃ ቄ ቅ ቆ ቇ ቈ ቊ ቊ ቋ ቌ ቍ ቐ ቐ ቑ ቒ
ቓ ቔ ቕ ቖ ቘ ቚ ቚ ቛ ቜ ቝ በ በ ቡ ቢ ባ ቤ ብ ቦ ቧ ᎄ ᎄ ᎅ ᎆ ᎇ ⶅ ቨ ቨ ቩ ቪ ቫ ቬ ቭ ቮ ቯ ተ ቱ ቲ ታ
ቴ ት ቶ ቷ ⶆ ቸ ቸ ቹ ቺ ቻ ቼ ች ቾ ቿ ⶇ ኀ ኀ ኁ ኂ ኃ ኄ ኅ ኆ ኇ ኈ ኊ ኊ ኋ ኌ ኍ ነ ነ ኑ ኒ ና ኔ ን ኖ
ኗ ⶈ ኘ ኘ ኙ ኚ ኛ ኜ ኝ ኞ ኟ ⶉ አ አ ኡ ኢ ኣ ኤ እ ኦ ኧ ⶊ ከ ከ ኩ ኪ ካ ኬ ክ ኮ ኯ ኰ ኲ ኲ ኳ ኴ ኵ ኸ
ኸ ኹ ኺ ኻ ኼ ኽ ኾ ዀ ዂ ዂ ዃ ዄ ዅ ወ ወ ዉ ዊ ዋ ዌ ው ዎ ዏ ዐ ዑ ዒ ዓ ዔ ዕ ዖ ዘ ዘ ዙ ዚ ዛ ዜ ዝ ዞ ዟ
ⶋ ዠ ዠ ዡ ዢ ዣ ዤ ዥ ዦ ዧ የ ዩ ዪ ያ ዬ ይ ዮ ዯ ደ ዱ ዲ ዳ ዴ ድ ዶ ዷ ⶌ ዸ ዸ ዹ ዺ ዻ ዼ ዽ ዾ ዿ ⶍ ጀ
ጀ ጁ ጂ ጃ ጄ ጅ ጆ ጇ ⶎ ገ ገ ጉ ጊ ጋ ጌ ግ ጎ ጏ ጐ ጒ ጒ ጓ ጔ ጕ ጘ ጘ ጙ ጚ ጛ ጜ ጝ ጞ ጟ ⶓ ⶓ ⶔ ⶕ ⶖ
ጠ ጠ ጡ ጢ ጣ ጤ ጥ ጦ ጧ ⶏ ጨ ጨ ጩ ጪ ጫ ጬ ጭ ጮ ጯ ⶐ ጰ ጰ ጱ ጲ ጳ ጴ ጵ ጶ ጷ ⶑ ጸ ጸ ጹ ጺ ጻ ጼ ጽ ጾ
ጿ ፀ ፁ ፂ ፃ ፄ ፅ ፆ ፇ ፈ ፉ ፊ ፋ ፌ ፍ ፎ ፏ ᎈ ᎈ ᎉ ᎊ ᎋ ፐ ፐ ፑ ፒ ፓ ፔ ፕ ፖ ፗ ᎌ ᎌ ᎍ ᎎ ᎏ ⶒ ፘ
ፘ ፙ ፚ ⶠ ⶠ ⶡ ⶢ ⶣ ⶤ ⶥ ⶦ ⶨ ⶨ ⶩ ⶪ ⶫ ⶬ ⶭ ⶮ ⶰ ⶰ ⶱ ⶲ ⶳ ⶴ ⶵ ⶶ ⶸ ⶸ ⶹ ⶺ ⶻ ⶼ ⶽ ⶾ ⷀ ⷀ ⷁ
ⷂ ⷃ ⷄ ⷅ ⷆ ⷈ ⷈ ⷉ ⷊ ⷋ ⷌ ⷍ ⷎ ⷐ ⷐ ⷑ ⷒ ⷓ ⷔ ⷕ ⷖ ⷘ ⷘ ⷙ ⷚ ⷛ ⷜ ⷝ ⷞ",
- },
- "xh": {
- 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",
- 4: "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",
- },
- "xog": {
- 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",
- 5: "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",
- },
- "yav": {
- 0: "a á à â ǎ ā b c d e é è ɛ ɛ́ ɛ̀ f h i í ì î ī k l m mb n ny ŋ ŋg o ó
ò ô ǒ ō ɔ ɔ́ ɔ̀ p s t u ú ù û ǔ ū v w y",
- 3: "g j q r x z",
- 5: "A B C D E Ɛ F H I K L M N Ŋ O Ɔ P S T U V W Y",
- },
- "yo": {
- 0: "a á à b d e é è ẹ ẹ́ ẹ̀ f g gb h i í ì j k l m n o ó ò ọ ọ́ ọ̀ p r s
ṣ t u ú ù w y",
- 3: "c q v x z",
- 5: "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",
- },
- "zh": {
- 0: "一 丁 七 万 万 丈 三 上 下 丌 不 与 专 且 世 丘 丘 丙 业 东 丝 丢 两
严 丧 个 中 丰 串 临 丸 丸 丹 为 主 丽 举 乃 久 么 义 之 之 乌 乍 乎 乏 乐
乔 乖 乘 乙 九 也 也 习 乡 书 买 乱 乾 了 予 争 事 二 于 亏 云 互 五 井 亚
些 亡 交 亦 亨 享 京 亮 亲 人 亿 亿 什 仁 仅 仇 今 介 仍 从 仔 他 付 仙 代
代 令 以 仪 们 仰 仲 件 任 份 仿 企 伊 伍 伏 伏 伐 休 众 伙 会 伟 传 伤 伦
伯 估 伴 伸 似 伽 但 位 位 低 住 佐 佑 体 何 余 佛 作 你 佤 佩 佳 使 例 供
依 侠 侦 侦 侧 侨 侬 侯 侵 便 促 俄 俊 俗 保 信 俩 修 俱 俾 倍 倒 候 倚 借
倦 值 倾 假 偌 偏 做 停 健 偶 偷 储 催 傲 傻 像 僧 儒 允 元 元 兄 充 先 光
克 免 兑 兔 入 全 八 八 公 六 兮 兰 共 关 关 兴 兵 其 具 典 兹 养 养 兼 兽
内 冈 再 冒 写 军 农 冠 冬 冰 冲 冷 准 凌 凝 几 凡 凤 凭 凯 凰 出 击 函 刀
分 切 刊 刑 划 列 列 刘 则 刚 创 初 判 利 别 到 制 制 刷 券 刺 刻 剂 前 剑
剧 剩 剪 副 割 力 劝 劝 办 功 加 务 劣 动 动 助 努 劫 励 励 劲 劳 势 勇 勉
勋 勒 勤 勾 勿 包 匆 匈 化 北 匙 匹 匹 区 医 十 千 升 午 半 华 协 卒 卓 单
单 卖 南 博 占 占 卡 卢 卫 印 危 即 卷 厄 厄 厅 历 厉 压 压 厌 厍 厚 原 去
县 参 又 又 叉 及 友 双 反 发 叔 取 取 受 变 叙 口 口 古 句 另 叫 叫 召 叭
可 台 史 右 叶 叶 号 司 叹 吃 各 合 合 吉 吊 同 同 名 后 吐 向 吓 吗 君 吝
吟 否 吧 含 吵 吸 吹 吻 吾 呀 呆 呈 告 呐 员 呜 呢 呦 周 味 呵 呼 命 和 咖
咦 咧 咪 咬 咯 咱 哀 品 哇 哇 哈 哉 响 哎 哟 哥 哦 哩 哪 哭 哲 唉 唐 唤 唬
售 唯 唱 唷 商 啊 啡 啥 啦 啪 喀 喂 善 喇 喊 喏 喔 喜 喝 喵 喷 喻 嗒 嗨 嗯
嘉 嘛 嘴 嘻 嘿 器 四 回 因 团 园 困 围 固 国 图 圆 圈 土 圣 在 圭 地 场 圾
址 均 坎 坐 坑 块 坚 坚 坛 坜 坡 坤 坦 坪 垂 垃 型 垒 埃 埋 城 埔 域 培 基
堂 堆 堕 堡 堪 塑 塔 塞 填 境 增 墨 壁 壤 士 壮 声 处 备 复 夏 夕 外 多 夜
夥 大 天 天 太 夫 央 失 头 夷 夷 夸 夹 夺 奇 奇 奈 奉 奋 奏 契 奔 套 奥 女
奴 奶 她 好 如 妇 妈 妖 妙 妥 妨 妮 妹 妻 姆 姊 始 姐 姑 姓 委 姿 威 娃 娄
娘 娜 娟 婆 婚 媒 嫁 嫌 嫩 子 孔 孕 字 字 存 孙 孜 孝 孟 季 孤 学 孩 宁 它
宇 宇 守 安 宋 完 宏 宗 宗 官 宙 定 宛 宜 宝 实 审 审 客 宣 室 宪 害 宴 家
容 宽 宽 宾 宿 寂 寄 密 寇 富 寒 寝 寝 寞 察 寡 寨 寸 对 寻 导 寿 封 射 将
尊 小 少 尔 尖 尘 尚 尝 尤 就 尺 尼 尼 尽 尾 局 局 屁 层 居 屋 屏 展 属 屠
山 岁 岂 岗 岘 岚 岛 岳 岸 峡 峰 崇 崩 崴 川 州 巡 工 工 左 巧 巨 巫 差 己
已 巴 巷 币 币 市 布 帅 师 希 帐 帕 帝 带 席 帮 常 帽 幅 幕 干 干 平 年 幸
幻 幻 幼 幽 广 庆 床 序 库 库 应 底 店 庙 府 庞 废 度 座 庭 康 庸 廉 廖 延
廷 建 开 弃 弄 弊 式 引 弗 弘 弟 张 弥 弦 弯 弱 弹 归 当 彝 形 彩 彬 彭 彰
影 彷 役 彻 彼 往 征 径 待 很 律 後 徐 徒 得 循 微 徵 德 心 必 忆 忌 忍 志
志 忘 忙 忠 忧 快 念 忽 怀 态 怎 怒 怕 怖 思 怡 急 性 怨 怪 总 恋 恐 恢 恨
恩 恭 息 恰 恶 恼 悄 悉 悔 悟 悠 患 您 悲 情 惑 惜 惠 惧 惨 惯 想 惹 愁 愈
愉 意 愚 感 愧 慈 慎 慕 慢 慧 慰 憾 懂 懒 戈 戏 戏 成 我 戒 或 战 截 戴 房
房 所 扁 扇 手 才 扎 扑 打 托 扣 执 扩 扫 扫 扬 扭 扮 扯 批 找 找 承 技 抄
把 抑 抓 投 抗 折 抢 护 报 披 抬 抱 抵 抹 抽 担 拆 拉 拍 拒 拔 拖 拘 招 拜
拟 拥 拦 拨 择 括 拳 拷 拼 拾 拿 持 指 按 挑 挖 挝 挡 挤 挥 挪 振 挺 捉 捐
捕 损 捡 换 捷 授 掉 掌 排 探 接 控 控 推 掩 措 掸 描 提 插 握 援 搜 搞 搬
搭 摄 摆 摊 摔 摘 摩 摸 撒 撞 播 操 擎 擦 支 收 改 攻 放 政 故 效 敌 敏 救
教 敝 敢 散 敦 敬 数 敲 整 文 斋 斐 斗 料 斜 斥 断 斯 新 方 於 施 旁 旅 旋
族 旗 无 既 日 日 旦 旧 旨 早 旭 时 旺 昂 昆 昌 明 昏 易 星 映 春 昨 昭 是
显 晃 晋 晒 晓 晚 晨 普 景 晴 晶 智 暂 暑 暖 暗 暮 暴 曰 曲 更 曹 曼 曾 曾
替 最 月 有 朋 服 朗 望 朝 期 木 未 未 末 本 札 术 朱 朵 杀 杂 权 杉 李 材
村 杜 束 条 来 杨 杯 杰 松 板 极 析 林 果 枝 枢 枪 枫 架 柏 某 染 柔 查 柬
柯 柳 柴 标 栋 栏 树 校 样 样 核 根 格 桃 框 案 桌 桑 档 桥 梁 梅 梦 梯 械
梵 检 棉 棋 棒 棚 森 椅 植 椰 楚 楼 概 榜 模 樱 檀 欠 欠 次 欢 欣 欧 欲 欺
款 歉 歌 止 止 正 此 步 武 歪 死 殊 残 段 毅 母 每 毒 比 毕 毛 毫 氏 民 氛
水 永 求 汉 汗 汝 江 江 池 污 汤 汪 汶 汽 沃 沈 沉 沙 沟 沧 河 油 治 沿 泉
泊 法 泛 泡 泡 波 泣 泥 注 泰 泳 泽 洋 洗 洛 洞 津 洪 洲 活 洽 派 流 浅 测
济 浑 浓 浦 浩 浪 浮 浴 海 涅 消 涉 涛 涨 涯 液 涵 淋 淑 淘 淡 深 混 添 清
渐 渡 渣 温 港 渴 游 湖 湾 源 溜 溪 滋 滑 满 滥 滨 滴 漂 漏 演 漠 漫 潘 潜
潮 澎 澳 激 灌 火 灭 灯 灰 灵 灿 炉 炎 炮 炸 点 烂 烈 烤 烦 烧 热 焦 然 煌
煞 照 煮 熊 熟 燃 燕 爆 爪 爬 爱 爵 爵 父 爷 爸 爽 片 版 牌 牙 牛 牡 牢 牧
物 牲 牵 特 牺 犯 状 犹 狂 狐 狗 狠 独 狮 狱 狼 猛 猜 献 玄 率 玉 王 玛 玩
玫 环 现 玲 玻 珀 珊 珍 珠 班 球 理 琊 琪 琳 琴 琼 瑙 瑜 瑞 瑟 瑰 瑶 璃 瓜
瓦 瓶 甘 甚 甜 生 用 田 田 由 甲 申 电 男 甸 画 畅 界 留 略 番 疆 疏 疑 疗
疯 疲 疼 疾 病 痕 痛 痴 登 白 百 的 皆 皇 皮 盈 益 监 盒 盖 盘 盛 盟 目 直
相 盼 盾 省 眉 看 真 眠 眼 睛 睡 督 瞧 矛 矣 知 短 石 矶 码 砂 砍 研 破 础
硕 硬 碍 碎 碗 碟 碧 碰 磁 磅 磨 示 礼 社 祖 祝 神 祥 票 祸 禁 禅 福 秀 私
秋 种 科 秒 秘 租 秤 秦 秩 积 称 移 稀 程 稍 稣 稳 稿 穆 究 穷 穹 空 穿 突
窗 窝 立 站 竞 竞 竟 章 童 端 竹 笑 笔 笛 符 笨 第 等 筋 答 策 筹 签 简 算
管 箭 箱 篇 篮 簿 籍 米 类 粉 粒 粗 粤 粹 精 糊 糕 糖 糟 系 素 索 紧 紫 累
繁 红 约 级 纪 纯 纲 纳 纵 纷 纸 纽 练 组 细 细 织 终 绍 经 结 绕 绘 给 络
统 继 绩 绪 续 维 绵 综 缅 缓 编 缘 缠 缩 缴 缶 缸 缺 罐 罕 罗 罚 罢 罪 置
署 羊 美 羞 群 羯 羽 翁 翅 翔 翘 翠 翰 翻 翼 耀 老 考 者 而 耍 耐 耗 耳 耶
聊 职 联 聚 聪 肉 肖 肚 股 肤 肥 肩 肯 育 胁 胆 背 胎 胖 胞 胡 胶 胸 能 脆
脑 脱 脸 腊 腐 腓 腰 腹 腾 腿 臂 臣 自 臭 至 致 舌 舍 舒 舞 舟 航 般 舰 船
良 色 艺 艾 节 芒 芝 芦 芬 芭 花 芳 苍 苏 苗 若 苦 英 茂 茨 茫 茶 草 荒 荣
药 荷 莉 莎 莪 莫 莱 莲 获 菜 菩 菲 萄 萍 萤 营 萧 萨 落 著 葛 葡 蒂 蒋 蒙
蓉 蓝 蓬 蔑 蔡 薄 薪 藉 藏 藤 虎 虑 虫 虹 虽 虾 蚁 蛇 蛋 蛙 蛮 蜂 蜜 蝶 融
蟹 蠢 血 行 街 衡 衣 补 表 袋 被 袭 裁 裂 装 裕 裤 西 要 覆 见 观 规 视 览
觉 角 解 言 誉 誓 警 计 订 认 讨 让 训 训 议 讯 记 讲 讷 许 论 设 访 证 评
识 诉 词 译 试 诗 诚 话 诞 询 该 详 语 误 说 请 诸 诺 读 课 谁 调 谅 谈 谊
谋 谓 谜 谢 谨 谱 谷 豆 象 豪 貌 贝 贝 贞 负 贡 贡 财 责 贤 败 货 货 质 贩
贪 购 贯 贱 贴 贵 费 贺 贼 贾 资 赋 赌 赏 赐 赔 赖 赚 赛 赞 赠 赢 赤 赫 走
赵 起 趁 超 越 趋 趣 足 跃 跌 跑 距 跟 路 跳 踏 踢 踩 身 躲 车 轨 轩 转 轮
轮 软 轰 轻 载 较 辅 辆 辈 辉 辑 输 辛 辞 辨 辩 辱 边 达 迁 迅 过 迈 迎 运
近 返 还 这 进 进 远 违 连 迟 迦 迪 迫 述 迷 追 退 送 逃 逆 选 逊 透 逐 递
途 通 逛 逝 速 造 逢 逸 逻 逼 遇 遍 道 遗 遭 遮 遵 避 邀 邓 那 邦 邪 邮 邱
邻 郎 郑 部 郭 都 鄂 酋 配 酒 酷 酸 醉 醒 采 释 里 里 重 野 量 金 针 钓 钟
钢 钦 钱 钻 铁 铃 铢 铭 银 销 锁 锅 锋 错 锡 锦 键 锺 镇 镜 镭 长 门 闪 闭
问 间 闷 闹 闻 阁 阐 阔 队 阮 防 防 阳 阴 阵 阶 阻 阿 陀 附 附 际 陆 陈 降
限 院 除 险 陪 陵 陵 陶 陷 隆 随 隐 隔 障 难 雄 雄 雅 集 雨 雪 雯 雳 零 雷
雾 需 震 霍 霖 露 霸 霹 青 靖 静 非 靠 面 革 靼 鞋 鞑 韦 韩 音 页 顶 项 项
顺 须 顽 顽 顾 顿 预 领 颇 频 颗 题 额 风 飘 飙 飞 食 餐 饭 饮 饰 饱 饼 馆
首 香 馨 马 驱 驶 驻 驾 验 骑 骗 骚 骤 骨 高 鬼 魂 魅 魔 鱼 鲁 鲜 鸟 鸣 鸭
鸿 鹅 鹤 鹰 鹿 麦 麻 黄 黎 黑 默 鼓 鼠 鼻 齐 齿 龄 龙 龟",
- 3: "侣 傣 卑 厘 吕 堤 奎 巽 录 户 撤 楔 楠 滕 瑚 甫 盲 禄 粟 线 脚 钯 铂
锑 镑 魁",
- 5: "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",
- },
- "zh_Hant": {
- 0: "一 丁 七 丈 丈 三 上 下 丌 不 且 世 丘 丙 丟 並 中 串 丸 丹 主 乃 久
么 之 乎 乏 乖 乘 乙 九 也 乾 亂 了 予 事 二 于 云 互 五 井 些 亞 亡 交 亦
亨 享 京 亮 人 什 仁 仇 今 介 仍 仔 他 付 仙 代 代 令 以 仰 仲 件 任 份 企
伊 伍 伐 休 伙 伯 估 伴 伸 似 伽 但 佈 位 位 低 住 佔 何 余 佛 作 你 佩 佳
使 來 例 供 依 侯 侵 便 係 係 促 俄 俊 俗 保 俠 信 修 俱 俾 個 倍 們 倒 候
倚 借 倫 值 假 偉 偏 做 停 健 側 側 偵 偶 偷 傑 備 傢 傣 傲 傳 傷 傻 傾 僅
像 僑 僧 價 儀 億 儒 儘 優 允 元 元 兄 充 兇 兇 先 光 克 免 兒 兔 入 內 內
全 兩 八 八 公 六 兮 共 兵 兵 其 具 典 兼 冊 再 冒 冠 冬 冰 冷 准 凌 凝 凡
凰 凱 出 函 刀 分 切 刊 列 初 判 別 利 刪 到 制 刷 刺 刻 則 前 剛 剩 剪 副
割 創 劃 劇 劉 劍 力 功 加 助 助 努 劫 勁 勇 勉 勒 動 務 勝 勞 勢 勤 勵 勸
勿 包 匈 化 北 匹 區 十 千 升 午 半 卒 卒 卓 協 南 博 卡 印 危 即 卷 卻 厄
厘 厚 原 厭 厲 去 參 又 及 友 反 叔 取 受 口 口 古 句 另 叫 叫 召 叭 可 台
史 右 司 吃 各 合 合 吉 吊 同 同 名 后 吐 向 君 吝 吝 吞 吟 否 吧 含 吳 吵
吸 吹 吾 呀 呂 呆 告 呢 周 味 呵 呼 命 和 咖 咦 咧 咪 咬 咱 哀 品 哇 哇 哈
哉 哎 員 哥 哦 哩 哪 哭 哲 唉 唐 唬 售 唯 唱 唷 唸 商 啊 問 啟 啡 啥 啦 啪
喀 喂 善 喇 喊 喔 喜 喝 喬 單 喵 嗎 嗚 嗨 嗯 嘆 嘉 嘗 嘛 嘴 嘻 嘿 器 噴 嚇
嚴 囉 四 回 因 困 固 圈 國 圍 園 圓 圖 團 圜 土 在 圭 地 圾 址 均 坎 坐 坡
坤 坦 坪 垂 垃 型 埃 城 埔 域 執 培 基 堂 堅 堆 堡 堪 報 場 塊 塔 塗 塞 填
塵 境 增 墨 墮 壁 壓 壘 壞 壢 士 壯 壽 夏 夕 外 多 夜 夠 夢 夥 大 天 天 太
夫 央 失 夷 夸 夾 奇 奇 奈 奉 奎 奏 契 奔 套 奧 奪 奮 女 奴 奶 她 好 如 妙
妥 妨 妮 妳 妹 妻 姆 姊 始 姐 姑 姓 委 姿 威 娃 娘 婁 婆 婚 婦 媒 媽 嫌 嫩
子 孔 字 存 孝 孟 季 孤 孩 孫 學 它 宅 宇 宇 守 安 宋 完 宏 宗 宗 官 宙 定
宛 宜 客 客 宣 室 宮 害 家 容 宿 寂 寄 密 富 寒 寞 察 寢 實 實 寧 寨 審 寫
寬 寮 寶 封 射 將 專 尊 尋 對 對 導 小 少 尖 尚 尤 就 尺 尼 尾 局 屁 居 屆
屋 屏 展 屠 層 屬 山 岡 岩 岸 峰 島 峽 崇 崙 崴 嵐 嶺 川 州 巡 工 工 左 巧
巨 巫 差 己 已 巴 巷 市 布 希 帕 帛 帝 帥 師 席 帳 帶 常 帽 幅 幕 幣 幫 干
干 平 年 幸 幹 幻 幻 幼 幽 幾 庇 床 序 底 店 府 度 座 庫 庭 康 庸 廉 廖 廠
廢 廣 廳 延 廷 建 弄 式 引 弗 弘 弟 弦 弱 張 強 彈 彊 彌 彎 彞 形 彥 彩 彬
彭 彰 影 役 彼 往 征 待 很 律 後 徐 徐 徑 徒 得 從 復 微 徵 德 徹 心 必 忌
忍 志 志 忘 忙 忠 快 念 忽 怎 怒 怕 怖 思 怡 急 性 怨 怪 恆 恐 恢 恥 恨 恩
恭 息 恰 悅 悉 悔 悟 悠 您 悲 悶 情 惑 惜 惠 惡 惱 想 惹 愁 愈 愉 意 愚 愛
感 慈 態 慕 慘 慢 慣 慧 慮 慰 慶 慾 憂 憐 憑 憲 憶 憾 懂 應 懶 懷 懼 戀 戈
成 成 我 戒 或 截 戰 戲 戴 戶 房 房 所 扁 扇 手 才 扎 打 托 扣 扥 扭 扯 批
找 找 承 技 抄 把 抓 投 抗 折 披 抬 抱 抵 抹 抽 拆 拉 拋 拍 拒 拔 拖 招 拜
括 拳 拼 拾 拿 持 指 按 挑 挖 挪 振 挺 捐 捕 捨 捲 捷 掃 授 掉 掌 排 掛 採
探 接 控 推 措 描 提 插 揚 換 握 揮 援 損 搖 搜 搞 搬 搭 搶 摘 摩 摸 撐 撒
撞 撣 撥 播 撾 撿 擁 擇 擊 擋 操 擎 擔 據 擠 擦 擬 擴 擺 擾 攝 支 收 改 攻
放 政 故 效 敍 敏 救 敗 敗 敘 教 敝 敢 散 敦 敬 整 敵 數 文 斐 斗 料 斯 新
斷 方 於 施 旁 旅 旋 族 旗 既 日 旦 早 旭 旺 昂 昆 昇 昌 明 昏 易 星 映 春
昨 昭 是 時 晉 晒 晚 晨 普 景 晴 晶 智 暑 暖 暗 暫 暴 曆 曉 曰 曲 更 書 曼
曾 曾 替 最 會 月 有 朋 服 朗 望 朝 期 木 未 未 末 本 札 朱 朵 杉 李 材 村
杜 束 杯 杯 杰 東 松 板 析 林 果 枝 架 柏 某 染 柔 查 柬 柯 柳 柴 校 核 根
格 桃 案 桌 桑 梁 梅 條 梨 梯 械 梵 棄 棉 棋 棒 棚 森 椅 植 椰 楊 楓 楚 業
極 概 榜 榮 構 槍 樂 樓 標 樞 模 樣 樹 橋 機 橫 檀 檔 檢 欄 權 次 欣 欲 欺
欽 款 歉 歌 歐 歡 歡 止 正 此 步 武 歲 歷 歸 死 殊 殘 段 殺 殼 毀 毅 母 每
毒 比 毛 毫 氏 民 氣 水 永 求 汗 汝 江 江 池 污 汪 汶 決 汽 沃 沈 沉 沒 沖
沙 河 油 治 沿 況 泉 泊 法 泡 波 泥 注 泰 泳 洋 洗 洛 洞 洩 洪 洲 活 洽 派
流 浦 浩 浪 浮 海 涇 涇 消 涉 涯 液 涵 涼 淑 淚 淡 淨 深 混 淺 清 減 渡 測
港 游 湖 湯 源 準 溝 溪 溫 滄 滅 滋 滑 滴 滾 滿 漂 漏 演 漠 漢 漫 漲 漸 潔
潘 潛 潮 澤 澳 激 濃 濟 濤 濫 濱 灌 灣 火 灰 災 炎 炮 炸 為 烈 烏 烤 無 焦
然 煙 煞 照 煩 熊 熟 熱 燃 燈 燒 營 爆 爐 爛 爪 爬 爭 爵 父 爸 爺 爽 爾 牆
牆 片 版 牌 牙 牛 牠 牧 物 牲 特 牽 犧 犯 狀 狂 狐 狗 狠 狼 猛 猜 猶 獄 獅
獎 獨 獲 獸 獻 玄 率 玉 王 玩 玫 玲 玻 珊 珍 珠 班 現 球 理 琉 琪 琴 瑙 瑜
瑞 瑟 瑤 瑪 瑰 環 瓜 瓦 瓶 甘 甚 甜 生 產 用 田 田 由 甲 申 男 甸 界 留 畢
略 番 畫 異 當 疆 疏 疑 疼 病 痕 痛 痴 瘋 療 癡 登 登 發 白 百 的 皆 皇 皮
盃 益 盛 盜 盟 盡 監 盤 盧 目 盲 直 相 盼 盾 省 眉 看 真 眠 眼 眾 睛 睡 督
瞧 瞭 矛 矣 知 短 石 砂 砍 研 砲 破 硬 碎 碗 碟 碧 碩 碰 確 碼 磁 磨 磯 礎
礙 示 社 祕 祖 祝 神 祥 票 禁 禍 福 禪 禮 秀 私 秋 科 秒 秘 租 秤 秦 移 稅
程 稍 種 稱 稿 穆 穌 積 穩 究 穹 空 穿 突 窗 窩 窮 立 站 竟 章 童 端 競 竹
笑 笛 符 笨 第 筆 等 筋 答 策 简 算 管 箭 箱 節 範 篇 築 簡 簫 簽 簿 籃 籌
籍 米 粉 粗 粵 精 糊 糕 糟 系 糾 紀 約 紅 納 紐 純 紙 紙 級 紛 素 索 紫 累
細 紹 終 組 結 絕 絡 給 統 絲 經 綜 綠 維 綱 網 緊 緒 線 緣 編 緩 緬 緯 練
縣 縮 縱 總 績 繁 繆 織 繞 繪 繳 繼 續 缸 缺 罕 罪 置 罰 署 罵 罷 羅 羊 美
羞 群 義 羽 翁 習 翔 翰 翹 翻 翼 耀 老 考 者 而 耍 耐 耗 耳 耶 聊 聖 聚 聞
聯 聰 聲 職 聽 肉 肚 股 肥 肩 肯 育 背 胎 胖 胞 胡 胸 能 脆 脫 腓 腔 腦 腰
腳 腿 膽 臉 臘 臣 臥 臨 自 臭 至 致 臺 與 與 興 舉 舊 舌 舍 舒 舞 舟 航 般
船 艦 良 色 艾 芝 芬 花 芳 若 苦 英 茅 茫 茲 茶 草 荒 荷 莉 莊 莎 莫 菜 菩
華 菲 萄 萊 萬 落 葉 著 葛 葡 蒂 蒙 蒲 蒼 蓋 蓮 蔕 蔡 蔣 蕭 薄 薦 薩 薪 藉
藍 藏 藝 藤 藥 蘆 蘇 蘭 虎 處 虛 號 虧 蛋 蛙 蜂 蜜 蝶 融 螢 蟲 蟹 蠍 蠻 血
行 術 街 衛 衝 衡 衣 表 袋 被 裁 裂 裕 補 裝 裡 製 複 褲 西 要 覆 見 規 視
親 覺 覽 觀 角 解 觸 言 訂 計 訊 討 訓 託 記 訥 訪 設 許 訴 註 証 評 詞 詢
試 詩 話 話 該 詳 誇 誌 認 誓 誕 語 誠 誤 說 誰 課 誼 調 談 請 諒 論 諸 諺
諾 謀 謂 講 謝 證 識 譜 警 譯 議 護 譽 讀 變 讓 讚 谷 豆 豈 豐 象 豪 豬 貌
貓 貝 貞 負 負 財 貢 貨 貪 貪 貫 責 貴 買 費 貼 賀 資 賈 賓 賜 賞 賢 賢 賣
賤 賦 質 賭 賴 賺 購 賽 贈 贊 贏 赤 赫 走 起 超 越 趕 趙 趣 趨 足 跌 跎 跑
距 跟 跡 路 跳 踏 踢 蹟 蹤 躍 身 躲 車 軌 軍 軒 軟 較 載 輔 輕 輛 輝 輩 輪
輯 輸 轉 轟 辛 辦 辨 辭 辯 辱 農 迅 迎 近 迦 迪 迫 述 迴 迷 追 退 送 逃 逆
透 逐 途 這 這 通 逛 逝 速 造 逢 連 週 進 逸 逼 遇 遊 運 遍 過 道 道 達 違
遙 遜 遠 適 遭 遮 遲 遷 選 遺 避 避 邀 邁 還 邊 邏 那 邦 邪 邱 郎 部 郭 郵
都 鄂 鄉 鄭 鄰 配 酒 酷 酸 醉 醒 醜 醫 采 釋 釋 里 重 野 量 金 針 釣 鈴 銀
銖 銘 銳 銷 鋒 鋼 錄 錢 錦 錫 錯 鍋 鍵 鍾 鎊 鎖 鎮 鏡 鐘 鐵 鑑 長 門 閃 閉
開 閒 間 閣 閱 闆 闊 闐 關 闡 防 阻 阿 陀 附 降 限 院 院 陣 除 陪 陰 陳 陵
陵 陶 陷 陸 陽 隆 隊 階 隔 際 障 隨 險 隱 隻 雄 雄 雅 集 雖 雙 雜 雞 離 難
雨 雪 雲 零 雷 電 需 震 霍 霧 露 霸 霹 靂 靈 青 靖 靜 非 靠 面 革 靼 鞋 韃
韋 韓 音 韻 響 頁 頂 項 順 須 預 頑 頓 頗 領 頭 頻 顆 題 額 顏 願 類 顧 顯
風 飄 飛 食 飯 飲 飽 飾 餅 養 餐 餘 館 首 香 馬 駐 駕 駛 騎 騙 騷 驅 驗 驚
骨 體 高 髮 鬆 鬥 鬧 鬱 鬼 魁 魂 魅 魔 魚 魯 鮮 鳥 鳳 鳴 鴻 鵝 鷹 鹿 麗 麥
麵 麻 麼 黃 黎 黑 默 點 黨 鼓 鼠 鼻 齊 齋 齒 齡 龍 龜",
- 3: "伏 侶 兌 兹 别 勳 卑 占 叶 堤 墎 奥 孜 峇 巽 彝 楔 渾 燦 狄 琳 瑚 甫
礁 芒 苗 茨 蚩 蜀 隴",
- 5: "一 丁 丈 不 且 丞 並 串 乘 乾 亂 亭 傀 僎 僵 儐 償 儳 儷 儻 叢 嚴 囌
囑 廳",
- },
- "zu": {
- 0: "a b bh c ch d dl dy e f g gc gq gx h hh hl i j k kh kl kp l m n nc
ngc ngq ngx nhl nk nkc nkq nkx nq ntsh nx ny o p ph q qh r rh s sh t th tl
ts tsh u v w x xh y z",
- 3: "á à ă â å ä ã ā æ ç é è ĕ ê ë ē í ì ĭ î ï ī ñ ó ò ŏ ô ö ø ō œ ú ù ŭ
û ü ū ÿ",
- 4: "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",
- },
-}
=======================================
--- /src/pkg/exp/locale/collate/tools/colcmp/col.go Thu Nov 15 13:23:56 2012
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "exp/locale/collate"
- "log"
- "unicode/utf16"
-)
-
-// Input holds an input string in both UTF-8 and UTF-16 format.
-type Input struct {
- index int // used for restoring to original random order
- UTF8 []byte
- UTF16 []uint16
- key []byte // used for sorting
-}
-
-func (i Input) String() string {
- return string(i.UTF8)
-}
-
-func makeInput(s8 []byte, s16 []uint16) Input {
- return Input{UTF8: s8, UTF16: s16}
-}
-
-func makeInputString(s string) Input {
- return Input{
- UTF8: []byte(s),
- UTF16: utf16.Encode([]rune(s)),
- }
-}
-
-// Collator is an interface for architecture-specific implementations of
collation.
-type Collator interface {
- // Key generates a sort key for the given input. Implemenations
- // may return nil if a collator does not support sort keys.
- Key(s Input) []byte
-
- // Compare returns -1 if a < b, 1 if a > b and 0 if a == b.
- Compare(a, b Input) int
-}
-
-// CollatorFactory creates a Collator for a given locale.
-type CollatorFactory struct {
- name string
- makeFn func(locale string) (Collator, error)
- description string
-}
-
-var collators = []CollatorFactory{}
-
-// AddFactory registers f as a factory for an implementation of Collator.
-func AddFactory(f CollatorFactory) {
- collators = append(collators, f)
-}
-
-func getCollator(name, locale string) Collator {
- for _, f := range collators {
- if
f.name == name {
- col, err := f.makeFn(locale)
- if err != nil {
- log.Fatal(err)
- }
- return col
- }
- }
- log.Fatalf("collator of type %q not found", name)
- return nil
-}
-
-// goCollator is an implemention of Collator using go's own collator.
-type goCollator struct {
- c *collate.Collator
- buf collate.Buffer
-}
-
-func init() {
- AddFactory(CollatorFactory{"go", newGoCollator, "Go's native collator
implementation."})
-}
-
-func newGoCollator(locale string) (Collator, error) {
- c := &goCollator{c: collate.New(locale)}
- return c, nil
-}
-
-func (c *goCollator) Key(b Input) []byte {
- return c.c.Key(&c.buf, b.UTF8)
-}
-
-func (c *goCollator) Compare(a, b Input) int {
- return c.c.Compare(a.UTF8, b.UTF8)
-}
=======================================
--- /src/pkg/exp/locale/collate/tools/colcmp/colcmp.go Wed Jan 30 12:19:03
2013
+++ /dev/null
@@ -1,528 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "bytes"
- "exp/norm"
- "flag"
- "fmt"
- "io"
- "log"
- "os"
- "runtime/pprof"
- "sort"
- "strconv"
- "strings"
- "text/template"
- "time"
-)
-
-var (
- doNorm = flag.Bool("norm", false, "normalize input strings")
- cases = flag.Bool("case", false, "generate case variants")
- verbose = flag.Bool("verbose", false, "print results")
- debug = flag.Bool("debug", false, "output debug information")
- locale = flag.String("locale", "en_US", "the locale to use. May be a
comma-separated list for some commands.")
- col = flag.String("col", "go", "collator to test")
- gold = flag.String("gold", "go", "collator used as the gold standard")
- usecmp = flag.Bool("usecmp", false,
- `use comparison instead of sort keys when sorting. Must
be "test", "gold" or "both"`)
- cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
- exclude = flag.String("exclude", "", "exclude errors that contain any
of the characters")
- limit = flag.Int("limit", 5000000, "maximum number of samples to
generate for one run")
-)
-
-func failOnError(err error) {
- if err != nil {
- log.Panic(err)
- }
-}
-
-// Test holds test data for testing a locale-collator pair.
-// Test also provides functionality that is commonly used by the various
commands.
-type Test struct {
- ctxt *Context
- Name string
- Locale string
- ColName string
-
- Col Collator
- UseCompare bool
-
- Input []Input
- Duration time.Duration
-
- start time.Time
- msg string
- count int
-}
-
-func (t *Test) clear() {
- t.Col = nil
- t.Input = nil
-}
-
-const (
- msgGeneratingInput = "generating input"
- msgGeneratingKeys = "generating keys"
- msgSorting = "sorting"
-)
-
-var lastLen = 0
-
-func (t *Test) SetStatus(msg string) {
- if *debug || *verbose {
- fmt.Printf("%s: %s...\n", t.Name, msg)
- } else if t.ctxt.out != nil {
- fmt.Fprint(t.ctxt.out, strings.Repeat(" ", lastLen))
- fmt.Fprint(t.ctxt.out, strings.Repeat("\b", lastLen))
- fmt.Fprint(t.ctxt.out, msg, "...")
- lastLen = len(msg) + 3
- fmt.Fprint(t.ctxt.out, strings.Repeat("\b", lastLen))
- }
-}
-
-// Start is used by commands to signal the start of an operation.
-func (t *Test) Start(msg string) {
- t.SetStatus(msg)
- t.count = 0
- t.msg = msg
- t.start = time.Now()
-}
-
-// Stop is used by commands to signal the end of an operation.
-func (t *Test) Stop() (time.Duration, int) {
- d := time.Now().Sub(t.start)
- t.Duration += d
- if *debug || *verbose {
- fmt.Printf("%s: %s done. (%.3fs /%dK ops)\n", t.Name, t.msg,
d.Seconds(), t.count/1000)
- }
- return d, t.count
-}
-
-// generateKeys generates sort keys for all the inputs.
-func (t *Test) generateKeys() {
- for i, s := range t.Input {
- b := t.Col.Key(s)
- t.Input[i].key = b
- if *debug {
- fmt.Printf("%s (%X): %X\n", string(s.UTF8), s.UTF16, b)
- }
- }
-}
-
-// Sort sorts the inputs. It generates sort keys if this is required by the
-// chosen sort method.
-func (t *Test) Sort() (tkey, tsort time.Duration, nkey, nsort int) {
- if *cpuprofile != "" {
- f, err := os.Create(*cpuprofile)
- failOnError(err)
- pprof.StartCPUProfile(f)
- defer pprof.StopCPUProfile()
- }
- if t.UseCompare || t.Col.Key(t.Input[0]) == nil {
- t.Start(msgSorting)
- sort.Sort(&testCompare{*t})
- tsort, nsort = t.Stop()
- } else {
- t.Start(msgGeneratingKeys)
- t.generateKeys()
- t.count = len(t.Input)
- tkey, nkey = t.Stop()
- t.Start(msgSorting)
- sort.Sort(t)
- tsort, nsort = t.Stop()
- }
- return
-}
-
-func (t *Test) Swap(a, b int) {
- t.Input[a], t.Input[b] = t.Input[b], t.Input[a]
-}
-
-func (t *Test) Less(a, b int) bool {
- t.count++
- return bytes.Compare(t.Input[a].key, t.Input[b].key) == -1
-}
-
-func (t Test) Len() int {
- return len(t.Input)
-}
-
-type testCompare struct {
- Test
-}
-
-func (t *testCompare) Less(a, b int) bool {
- t.count++
- return t.Col.Compare(t.Input[a], t.Input[b]) == -1
-}
-
-type testRestore struct {
- Test
-}
-
-func (t *testRestore) Less(a, b int) bool {
- return t.Input[a].index < t.Input[b].index
-}
-
-// GenerateInput generates input phrases for the locale tested by t.
-func (t *Test) GenerateInput() {
- t.Input = nil
- if t.ctxt.lastLocale != t.Locale {
- gen := phraseGenerator{}
- gen.init(t.Locale)
- t.SetStatus(msgGeneratingInput)
- t.ctxt.lastInput = nil // allow the previous value to be garbage
collected.
- t.Input = gen.generate(*doNorm)
- t.ctxt.lastInput = t.Input
- t.ctxt.lastLocale = t.Locale
- } else {
- t.Input = t.ctxt.lastInput
- for i := range t.Input {
- t.Input[i].key = nil
- }
- sort.Sort(&testRestore{*t})
- }
-}
-
-// Context holds all tests and settings translated from command line
options.
-type Context struct {
- test []*Test
- last *Test
-
- lastLocale string
- lastInput []Input
-
- out io.Writer
-}
-
-func (ts *Context) Printf(format string, a ...interface{}) {
- ts.assertBuf()
- fmt.Fprintf(ts.out, format, a...)
-}
-
-func (ts *Context) Print(a ...interface{}) {
- ts.assertBuf()
- fmt.Fprint(ts.out, a...)
-}
-
-// assertBuf sets up an io.Writer for ouput, if it doesn't already exist.
-// In debug and verbose mode, output is buffered so that the regular output
-// will not interfere with the additional output. Otherwise, output is
-// written directly to stdout for a more responsive feel.
-func (ts *Context) assertBuf() {
- if ts.out != nil {
- return
- }
- if *debug || *verbose {
- ts.out = &bytes.Buffer{}
- } else {
- ts.out = os.Stdout
- }
-}
-
-// flush flushes the contents of ts.out to stdout, if it is not stdout
already.
-func (ts *Context) flush() {
- if ts.out != nil {
- if _, ok := ts.out.(io.ReadCloser); !ok {
- io.Copy(os.Stdout, ts.out.(io.Reader))
- }
- }
-}
-
-// parseTests creates all tests from command lines and returns
-// a Context to hold them.
-func parseTests() *Context {
- ctxt := &Context{}
- colls := strings.Split(*col, ",")
- for _, loc := range strings.Split(*locale, ",") {
- loc = strings.TrimSpace(loc)
- for _, name := range colls {
- name = strings.TrimSpace(name)
- col := getCollator(name, loc)
- ctxt.test = append(ctxt.test, &Test{
- ctxt: ctxt,
- Locale: loc,
- ColName: name,
- UseCompare: *usecmp,
- Col: col,
- })
- }
- }
- return ctxt
-}
-
-func (c *Context) Len() int {
- return len(c.test)
-}
-
-func (c *Context) Test(i int) *Test {
- if c.last != nil {
- c.last.clear()
- }
- c.last = c.test[i]
- return c.last
-}
-
-func parseInput(args []string) []Input {
- input := []Input{}
- for _, s := range args {
- rs := []rune{}
- for len(s) > 0 {
- var r rune
- r, _, s, _ = strconv.UnquoteChar(s, '\'')
- rs = append(rs, r)
- }
- s = string(rs)
- if *doNorm {
- s = norm.NFD.String(s)
- }
- input = append(input, makeInputString(s))
- }
- return input
-}
-
-// A Command is an implementation of a colcmp command.
-type Command struct {
- Run func(cmd *Context, args []string)
- Usage string
- Short string
- Long string
-}
-
-func (cmd Command) Name() string {
- return strings.SplitN(cmd.Usage, " ", 2)[0]
-}
-
-var commands = []*Command{
- cmdSort,
- cmdBench,
- cmdRegress,
-}
-
-const sortHelp = `
-Sort sorts a given list of strings. Strings are separated by whitespace.
-`
-
-var cmdSort = &Command{
- Run: runSort,
- Usage: "sort <string>*",
- Short: "sort a given list of strings",
- Long: sortHelp,
-}
-
-func runSort(ctxt *Context, args []string) {
- input := parseInput(args)
- if len(input) == 0 {
- log.Fatalf("Nothing to sort.")
- }
- if ctxt.Len() > 1 {
- ctxt.Print("COLL LOCALE RESULT\n")
- }
- for i := 0; i < ctxt.Len(); i++ {
- t := ctxt.Test(i)
- t.Input = append(t.Input, input...)
- t.Sort()
- if ctxt.Len() > 1 {
- ctxt.Printf("%-5s %-5s ", t.ColName, t.Locale)
- }
- for _, s := range t.Input {
- ctxt.Print(string(s.UTF8), " ")
- }
- ctxt.Print("\n")
- }
-}
-
-const benchHelp = `
-Bench runs a benchmark for the given list of collator implementations.
-If no collator implementations are given, the go collator will be used.
-`
-
-var cmdBench = &Command{
- Run: runBench,
- Usage: "bench",
- Short: "benchmark a given list of collator implementations",
- Long: benchHelp,
-}
-
-func runBench(ctxt *Context, args []string) {
-
ctxt.Printf("%-7s %-5s %-6s %-24s %-24s %-5s %s\n", "LOCALE", "COLL", "N", "KEYS", "SORT", "AVGLN", "TOTAL")
- for i := 0; i < ctxt.Len(); i++ {
- t := ctxt.Test(i)
- ctxt.Printf("%-7s %-5s ", t.Locale, t.ColName)
- t.GenerateInput()
- ctxt.Printf("%-6s ", fmt.Sprintf("%dK", t.Len()/1000))
- tkey, tsort, nkey, nsort := t.Sort()
- p := func(dur time.Duration, n int) {
- s := ""
- if dur > 0 {
- s = fmt.Sprintf("%6.3fs ", dur.Seconds())
- if n > 0 {
- s += fmt.Sprintf("%15s", fmt.Sprintf("(%4.2f ns/op)",
float64(dur)/float64(n)))
- }
- }
- ctxt.Printf("%-24s ", s)
- }
- p(tkey, nkey)
- p(tsort, nsort)
-
- total := 0
- for _, s := range t.Input {
- total += len(s.key)
- }
- ctxt.Printf("%-5d ", total/t.Len())
- ctxt.Printf("%6.3fs\n", t.Duration.Seconds())
- if *debug {
- for _, s := range t.Input {
- fmt.Print(string(s.UTF8), " ")
- }
- fmt.Println()
- }
- }
-}
-
-const regressHelp = `
-Regress runs a monkey test by comparing the results of randomly generated
tests
-between two implementations of a collator. The user may optionally pass a
list
-of strings to regress against instead of the default test set.
-`
-
-var cmdRegress = &Command{
- Run: runRegress,
- Usage: "regress -gold=<col> -test=<col> [string]*",
- Short: "run a monkey test between two collators",
- Long: regressHelp,
-}
-
-const failedKeyCompare = `
-%s:%d: incorrect comparison result for input:
- a: %q (%.4X)
- key: %s
- b: %q (%.4X)
- key: %s
- Compare(a, b) = %d; want %d.
-
- gold keys:
- a: %s
- b: %s
-`
-
-const failedCompare = `
-%s:%d: incorrect comparison result for input:
- a: %q (%.4X)
- b: %q (%.4X)
- Compare(a, b) = %d; want %d.
-`
-
-func keyStr(b []byte) string {
- buf := &bytes.Buffer{}
- for _, v := range b {
- fmt.Fprintf(buf, "%.2X ", v)
- }
- return buf.String()
-}
-
-func runRegress(ctxt *Context, args []string) {
- input := parseInput(args)
- for i := 0; i < ctxt.Len(); i++ {
- t := ctxt.Test(i)
- if len(input) > 0 {
- t.Input = append(t.Input, input...)
- } else {
- t.GenerateInput()
- }
- t.Sort()
- count := 0
- gold := getCollator(*gold, t.Locale)
- for i := 1; i < len(t.Input); i++ {
- ia := t.Input[i-1]
- ib := t.Input[i]
- if bytes.IndexAny(ib.UTF8, *exclude) != -1 {
- i++
- continue
- }
- if bytes.IndexAny(ia.UTF8, *exclude) != -1 {
- continue
- }
- goldCmp := gold.Compare(ia, ib)
- if cmp := bytes.Compare(ia.key, ib.key); cmp != goldCmp {
- count++
- a := string(ia.UTF8)
- b := string(ib.UTF8)
- fmt.Printf(failedKeyCompare, t.Locale, i-1, a, []rune(a),
keyStr(ia.key), b, []rune(b), keyStr(ib.key), cmp, goldCmp,
keyStr(gold.Key(ia)), keyStr(gold.Key(ib)))
- } else if cmp := t.Col.Compare(ia, ib); cmp != goldCmp {
- count++
- a := string(ia.UTF8)
- b := string(ib.UTF8)
- fmt.Printf(failedCompare, t.Locale, i-1, a, []rune(a), b, []rune(b),
cmp, goldCmp)
- }
- }
- if count > 0 {
- ctxt.Printf("Found %d inconsistencies in %d entries.\n", count,
t.Len()-1)
- }
- }
-}
-
-const helpTemplate = `
-colcmp is a tool for testing and benchmarking collation
-
-Usage: colcmp command [arguments]
-
-The commands are:
-{{range .}}
- {{.Name | printf "%-11s"}} {{.Short}}{{end}}
-
-Use "col help [topic]" for more information about that topic.
-`
-
-const detailedHelpTemplate = `
-Usage: colcmp {{.Usage}}
-
-{{.Long | trim}}
-`
-
-func runHelp(args []string) {
- t := template.New("help")
- t.Funcs(template.FuncMap{"trim": strings.TrimSpace})
- if len(args) < 1 {
- template.Must(t.Parse(helpTemplate))
- failOnError(t.Execute(os.Stderr, &commands))
- } else {
- for _, cmd := range commands {
- if cmd.Name() == args[0] {
- template.Must(t.Parse(detailedHelpTemplate))
- failOnError(t.Execute(os.Stderr, cmd))
- os.Exit(0)
- }
- }
- log.Fatalf("Unknown command %q. Run 'colcmp help'.", args[0])
- }
- os.Exit(0)
-}
-
-func main() {
- flag.Parse()
- log.SetFlags(0)
-
- ctxt := parseTests()
-
- if flag.NArg() < 1 {
- runHelp(nil)
- }
- args := flag.Args()[1:]
- if flag.Arg(0) == "help" {
- runHelp(args)
- }
- for _, cmd := range commands {
- if cmd.Name() == flag.Arg(0) {
- cmd.Run(ctxt, args)
- ctxt.flush()
- return
- }
- }
- runHelp(flag.Args())
-}
=======================================
--- /src/pkg/exp/locale/collate/tools/colcmp/darwin.go Sun Sep 23 21:22:03
2012
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin
-
-package main
-
-/*
-#cgo LDFLAGS: -framework CoreFoundation
-#include <CoreFoundation/CFBase.h>
-#include <CoreFoundation/CoreFoundation.h>
-*/
-import "C"
-import (
- "unsafe"
-)
-
-func init() {
- AddFactory(CollatorFactory{"osx", newOSX16Collator,
- "OS X/Darwin collator, using native strings."})
- AddFactory(CollatorFactory{"osx8", newOSX8Collator,
- "OS X/Darwin collator for UTF-8."})
-}
-
-func osxUInt8P(s []byte) *C.UInt8 {
- return (*C.UInt8)(unsafe.Pointer(&s[0]))
-}
-
-func osxCharP(s []uint16) *C.UniChar {
- return (*C.UniChar)(unsafe.Pointer(&s[0]))
-}
-
-// osxCollator implements an Collator based on OS X's CoreFoundation.
-type osxCollator struct {
- loc C.CFLocaleRef
- opt C.CFStringCompareFlags
-}
-
-func (c *osxCollator) init(locale string) {
- l := C.CFStringCreateWithBytes(
- nil,
- osxUInt8P([]byte(locale)),
- C.CFIndex(len(locale)),
- C.kCFStringEncodingUTF8,
- C.Boolean(0),
- )
- c.loc = C.CFLocaleCreate(nil, l)
-}
-
-func newOSX8Collator(locale string) (Collator, error) {
- c := &osx8Collator{}
- c.init(locale)
- return c, nil
-}
-
-func newOSX16Collator(locale string) (Collator, error) {
- c := &osx16Collator{}
- c.init(locale)
- return c, nil
-}
-
-func (c osxCollator) Key(s Input) []byte {
- return nil // sort keys not supported by OS X CoreFoundation
-}
-
-type osx8Collator struct {
- osxCollator
-}
-
-type osx16Collator struct {
- osxCollator
-}
-
-func (c osx16Collator) Compare(a, b Input) int {
- sa := C.CFStringCreateWithCharactersNoCopy(
- nil,
- osxCharP(a.UTF16),
- C.CFIndex(len(a.UTF16)),
- C.kCFAllocatorNull,
- )
- sb := C.CFStringCreateWithCharactersNoCopy(
- nil,
- osxCharP(b.UTF16),
- C.CFIndex(len(b.UTF16)),
- C.kCFAllocatorNull,
- )
- _range := C.CFRangeMake(0, C.CFStringGetLength(sa))
- return int(C.CFStringCompareWithOptionsAndLocale(sa, sb, _range, c.opt,
c.loc))
-}
-
-func (c osx8Collator) Compare(a, b Input) int {
- sa := C.CFStringCreateWithBytesNoCopy(
- nil,
- osxUInt8P(a.UTF8),
- C.CFIndex(len(a.UTF8)),
- C.kCFStringEncodingUTF8,
- C.Boolean(0),
- C.kCFAllocatorNull,
- )
- sb := C.CFStringCreateWithBytesNoCopy(
- nil,
- osxUInt8P(b.UTF8),
- C.CFIndex(len(b.UTF8)),
- C.kCFStringEncodingUTF8,
- C.Boolean(0),
- C.kCFAllocatorNull,
- )
- _range := C.CFRangeMake(0, C.CFStringGetLength(sa))
- return int(C.CFStringCompareWithOptionsAndLocale(sa, sb, _range, c.opt,
c.loc))
-}
=======================================
--- /src/pkg/exp/locale/collate/tools/colcmp/gen.go Wed Jan 30 12:19:03 2013
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "exp/norm"
- "math"
- "math/rand"
- "strings"
- "unicode"
- "unicode/utf16"
- "unicode/utf8"
-)
-
-// parent computes the parent locale for the given locale.
-// It returns false if the parent is already root.
-func parent(locale string) (parent string, ok bool) {
- if locale == "root" {
- return "", false
- }
- if i := strings.LastIndex(locale, "_"); i != -1 {
- return locale[:i], true
- }
- return "root", true
-}
-
-// rewriter is used to both unique strings and create variants of strings
-// to add to the test set.
-type rewriter struct {
- seen map[string]bool
- addCases bool
-}
-
-func newRewriter() *rewriter {
- return &rewriter{
- seen: make(map[string]bool),
- }
-}
-
-func (r *rewriter) insert(a []string, s string) []string {
- if !r.seen[s] {
- r.seen[s] = true
- a = append(a, s)
- }
- return a
-}
-
-// rewrite takes a sequence of strings in, adds variants of the these
strings
-// based on options and removes duplicates.
-func (r *rewriter) rewrite(ss []string) []string {
- ns := []string{}
- for _, s := range ss {
- ns = r.insert(ns, s)
- if r.addCases {
- rs := []rune(s)
- rn := rs[0]
- for c := unicode.SimpleFold(rn); c != rn; c = unicode.SimpleFold(c) {
- rs[0] = c
- ns = r.insert(ns, string(rs))
- }
- }
- }
- return ns
-}
-
-// exemplarySet holds a parsed set of characters from the
exemplarCharacters table.
-type exemplarySet struct {
- typ exemplarType
- set []string
- charIndex int // cumulative total of phrases, including this set
-}
-
-type phraseGenerator struct {
- sets [exN]exemplarySet
- n int
-}
-
-func (g *phraseGenerator) init(locale string) {
- ec := exemplarCharacters
- // get sets for locale or parent locale if the set is not defined.
- for i := range g.sets {
- for p, ok := locale, true; ok; p, ok = parent(p) {
- if set, ok := ec[p]; ok && set[i] != "" {
- g.sets[i].set = strings.Split(set[i], " ")
- break
- }
- }
- }
- r := newRewriter()
- r.addCases = *cases
- for i := range g.sets {
- g.sets[i].set = r.rewrite(g.sets[i].set)
- }
- // compute indexes
- for i, set := range g.sets {
- g.n += len(set.set)
- g.sets[i].charIndex = g.n
- }
-}
-
-// phrase returns the ith phrase, where i < g.n.
-func (g *phraseGenerator) phrase(i int) string {
- for _, set := range g.sets {
- if i < set.charIndex {
- return set.set[i-(set.charIndex-len(set.set))]
- }
- }
- panic("index out of range")
-}
-
-// generate generates inputs by combining all pairs of examplar strings.
-// If doNorm is true, all input strings are normalized to NFC.
-// TODO: allow other variations, statistical models, and random
-// trailing sequences.
-func (g *phraseGenerator) generate(doNorm bool) []Input {
- const (
- M = 1024 * 1024
- buf8Size = 30 * M
- buf16Size = 10 * M
- )
- // TODO: use a better way to limit the input size.
- if sq := int(math.Sqrt(float64(*limit))); g.n > sq {
- g.n = sq
- }
- size := g.n * g.n
- a := make([]Input, 0, size)
- buf8 := make([]byte, 0, buf8Size)
- buf16 := make([]uint16, 0, buf16Size)
-
- addInput := func(str string) {
- buf8 = buf8[len(buf8):]
- buf16 = buf16[len(buf16):]
- if len(str) > cap(buf8) {
- buf8 = make([]byte, 0, buf8Size)
- }
- if len(str) > cap(buf16) {
- buf16 = make([]uint16, 0, buf16Size)
- }
- if doNorm {
- buf8 = norm.NFD.AppendString(buf8, str)
- } else {
- buf8 = append(buf8, str...)
- }
- buf16 = appendUTF16(buf16, buf8)
- a = append(a, makeInput(buf8, buf16))
- }
- for i := 0; i < g.n; i++ {
- p1 := g.phrase(i)
- addInput(p1)
- for j := 0; j < g.n; j++ {
- p2 := g.phrase(j)
- addInput(p1 + p2)
- }
- }
- // permutate
- rnd := rand.New(rand.NewSource(int64(rand.Int())))
- for i := range a {
- j := i + rnd.Intn(len(a)-i)
- a[i], a[j] = a[j], a[i]
- a[i].index = i // allow restoring this order if input is used multiple
times.
- }
- return a
-}
-
-func appendUTF16(buf []uint16, s []byte) []uint16 {
- for len(s) > 0 {
- r, sz := utf8.DecodeRune(s)
- s = s[sz:]
- r1, r2 := utf16.EncodeRune(r)
- if r1 != 0xFFFD {
- buf = append(buf, uint16(r1), uint16(r2))
- } else {
- buf = append(buf, uint16(r))
- }
- }
- return buf
-}
=======================================
***Additional files exist in this changeset.***