125 lines
13 KiB
Bash
Executable File
125 lines
13 KiB
Bash
Executable File
|
|
#!/bin/bash
|
|
|
|
# Input Validation Test Suite for C-Relay
|
|
# Comprehensive testing of input boundary conditions and malformed data
|
|
|
|
set -e
|
|
|
|
# Configuration
|
|
RELAY_HOST="127.0.0.1"
|
|
RELAY_PORT="8888"
|
|
TEST_TIMEOUT=10
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Test counters
|
|
TOTAL_TESTS=0
|
|
PASSED_TESTS=0
|
|
FAILED_TESTS=0
|
|
|
|
# Function to test input validation
|
|
test_input_validation() {
|
|
local description="$1"
|
|
local message="$2"
|
|
local expect_success="${3:-false}"
|
|
|
|
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
|
|
|
echo -n "Testing $description... "
|
|
|
|
# Send message via websocat and capture response
|
|
local response
|
|
response=$(timeout $TEST_TIMEOUT bash -c "
|
|
echo '$message' | websocat -B 1048576 ws://$RELAY_HOST:$RELAY_PORT 2>/dev/null | head -3
|
|
" 2>/dev/null || echo 'TIMEOUT')
|
|
|
|
if [[ "$response" == "TIMEOUT" ]]; then
|
|
echo -e "${RED}FAILED${NC} - Connection timeout"
|
|
FAILED_TESTS=$((FAILED_TESTS + 1))
|
|
return 1
|
|
fi
|
|
|
|
# Check if response indicates success or proper error handling
|
|
if [[ "$expect_success" == "true" ]]; then
|
|
if [[ "$response" == *"EOSE"* ]] || [[ "$response" == *"EVENT"* ]] || [[ ! "$response" == *"error:"* ]]; then
|
|
echo -e "${GREEN}PASSED${NC} - Input accepted correctly"
|
|
PASSED_TESTS=$((PASSED_TESTS + 1))
|
|
return 0
|
|
else
|
|
echo -e "${RED}FAILED${NC} - Valid input rejected: $response"
|
|
FAILED_TESTS=$((FAILED_TESTS + 1))
|
|
return 1
|
|
fi
|
|
else
|
|
if [[ "$response" == *"error:"* ]] || [[ "$response" == *"CONNECTION_FAILED"* ]]; then
|
|
echo -e "${GREEN}PASSED${NC} - Invalid input properly rejected"
|
|
PASSED_TESTS=$((PASSED_TESTS + 1))
|
|
return 0
|
|
else
|
|
echo -e "${RED}FAILED${NC} - Invalid input not rejected: $response"
|
|
FAILED_TESTS=$((FAILED_TESTS + 1))
|
|
return 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
echo "=========================================="
|
|
echo "C-Relay Input Validation Test Suite"
|
|
echo "=========================================="
|
|
echo "Testing against relay at ws://$RELAY_HOST:$RELAY_PORT"
|
|
echo
|
|
|
|
# Test basic connectivity first
|
|
echo "=== Basic Connectivity Test ==="
|
|
test_input_validation "Basic connectivity" '["REQ","basic_test",{}]' true
|
|
echo
|
|
|
|
echo "=== Message Type Validation ==="
|
|
# Test invalid message types
|
|
test_input_validation "Invalid message type - string" '["INVALID","test",{}]' false
|
|
test_input_validation "Invalid message type - number" '[123,"test",{}]' false
|
|
test_input_validation "Invalid message type - null" '[null,"test",{}]' false
|
|
test_input_validation "Invalid message type - object" '[{"type":"invalid"},"test",{}]' false
|
|
test_input_validation "Empty message type" '["","test",{}]' false
|
|
test_input_validation "Very long message type" '["'$(printf 'a%.0s' {1..1000})'","test",{}]' false
|
|
echo
|
|
|
|
echo "=== Message Structure Validation ==="
|
|
# Test malformed message structures
|
|
test_input_validation "Too few arguments" '["REQ"]' false
|
|
test_input_validation "Too many arguments" '["REQ","test",{}, "extra"]' false
|
|
test_input_validation "Non-array message" '"not an array"' false
|
|
test_input_validation "Empty array" '[]' false
|
|
test_input_validation "Nested arrays incorrectly" '[["REQ","test",{}]]' false
|
|
echo
|
|
|
|
echo "=== Subscription ID Boundary Tests ==="
|
|
# Test subscription ID limits
|
|
test_input_validation "Valid subscription ID" '["REQ","valid_sub_123",{}]' true
|
|
test_input_validation "Empty subscription ID" '["REQ","",{}]' false
|
|
test_input_validation "Subscription ID with spaces" '["REQ","sub with spaces",{}]' false
|
|
test_input_validation "Subscription ID with newlines" '["REQ","sub\nwith\nlines",{}]' false
|
|
test_input_validation "Subscription ID with tabs" '["REQ","sub\twith\ttabs",{}]' false
|
|
test_input_validation "Subscription ID with control chars" '["REQ","sub\x01\x02",{}]' false
|
|
test_input_validation "Unicode subscription ID" '["REQ","test🚀",{}]' true
|
|
test_input_validation "Very long subscription ID" '["REQ","'$(printf 'a%.0s' {1..200})'",{}]' false
|
|
echo
|
|
|
|
echo "=== Filter Object Validation ==="
|
|
# Test filter object structure
|
|
test_input_validation "Valid empty filter" '["REQ","test",{}]' true
|
|
test_input_validation "Non-object filter" '["REQ","test","not an object"]' false
|
|
test_input_validation "Null filter" '["REQ","test",null]' false
|
|
test_input_validation "Array filter" '["REQ","test",[]]' false
|
|
test_input_validation "Filter with invalid keys" '["REQ","test",{"invalid_key":"value"}]' false
|
|
echo
|
|
|
|
echo "=== Authors Field Validation ==="
|
|
# Test authors field
|
|
test_input_validation "Valid authors array" '["REQ","test",{"authors":["02c5fc1b6db3f0b0286a7d9a6b4ae3b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c6e8b8c |