Пример #1
0
func TestJSONScannerNextCurrentPosition(t *testing.T) {
	testCaseList := []testCaseForJSONScannerCurrentPosition{
		{data: "12345678", expected: []int{0, 1, 2, 3, 4, 5, 6, 7, 8}},
	}

	for testIndex, testCase := range testCaseList {
		scanner := scanner.NewJSONScanner(strings.NewReader(testCase.data))
		for expectedIndex, expected := range testCase.expected {
			actual := scanner.CurrentPosition()

			if actual != expected {
				t.Errorf("testCase[%d:%d] expected=%#v, actual=%#v", testIndex, expectedIndex, expected, actual)
			}

			scanner.NextRune()
		}
		actual, err := scanner.NextNonWhiteSpaceRune()
		if err != io.EOF {
			t.Logf("%s", string([]rune{actual}))
			t.Errorf("testCase[%d] EOF not found", testIndex)
		}
		actual, err = scanner.NextRune()
		if err != io.EOF {
			t.Logf("%s", string([]rune{actual}))
			t.Errorf("testCase[%d] EOF not found, current:%d", testIndex, scanner.CurrentPosition())
		}
	}
}
Пример #2
0
func TestMultiCharacterScannerScan(t *testing.T) {
	testCaseList := []testCaseForTestMultiCharacterScannerScan{
		{data: " null  ", tokenKind: token.KindNull, expectedError: false, expected: token.NewToken(token.KindNull, string(token.KindNull))},
		{data: " true  ", tokenKind: token.KindTrue, expectedError: false, expected: token.NewToken(token.KindTrue, string(token.KindTrue))},
		{data: "false ", tokenKind: token.KindFalse, expectedError: false, expected: token.NewToken(token.KindFalse, string(token.KindFalse))},

		{data: "f alse ", tokenKind: token.KindFalse, expectedError: true, expected: token.NewToken(token.KindEmpty, "")},
		{data: "tru e", tokenKind: token.KindTrue, expectedError: true, expected: token.NewToken(token.KindEmpty, "")},
		{data: "xnull", tokenKind: token.KindNull, expectedError: true, expected: token.NewToken(token.KindEmpty, "")},
	}
	for testIndex, testCase := range testCaseList {
		stringReader := strings.NewReader(testCase.data)
		jsonScanner := scanner.NewJSONScanner(stringReader)
		scanner := tokenscanner.NewMultiCharacterScanner(testCase.tokenKind, jsonScanner).(*tokenscanner.MultiCharacterScanner)

		actual, err := scanner.Scan()
		if err == nil && testCase.expectedError {
			t.Errorf("testCase[%d] must return error", testIndex)
		}
		if err != nil && !testCase.expectedError {
			t.Error(err)
		}
		expected := testCase.expected

		if !actual.IsEqualTo(expected) {
			t.Errorf("testCase[%d] expected=%#v, actual=%#v", testIndex, expected, actual)
		}
	}
}
Пример #3
0
func TestStringScanner1(t *testing.T) {
	testData := `
	"teststring"
	`
	reader := strings.NewReader(testData)
	jsonScanner := scanner.NewJSONScanner(reader)
	scanner := tokenscanner.NewStringScanner(jsonScanner).(*tokenscanner.StringScanner)
	if !scanner.CanProcess() {
		t.Error("testData can process")
	}
	if scanner.RuneOfToken() != '"' {
		t.Error("StringScanner.RunOfToken must be '\"'")
	}
	if !scanner.CanProcessRune('"') {
		t.Error("StringScanner.CanProcessRune can process rune '\"'")
	}

	expectedToken := token.NewToken(token.KindString, "teststring")
	token, err := scanner.Scan()
	if err != nil {
		t.Error(err)
	}
	if !expectedToken.IsEqualTo(token) {
		t.Errorf("expected=%#v, actual=%#v", expectedToken, token)
	}
}
Пример #4
0
func TestSingleCharacterScannerCanProcess(t *testing.T) {
	testCaseList := []testCaseForTestSingleCharacterScannerCanProcess{
		{data: "{", tokenKind: token.KindBeginObject, expected: true},
		{data: "}", tokenKind: token.KindEndObject, expected: true},
		{data: "[", tokenKind: token.KindBeginArray, expected: true},
		{data: "]", tokenKind: token.KindEndArray, expected: true},
		{data: ",", tokenKind: token.KindComma, expected: true},
		{data: ":", tokenKind: token.KindSeparator, expected: true},

		{data: "", tokenKind: token.KindBeginObject, expected: false},
		{data: "a", tokenKind: token.KindEndObject, expected: false},
		{data: "}", tokenKind: token.KindBeginArray, expected: false},
		{data: "{", tokenKind: token.KindEndArray, expected: false},
		{data: "-", tokenKind: token.KindComma, expected: false},
		{data: "=", tokenKind: token.KindSeparator, expected: false},
	}

	for testIndex, testCase := range testCaseList {
		reader := strings.NewReader(testCase.data)
		jsonScanner := scanner.NewJSONScanner(reader)
		scanner := tokenscanner.NewSingleCharacterScanner(testCase.tokenKind, jsonScanner)
		actual := scanner.CanProcess()
		if actual != testCase.expected {
			t.Errorf("testCase[%d] expected=%#v, actual=%#v\n", testIndex, testCase.expected, actual)
		}
	}
}
Пример #5
0
func TestJSONScannerNextPeekRune(t *testing.T) {
	testCaseList := []testCaseForJSONScannerPeekRune{
		{data: "12345678", expected: "12345678"},
	}

	for testIndex, testCase := range testCaseList {
		scanner := scanner.NewJSONScanner(strings.NewReader(testCase.data))
		for expectedIndex, expected := range testCase.expected {
			beforePosition := scanner.CurrentPosition()
			actual, err := scanner.PeekRune()
			afterPosition := scanner.CurrentPosition()
			if err != nil {
				t.Error(err)
			}
			if actual != expected {
				t.Errorf("testCase[%d:%d] expected=%#v, actual=%#v", testIndex, expectedIndex, expected, actual)
			}
			if beforePosition != afterPosition {
				t.Errorf("testCase[%d:%d] position is wrong", testIndex, expectedIndex)
			}
			scanner.NextRune()
		}
		actual, err := scanner.NextNonWhiteSpaceRune()
		if err != io.EOF {
			t.Logf("%s", string([]rune{actual}))
			t.Errorf("testCase[%d] EOF not found", testIndex)
		}
		actual, err = scanner.NextRune()
		if err != io.EOF {
			t.Logf("%s", string([]rune{actual}))
			t.Errorf("testCase[%d] EOF not found, current:%d", testIndex, scanner.CurrentPosition())
		}
	}
}
Пример #6
0
// NewTokenizer returns a new tokenizer.
func NewTokenizer(reader io.Reader) *Tokenizer {
	jsonScanner := scanner.NewJSONScanner(reader)
	return &Tokenizer{
		scanner:       jsonScanner,
		tokenScanners: createJSONScanners(jsonScanner),
		buffer:        &tokenBuffer{buffer: []token.Token{}},
	}
}
Пример #7
0
func TestJSONScannerNewScanner(t *testing.T) {
	testData := `
	{
		"key": "value"
	}
	`
	actual := scanner.NewJSONScanner(strings.NewReader(testData))
	if actual == nil {
		t.Error("scanner not created")
	}
}
Пример #8
0
func TestSingleCharacterScannerMultiScanner(t *testing.T) {
	testData := `
	{
		[	],
		:
	}
	`
	expectedString := `{[],:}`
	reader := strings.NewReader(testData)
	jsonScanner := scanner.NewJSONScanner(reader)
	scanners := []tokenscanner.TokenScanner{
		tokenscanner.NewSingleCharacterScanner(token.KindBeginObject, jsonScanner),
		tokenscanner.NewSingleCharacterScanner(token.KindEndObject, jsonScanner),
		tokenscanner.NewSingleCharacterScanner(token.KindBeginArray, jsonScanner),
		tokenscanner.NewSingleCharacterScanner(token.KindEndArray, jsonScanner),
		tokenscanner.NewSingleCharacterScanner(token.KindSeparator, jsonScanner),
		tokenscanner.NewSingleCharacterScanner(token.KindComma, jsonScanner),
	}
	var buffer bytes.Buffer
	for {
		_, err := jsonScanner.PeekNonWhiteSpaceRune()
		if err == io.EOF {
			break
		}
		scanned := false
		for scannerIndex, scanner := range scanners {
			if scanner.CanProcess() {
				scanned = true
				currentToken, err := scanner.Scan()
				buffer.WriteString(currentToken.Value)
				if err != nil {
					t.Log(scannerIndex)
					t.Fatal(err)
				}
			}
		}
		if !scanned {
			peek, err := jsonScanner.PeekNonWhiteSpaceRune()
			if err != nil {
				t.Log("err:", err)
			} else {
				t.Log("current rune:", string(peek))
			}
			t.Fatal("can't scan")
		}
	}
	if buffer.String() != expectedString {
		t.Errorf("Scan result is wrong expected=%#v, actual=%#v\n", testData, buffer.String())
	}
}
Пример #9
0
func TestSingleCharacterScannerRuneOfToken(t *testing.T) {
	testCaseList := []testCaseForTestSingleCharacterScannerRuneOfToken{
		{data: "{", tokenKind: token.KindBeginObject, expected: '{'},
		{data: "}", tokenKind: token.KindEndObject, expected: '}'},
		{data: "[", tokenKind: token.KindBeginArray, expected: '['},
		{data: "]", tokenKind: token.KindEndArray, expected: ']'},
		{data: ",", tokenKind: token.KindComma, expected: ','},
		{data: ":", tokenKind: token.KindSeparator, expected: ':'},
	}
	for testIndex, testCase := range testCaseList {
		reader := strings.NewReader(testCase.data)
		jsonScanner := scanner.NewJSONScanner(reader)
		scanner := tokenscanner.NewSingleCharacterScanner(testCase.tokenKind, jsonScanner)
		actual := scanner.(*tokenscanner.SingleCharacterScanner).RuneOfToken()
		if actual != testCase.expected {
			t.Errorf("testCase[%d] expected=%#v, actual=%#v\n", testIndex, testCase.expected, actual)
		}
	}
}
Пример #10
0
func TestMultiCharacterScannerRuneOfToken(t *testing.T) {
	testCaseList := []testCaseForTestMultiCharacterScannerRuneOfToken{
		{data: " null ", tokenKind: token.KindNull, expected: 'n'},
		{data: " true ", tokenKind: token.KindTrue, expected: 't'},
		{data: " false ", tokenKind: token.KindFalse, expected: 'f'},
	}
	for testIndex, testCase := range testCaseList {
		stringReader := strings.NewReader(testCase.data)
		jsonScanner := scanner.NewJSONScanner(stringReader)
		scanner := tokenscanner.NewMultiCharacterScanner(testCase.tokenKind, jsonScanner).(*tokenscanner.MultiCharacterScanner)

		actual := scanner.RuneOfToken()
		expected := testCase.expected

		if actual != expected {
			t.Errorf("testCase[%d] expected=%#v, actual=%#v", testIndex, string(expected), string(actual))
		}
	}
}
Пример #11
0
func TestJSONScannerNextPeekRuneWithOffset(t *testing.T) {
	testCaseList := []testCaseForJSONScannerPeekRuneWithOffset{
		{data: "12345678", expected: []rune{'1', '2', '3', '4', '5', '6', '7', '8'}},
	}

	for testIndex, testCase := range testCaseList {
		scanner := scanner.NewJSONScanner(strings.NewReader(testCase.data))
		index := 0
		for expectedIndex, expected := range testCase.expected {
			actual, err := scanner.PeekRuneWithOffset(index)
			index++
			if err != nil {
				t.Fatal(err)
			}

			if actual != expected {
				t.Errorf("testCase[%d:%d] expected=%#v, actual=%#v", testIndex, expectedIndex, expected, actual)
			}
		}
		for expectedIndex, expected := range testCase.expected {
			actual, err := scanner.NextRune()
			if err != nil {
				t.Fatal(err)
			}

			if actual != expected {
				t.Errorf("testCase[%d:%d] expected=%#v, actual=%#v", testIndex, expectedIndex, expected, actual)
			}
		}
		actual, err := scanner.NextNonWhiteSpaceRune()
		if err != io.EOF {
			t.Logf("%s", string([]rune{actual}))
			t.Errorf("testCase[%d] EOF not found", testIndex)
		}
		actual, err = scanner.NextRune()
		if err != io.EOF {
			t.Logf("%s", string([]rune{actual}))
			t.Errorf("testCase[%d] EOF not found, current:%d", testIndex, scanner.CurrentPosition())
		}
	}
}
Пример #12
0
func TestNumber1(t *testing.T) {
	testData := `
	-2.8e-10
	`
	reader := strings.NewReader(testData)
	jsonScanner := scanner.NewJSONScanner(reader)
	scanner := tokenscanner.NewNumberScanner(jsonScanner)
	if !scanner.CanProcess() {
		t.Error("token can't process")
	}

	scannedToken, err := scanner.Scan()
	if err != nil {
		t.Error(err)
	}
	if scannedToken.Kind != token.KindNumber {
		t.Error("token must be number")
	}
	if scannedToken.Value != "-2.8e-10" {
		t.Errorf("token value is wrong: %#v", scannedToken.Value)
	}
}
Пример #13
0
func TestMultiCharacterScannerCanProcess(t *testing.T) {
	testCaseList := []testCaseForTestMultiCharacterScannerCanProcess{
		{data: " null  ", tokenKind: token.KindNull, expected: true},
		{data: " true  ", tokenKind: token.KindTrue, expected: true},
		{data: "false ", tokenKind: token.KindFalse, expected: true},

		{data: "xtrue ", tokenKind: token.KindFalse, expected: false},
		{data: "alse ", tokenKind: token.KindTrue, expected: false},
		{data: "false ", tokenKind: token.KindNull, expected: false},
	}
	for testIndex, testCase := range testCaseList {
		stringReader := strings.NewReader(testCase.data)
		jsonScanner := scanner.NewJSONScanner(stringReader)
		scanner := tokenscanner.NewMultiCharacterScanner(testCase.tokenKind, jsonScanner).(*tokenscanner.MultiCharacterScanner)

		actual := scanner.CanProcess()
		expected := testCase.expected

		if actual != expected {
			t.Errorf("testCase[%d] expected=%#v, actual=%#v", testIndex, expected, actual)
		}
	}
}
Пример #14
0
func TestJSONScannerNextRune(t *testing.T) {
	testCaseList := []testCaseForJSONScannerNextRune{
		{data: "12345678"},
		{data: "abcd efghij"},
	}

	for testIndex, testCase := range testCaseList {
		scanner := scanner.NewJSONScanner(strings.NewReader(testCase.data))
		for expectedIndex, expected := range testCase.data {
			actual, err := scanner.NextRune()
			if err != nil {
				t.Error(err)
			}
			if actual != expected {
				t.Errorf("testCase[%d:%d] expected=%#v, actual=%#v", testIndex, expectedIndex, expected, actual)
			}

		}
		_, err := scanner.NextRune()
		if err != io.EOF {
			t.Errorf("testCase[%d] EOF not found", testIndex)
		}
	}
}
Пример #15
0
func TestSingleCharacterScannerScan(t *testing.T) {
	testCaseList := []testCaseForTestSingleCharacterScannerScan{
		{data: "{", tokenKind: token.KindBeginObject, expected: token.NewToken(token.KindBeginObject, string(token.KindBeginObject))},
		{data: "}", tokenKind: token.KindEndObject, expected: token.NewToken(token.KindEndObject, string(token.KindEndObject))},
		{data: "[", tokenKind: token.KindBeginArray, expected: token.NewToken(token.KindBeginArray, string(token.KindBeginArray))},
		{data: "]", tokenKind: token.KindEndArray, expected: token.NewToken(token.KindEndArray, string(token.KindEndArray))},
		{data: ",", tokenKind: token.KindComma, expected: token.NewToken(token.KindComma, string(token.KindComma))},
		{data: ":", tokenKind: token.KindSeparator, expected: token.NewToken(token.KindSeparator, string(token.KindSeparator))},
	}

	for testIndex, testCase := range testCaseList {
		reader := strings.NewReader(testCase.data)
		jsonScanner := scanner.NewJSONScanner(reader)
		scanner := tokenscanner.NewSingleCharacterScanner(testCase.tokenKind, jsonScanner)
		actual, err := scanner.Scan()
		if err != nil {
			t.Logf("testCase[%d]", testIndex)
			t.Error(err)
		}
		if actual != testCase.expected {
			t.Errorf("testCase[%d] expected=%#v, actual=%#v\n", testIndex, testCase.expected, actual)
		}
	}
}
Пример #16
0
func TestStringScannerScan(t *testing.T) {
	testCaseList := []testCaseForTestStringScannerScan{
		{
			data: `
		"abcdefg"
		`,
			expected: token.NewToken(token.KindString, "abcdefg"),
		},
		{
			data: `
		"\t\n\r\b\f\\\/"
		`,
			expected: token.NewToken(token.KindString,
				`	`+`
`+"\r\b\f\\/"),
		},
		{
			data: `
		"\u65E5\u672C\u8A9E\uD867\uDE3D"
		`,
			expected: token.NewToken(token.KindString, "日本語𩸽"),
		},
	}
	for testIndex, testCase := range testCaseList {
		reader := strings.NewReader(testCase.data)
		jsonScanner := scanner.NewJSONScanner(reader)
		scanner := tokenscanner.NewStringScanner(jsonScanner).(*tokenscanner.StringScanner)
		actual, err := scanner.Scan()
		if err != nil {
			t.Error(err)
		}
		if !testCase.expected.IsEqualTo(actual) {
			t.Errorf("testCase[%d] expected=%#v, actual=%#v", testIndex, testCase.expected, actual)
		}
	}
}
Пример #17
0
func TestTokenizer1(t *testing.T) {
	testData := `
	{
		"key": [
			{
				"inner1": "stringValue",
				"inner2": true,
				"inner3": false,
				"inner4": null,
				"inner5": {
					"nested": -2.5e-3
				}
			}
		]
	}
	`
	reader := strings.NewReader(testData)
	jsonScanner := scanner.NewJSONScanner(reader)

	scanners := []tokenscanner.TokenScanner{
		tokenscanner.NewSingleCharacterScanner(token.KindBeginObject, jsonScanner),
		tokenscanner.NewSingleCharacterScanner(token.KindEndObject, jsonScanner),
		tokenscanner.NewSingleCharacterScanner(token.KindBeginArray, jsonScanner),
		tokenscanner.NewSingleCharacterScanner(token.KindEndArray, jsonScanner),
		tokenscanner.NewSingleCharacterScanner(token.KindSeparator, jsonScanner),
		tokenscanner.NewSingleCharacterScanner(token.KindComma, jsonScanner),

		tokenscanner.NewMultiCharacterScanner(token.KindTrue, jsonScanner),
		tokenscanner.NewMultiCharacterScanner(token.KindFalse, jsonScanner),
		tokenscanner.NewMultiCharacterScanner(token.KindNull, jsonScanner),

		tokenscanner.NewStringScanner(jsonScanner),
		tokenscanner.NewNumberScanner(jsonScanner),
	}

	expectedTokens := []token.Token{
		token.NewToken(token.KindBeginObject, string(token.KindBeginObject)),
		token.NewToken(token.KindString, "key"),
		token.NewToken(token.KindSeparator, string(token.KindSeparator)),
		token.NewToken(token.KindBeginArray, string(token.KindBeginArray)),
		token.NewToken(token.KindBeginObject, string(token.KindBeginObject)),

		token.NewToken(token.KindString, "inner1"),
		token.NewToken(token.KindSeparator, string(token.KindSeparator)),
		token.NewToken(token.KindString, "stringValue"),
		token.NewToken(token.KindComma, string(token.KindComma)),

		token.NewToken(token.KindString, "inner2"),
		token.NewToken(token.KindSeparator, string(token.KindSeparator)),
		token.NewToken(token.KindTrue, string(token.KindTrue)),
		token.NewToken(token.KindComma, string(token.KindComma)),

		token.NewToken(token.KindString, "inner3"),
		token.NewToken(token.KindSeparator, string(token.KindSeparator)),
		token.NewToken(token.KindFalse, string(token.KindFalse)),
		token.NewToken(token.KindComma, string(token.KindComma)),

		token.NewToken(token.KindString, "inner4"),
		token.NewToken(token.KindSeparator, string(token.KindSeparator)),
		token.NewToken(token.KindNull, string(token.KindNull)),
		token.NewToken(token.KindComma, string(token.KindComma)),

		token.NewToken(token.KindString, "inner5"),
		token.NewToken(token.KindSeparator, string(token.KindSeparator)),

		token.NewToken(token.KindBeginObject, string(token.KindBeginObject)),

		token.NewToken(token.KindString, "nested"),
		token.NewToken(token.KindSeparator, string(token.KindSeparator)),
		token.NewToken(token.KindNumber, "-2.5e-3"),

		token.NewToken(token.KindEndObject, string(token.KindEndObject)),

		token.NewToken(token.KindEndObject, string(token.KindEndObject)),
		token.NewToken(token.KindEndArray, string(token.KindEndArray)),
		token.NewToken(token.KindEndObject, string(token.KindEndObject)),
	}

	for {
		if _, err := jsonScanner.PeekNonWhiteSpaceRune(); err == io.EOF {
			break
		}
		for expectedIndex, expected := range expectedTokens {
			for scannerIndex, scanner := range scanners {
				if scanner.CanProcess() {
					actual, err := scanner.Scan()
					if err != nil {
						t.Logf("scanners[%d]: ", scannerIndex)
						t.Error(err)
					}
					if !expected.IsEqualTo(actual) {
						t.Errorf("expected[%d] = %#v, actual = %#v\n", expectedIndex, expected, actual)
					}
					break
				}
			}
		}
	}
}
Пример #18
0
func TestCompositeCase(t *testing.T) {
	testData := `
	{
		false: [true, null,
		{
			null: true
		}]
	}
	`
	expectedString := "{false:[true,null,{null:true}]}"
	expectedTokens := []token.Token{
		token.NewToken(token.KindBeginObject, string(token.KindBeginObject)),
		token.NewToken(token.KindFalse, string(token.KindFalse)),
		token.NewToken(token.KindSeparator, string(token.KindSeparator)),
		token.NewToken(token.KindBeginArray, string(token.KindBeginArray)),
		token.NewToken(token.KindTrue, string(token.KindTrue)),
		token.NewToken(token.KindComma, string(token.KindComma)),
		token.NewToken(token.KindNull, string(token.KindNull)),
		token.NewToken(token.KindComma, string(token.KindComma)),
		token.NewToken(token.KindBeginObject, string(token.KindBeginObject)),
		token.NewToken(token.KindNull, string(token.KindNull)),
		token.NewToken(token.KindSeparator, string(token.KindSeparator)),
		token.NewToken(token.KindTrue, string(token.KindTrue)),
		token.NewToken(token.KindEndObject, string(token.KindEndObject)),
		token.NewToken(token.KindEndArray, string(token.KindEndArray)),
		token.NewToken(token.KindEndObject, string(token.KindEndObject)),
	}

	reader := strings.NewReader(testData)
	jsonScanner := scanner.NewJSONScanner(reader)
	scanners := []tokenscanner.TokenScanner{
		tokenscanner.NewSingleCharacterScanner(token.KindBeginObject, jsonScanner),
		tokenscanner.NewSingleCharacterScanner(token.KindEndObject, jsonScanner),
		tokenscanner.NewSingleCharacterScanner(token.KindBeginArray, jsonScanner),
		tokenscanner.NewSingleCharacterScanner(token.KindEndArray, jsonScanner),
		tokenscanner.NewSingleCharacterScanner(token.KindSeparator, jsonScanner),
		tokenscanner.NewSingleCharacterScanner(token.KindComma, jsonScanner),
		tokenscanner.NewMultiCharacterScanner(token.KindNull, jsonScanner),
		tokenscanner.NewMultiCharacterScanner(token.KindTrue, jsonScanner),
		tokenscanner.NewMultiCharacterScanner(token.KindFalse, jsonScanner),
	}
	var buffer bytes.Buffer
	expectedTokenIndex := 0
	for {
		_, err := jsonScanner.PeekNonWhiteSpaceRune()
		if err == io.EOF {
			break
		}
		for scannerIndex, scanner := range scanners {
			if scanner.CanProcess() {
				scannedToken, err := scanner.Scan()
				if err != nil {
					t.Log(scannerIndex)
					t.Error(err)
				}
				if !expectedTokens[expectedTokenIndex].IsEqualTo(scannedToken) {
					t.Errorf("expected=%#v, actual=%#v", expectedTokens[expectedTokenIndex], scannedToken)
				}
				expectedTokenIndex++
				buffer.WriteString(scannedToken.Value)
			}
		}
	}
	if buffer.String() != expectedString {
		t.Errorf("expected=%#v, actual=%#v", expectedString, buffer.String())
	}
}