diff options
Diffstat (limited to 'pkg/csource')
| -rw-r--r-- | pkg/csource/csource.go | 58 | ||||
| -rw-r--r-- | pkg/csource/csource_test.go | 5 | ||||
| -rw-r--r-- | pkg/csource/options.go | 18 | ||||
| -rw-r--r-- | pkg/csource/syscall_generation_test.go | 201 | ||||
| -rw-r--r-- | pkg/csource/testdata/0 | 25 | ||||
| -rw-r--r-- | pkg/csource/testdata/1 | 80 | ||||
| -rw-r--r-- | pkg/csource/testdata/2 | 144 |
7 files changed, 518 insertions, 13 deletions
diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go index a37040e8f..ecfca80ea 100644 --- a/pkg/csource/csource.go +++ b/pkg/csource/csource.go @@ -74,13 +74,17 @@ func generateSandboxFunctionSignature(sandboxName string, sandboxArg int) string func (ctx *context) generateSource() ([]byte, error) { ctx.filterCalls() - calls, vars, err := ctx.generateProgCalls(ctx.p, ctx.opts.Trace) + calls, vars, err := ctx.generateProgCalls(ctx.p, ctx.opts.Trace, ctx.opts.CallComments) if err != nil { return nil, err } mmapProg := ctx.p.Target.DataMmapProg() - mmapCalls, _, err := ctx.generateProgCalls(mmapProg, false) + // Disable comments on the mmap calls as they are part of the initial setup + // for a program and always very similar. Comments on these provide + // little-to-no additional context that can't be inferred from looking at + // the call arguments directly, and just make the source longer. + mmapCalls, _, err := ctx.generateProgCalls(mmapProg, false, false) if err != nil { return nil, err } @@ -236,7 +240,47 @@ func (ctx *context) generateSyscallDefines() string { return buf.String() } -func (ctx *context) generateProgCalls(p *prog.Prog, trace bool) ([]string, []uint64, error) { +const indent string = " " // Two spaces. +// clang-format produces nicer comments with '//' prefixing versus '/* ... */' style comments. +const commentPrefix string = "//" + +func linesToCStyleComment(lines []string) string { + var commentBuilder strings.Builder + for i, line := range lines { + commentBuilder.WriteString(commentPrefix + indent + line) + if i != len(lines)-1 { + commentBuilder.WriteString("\n") + } + } + return commentBuilder.String() +} + +func generateComment(call *prog.Call) string { + lines := []string{fmt.Sprintf("%s arguments: [", call.Meta.Name)} + for i, arg := range call.Args { + argLines := prog.FormatArg(arg, call.Meta.Args[i].Name) + // Indent the formatted argument. + for i := range argLines { + argLines[i] = indent + argLines[i] + } + lines = append(lines, argLines...) + } + lines = append(lines, "]") + if call.Ret != nil { + lines = append(lines, "returns "+call.Ret.Type().Name()) + } + return linesToCStyleComment(lines) +} + +func (ctx *context) generateProgCalls(p *prog.Prog, trace, addComments bool) ([]string, []uint64, error) { + var comments []string + if addComments { + comments = make([]string, len(p.Calls)) + for i, call := range p.Calls { + comments[i] = generateComment(call) + } + } + exec, err := p.SerializeForExec() if err != nil { return nil, nil, fmt.Errorf("failed to serialize program: %w", err) @@ -245,15 +289,19 @@ func (ctx *context) generateProgCalls(p *prog.Prog, trace bool) ([]string, []uin if err != nil { return nil, nil, err } - calls, vars := ctx.generateCalls(decoded, trace) + calls, vars := ctx.generateCalls(decoded, trace, addComments, comments) return calls, vars, nil } -func (ctx *context) generateCalls(p prog.ExecProg, trace bool) ([]string, []uint64) { +func (ctx *context) generateCalls(p prog.ExecProg, trace, addComments bool, + callComments []string) ([]string, []uint64) { var calls []string csumSeq := 0 for ci, call := range p.Calls { w := new(bytes.Buffer) + if addComments { + w.WriteString(callComments[ci] + "\n") + } // Copyin. for _, copyin := range call.Copyin { ctx.copyin(w, &csumSeq, copyin) diff --git a/pkg/csource/csource_test.go b/pkg/csource/csource_test.go index 3c9cdc360..e48f197c3 100644 --- a/pkg/csource/csource_test.go +++ b/pkg/csource/csource_test.go @@ -285,7 +285,10 @@ syscall(SYS_csource8, /*num=*/(intptr_t)-1); target: test.target, sysTarget: targets.Get(test.target.OS, test.target.Arch), } - calls, _, err := ctx.generateProgCalls(p, false) + // Disable comment generation, as it's not the focus of these tests. + // This simplifies the expected output. For tests covering comments, see + // /pkg/csource/syscall_generation_test.go. + calls, _, err := ctx.generateProgCalls(p, false, false) if err != nil { t.Fatal(err) } diff --git a/pkg/csource/options.go b/pkg/csource/options.go index 74d4a587a..4438e5df2 100644 --- a/pkg/csource/options.go +++ b/pkg/csource/options.go @@ -50,6 +50,9 @@ type Options struct { HandleSegv bool `json:"segv,omitempty"` Trace bool `json:"trace,omitempty"` + + CallComments bool `json:"callcomments,omitempty"` + LegacyOptions } @@ -160,13 +163,14 @@ func (opts Options) checkLinuxOnly(OS string) error { func DefaultOpts(cfg *mgrconfig.Config) Options { opts := Options{ - Threaded: true, - Repeat: true, - Procs: cfg.Procs, - Slowdown: cfg.Timeouts.Slowdown, - Sandbox: cfg.Sandbox, - UseTmpDir: true, - HandleSegv: true, + Threaded: true, + Repeat: true, + Procs: cfg.Procs, + Slowdown: cfg.Timeouts.Slowdown, + Sandbox: cfg.Sandbox, + UseTmpDir: true, + HandleSegv: true, + CallComments: true, } if cfg.TargetOS == targets.Linux { opts.NetInjection = true diff --git a/pkg/csource/syscall_generation_test.go b/pkg/csource/syscall_generation_test.go new file mode 100644 index 000000000..c84cb703b --- /dev/null +++ b/pkg/csource/syscall_generation_test.go @@ -0,0 +1,201 @@ +// Copyright 2025 syzkaller project authors. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. +package csource + +import ( + "bufio" + "flag" + "fmt" + "os" + "path" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/syzkaller/prog" + "github.com/google/syzkaller/sys/targets" + "github.com/stretchr/testify/assert" +) + +var flagUpdate = flag.Bool("update", false, "update test files accordingly to current results") + +type testData struct { + filepath string + // The input syscall description, e.g. bind$netlink(r0, &(0x7f0000514ff4)={0x10, 0x0, 0x0, 0x2ffffffff}, 0xc). + input string + calls []annotatedCall +} + +type annotatedCall struct { + comment string + syscall string +} + +func TestGenerateSyscalls(t *testing.T) { + flag.Parse() + + testCases, err := readTestCases("./testdata") + assert.NoError(t, err) + + target, err := prog.GetTarget(targets.Linux, targets.AMD64) + if err != nil { + t.Fatal(err) + } + + for _, tc := range testCases { + newData, equal := testGenerationImpl(t, tc, target) + if *flagUpdate && !equal { + t.Logf("writing updated contents to %s", tc.filepath) + err = os.WriteFile(tc.filepath, []byte(newData), 0640) + assert.NoError(t, err) + } + } +} + +func readTestCases(dir string) ([]testData, error) { + var testCases []testData + + testFiles, err := os.ReadDir(dir) + if err != nil { + return nil, err + } + + for _, testFile := range testFiles { + if testFile.IsDir() { + continue + } + + testCase, err := readTestData(path.Join(dir, testFile.Name())) + if err != nil { + return nil, err + } + testCases = append(testCases, testCase) + } + + return testCases, nil +} + +func readTestData(filepath string) (testData, error) { + var td testData + td.filepath = filepath + + file, err := os.Open(filepath) + if err != nil { + return testData{}, err + } + + scanner := bufio.NewScanner(file) + + var inputBuilder strings.Builder + for scanner.Scan() { + line := scanner.Text() + if line == "" { + break + } + inputBuilder.WriteString(line + "\n") + } + td.input = inputBuilder.String() + + var commentBuilder strings.Builder + for scanner.Scan() { + line := scanner.Text() + if strings.HasPrefix(line, commentPrefix) { + if commentBuilder.Len() > 0 { + commentBuilder.WriteString("\n") + } + commentBuilder.WriteString(line) + } else { + td.calls = append(td.calls, annotatedCall{ + comment: commentBuilder.String(), + syscall: line, + }) + commentBuilder.Reset() + } + } + + if err := scanner.Err(); err != nil { + return testData{}, err + } + + if commentBuilder.Len() != 0 { + return testData{}, fmt.Errorf("expected a syscall expression but got EOF") + } + return td, nil +} + +// Returns the generated content, and whether or not they were equal. +func testGenerationImpl(t *testing.T, test testData, target *prog.Target) (string, bool) { + p, err := target.Deserialize([]byte(test.input), prog.Strict) + if err != nil { + t.Fatal(err) + } + + // Generate the actual comments. + var actualComments []string + for _, call := range p.Calls { + comment := generateComment(call) + // Formatted comments make comparison easier. + formatted, err := Format([]byte(comment)) + if err != nil { + t.Fatal(err) + } + actualComments = append(actualComments, string(formatted)) + } + + // Minimal options as we are just testing syscall output. + opts := Options{ + Slowdown: 1, + } + ctx := &context{ + p: p, + opts: opts, + target: p.Target, + sysTarget: targets.Get(p.Target.OS, p.Target.Arch), + calls: make(map[string]uint64), + } + + // Partially replicate the flow from csource.go. + exec, err := p.SerializeForExec() + if err != nil { + t.Fatal(err) + } + decoded, err := ctx.target.DeserializeExec(exec, nil) + if err != nil { + t.Fatal(err) + } + var actualSyscalls []string + for _, execCall := range decoded.Calls { + actualSyscalls = append(actualSyscalls, ctx.fmtCallBody(execCall)) + } + + if len(actualSyscalls) != len(test.calls) || len(actualSyscalls) != len(actualComments) { + t.Fatal("Generated inconsistent syscalls or comments.") + } + + areEqual := true + for i := range actualSyscalls { + if diffSyscalls := cmp.Diff(actualSyscalls[i], test.calls[i].syscall); diffSyscalls != "" { + fmt.Print(diffSyscalls) + t.Fail() + areEqual = false + } + if diffComments := cmp.Diff(actualComments[i], test.calls[i].comment); diffComments != "" { + fmt.Print(diffComments) + t.Fail() + areEqual = false + } + } + + var outputBuilder strings.Builder + outputBuilder.WriteString(test.input + "\n") + for i := range actualSyscalls { + outputBuilder.WriteString(actualComments[i] + "\n") + outputBuilder.WriteString(actualSyscalls[i]) + // Avoid trailing newline. + if i != len(test.calls)-1 { + outputBuilder.WriteString("\n") + } + } + + return outputBuilder.String(), areEqual +} diff --git a/pkg/csource/testdata/0 b/pkg/csource/testdata/0 new file mode 100644 index 000000000..1f8c0f959 --- /dev/null +++ b/pkg/csource/testdata/0 @@ -0,0 +1,25 @@ +r0 = socket$netlink(0x10, 0x3, 0x2) +bind$netlink(r0, &(0x7f0000514ff4)={0x10, 0x0, 0x0, 0x2ffffffff}, 0xc) + +// socket$netlink arguments: [ +// domain: const = 0x10 (8 bytes) +// type: const = 0x3 (8 bytes) +// proto: netlink_proto = 0x2 (4 bytes) +// ] +// returns sock_netlink +syscall(__NR_socket, /*domain=*/0x10ul, /*type=*/3ul, /*proto=NETLINK_USERSOCK*/2) +// bind$netlink arguments: [ +// fd: sock_netlink (resource) +// addr: ptr[in, sockaddr_nl_t[AF_NETLINK, netlink_port_id, +// flags[netlink_group_bitmap, int32]]] { +// sockaddr_nl_t[AF_NETLINK, netlink_port_id, flags[netlink_group_bitmap, +// int32]] { +// nl_family: const = 0x10 (2 bytes) +// nl_pad: const = 0x0 (2 bytes) +// nl_pid: int32 = 0x0 (4 bytes) +// nl_groups: netlink_group_bitmap = 0x2ffffffff (4 bytes) +// } +// } +// addrlen: len = 0xc (8 bytes) +// ] +syscall(__NR_bind, /*fd=*/r[0], /*addr=*/0x200000514ff4ul, /*addrlen=*/0xcul)
\ No newline at end of file diff --git a/pkg/csource/testdata/1 b/pkg/csource/testdata/1 new file mode 100644 index 000000000..60af6b708 --- /dev/null +++ b/pkg/csource/testdata/1 @@ -0,0 +1,80 @@ +r0 = openat$iommufd(0xffffffffffffff9c, &(0x7f0000000000), 0x0, 0x0) +ioctl$IOMMU_IOAS_ALLOC(r0, 0x3b81, &(0x7f00000003c0)={0xc, 0x0, <r1=>0x0}) +ioctl$IOMMU_IOAS_MAP$PAGES(r0, 0x3b85, &(0x7f0000000040)={0x28, 0x7, r1, 0x0, &(0x7f0000800000/0x800000)=nil, 0x800000, 0x0}) +ioctl$IOMMU_TEST_OP_CREATE_ACCESS(r0, 0x3ba0, &(0x7f0000000340)={0x48, 0x5, r1, 0x0, <r2=>0xffffffffffffffff, 0x1}) +ioctl$IOMMU_TEST_OP_ACCESS_PAGES$syz(r0, 0x3ba0, &(0x7f0000000100)={0x48, 0x7, r2, 0x0, 0x0, 0x0, 0x200000, 0x0, 0x334e8b, 0x200000000000}) + +// openat$iommufd arguments: [ +// fd: const = 0xffffffffffffff9c (8 bytes) +// file: ptr[in, buffer] { +// buffer: {2f 64 65 76 2f 69 6f 6d 6d 75 00} (length 0xb) +// } +// flags: open_flags = 0x0 (4 bytes) +// mode: const = 0x0 (2 bytes) +// ] +// returns fd_iommufd +syscall(__NR_openat, /*fd=*/0xffffffffffffff9cul, /*file=*/0x200000000000ul, /*flags=*/0, /*mode=*/0) +// ioctl$IOMMU_IOAS_ALLOC arguments: [ +// fd: fd_iommufd (resource) +// cmd: const = 0x3b81 (4 bytes) +// arg: ptr[in, iommu_ioas_alloc] { +// iommu_ioas_alloc { +// size: len = 0xc (4 bytes) +// flags: const = 0x0 (4 bytes) +// out_ioas_id: ioas_handle (resource) +// } +// } +// ] +syscall(__NR_ioctl, /*fd=*/r[0], /*cmd=*/0x3b81, /*arg=*/0x2000000003c0ul) +// ioctl$IOMMU_IOAS_MAP$PAGES arguments: [ +// fd: fd_iommufd (resource) +// cmd: const = 0x3b85 (4 bytes) +// arg: ptr[in, iommu_ioas_map$PAGES] { +// iommu_ioas_map$PAGES { +// size: len = 0x28 (4 bytes) +// flags: iommufd_ioas_map_flags = 0x7 (4 bytes) +// ioas_id: ioas_handle (resource) +// __reserved: const = 0x0 (4 bytes) +// user_va: VMA[0x800000] +// length: len = 0x800000 (8 bytes) +// iova: int64 = 0x0 (8 bytes) +// } +// } +// ] +syscall(__NR_ioctl, /*fd=*/r[0], /*cmd=*/0x3b85, /*arg=*/0x200000000040ul) +// ioctl$IOMMU_TEST_OP_CREATE_ACCESS arguments: [ +// fd: fd_iommufd (resource) +// cmd: const = 0x3ba0 (4 bytes) +// arg: ptr[in, iommu_test_cmd$create_access] { +// iommu_test_cmd$create_access { +// size: len = 0x48 (4 bytes) +// op: const = 0x5 (4 bytes) +// id: ioas_handle (resource) +// __reserved: const = 0x0 (4 bytes) +// out_access_fd: fd_access (resource) +// flags: iommu_test_cmd_create_access_flags = 0x1 (4 bytes) +// pad = 0x0 (48 bytes) +// } +// } +// ] +syscall(__NR_ioctl, /*fd=*/r[0], /*cmd=*/0x3ba0, /*arg=*/0x200000000340ul) +// ioctl$IOMMU_TEST_OP_ACCESS_PAGES$syz arguments: [ +// fd: fd_iommufd (resource) +// cmd: const = 0x3ba0 (4 bytes) +// arg: ptr[in, iommu_test_cmd$access_pages$syz] { +// iommu_test_cmd$access_pages$syz { +// size: len = 0x48 (4 bytes) +// op: const = 0x7 (4 bytes) +// id: fd_access (resource) +// __reserved: const = 0x0 (4 bytes) +// flags: iommu_test_cmd_acess_pages_flags_syz = 0x0 (4 bytes) +// out_access_pages_id: access_pages_handle (resource) +// nth_area: int32 = 0x200000 (4 bytes) +// offset: int32 = 0x0 (4 bytes) +// length: int64 = 0x334e8b (8 bytes) +// uptr: const = 0x200000000000 (8 bytes) +// pad = 0x0 (24 bytes) +// } +// } +// ] +syscall(__NR_ioctl, /*fd=*/r[0], /*cmd=*/0x3ba0, /*arg=*/0x200000000100ul)
\ No newline at end of file diff --git a/pkg/csource/testdata/2 b/pkg/csource/testdata/2 new file mode 100644 index 000000000..10d648d59 --- /dev/null +++ b/pkg/csource/testdata/2 @@ -0,0 +1,144 @@ +#{"repeat":true,"procs":5,"slowdown":1,"sandbox":"none","sandbox_arg":0,"close_fds":true,"swap":true,"tmpdir":true} +syz_mount_image$f2fs(&(0x7f0000000000), &(0x7f0000000040)='./file0\x00', 0x8, &(0x7f0000005880)=ANY=[@ANYBLOB="6e6f646973636172642c6e6f636865636b706f696e745f6d657267652c616c6c6f635f6d6f64653d64656661756c742c6163746976655f6c6f67733d362c666c7573685f6d657267652c6661756c745f696e6a656374696f6e3d30303030303030303030303030303030303032332c646973636172642c6e6f61636c2c6673796e635f6d6f64653d706f7369782c616c6c6f635f6d6f64653d64656661756c742c6e6f657874656e745f63616368652c6163746976655f6c6f67733d322c6661756c745f747970653d30303030303030303030303031363737373231342c0071b1a3325f83482c0961b0e88944923b0c039b5713440e8bfe9b03cd735839577bdc2206c94f19915532121069d31d5b837bfe566213ca848679685540de5aa794f2bdf4daf374cc29c1f1f12dab5e09560694bda1b83f5d21c821f71fdafb606c829fa1b4d0ab1c7c2dd217dcca946abf1257c4b6cf95ae6b5dcaf73d49491efb2e9918a381568b5a081baddf1cbb01ccbb81b50c7c81028797700195adf5fd02a28c78066133dd0cb0014f44eafea1ab502d2192e8ce9f607d392a23940fc95a5a4867f40ad2335db9a6af219433f7fda740407bf1685b1672a903a2ec8019c0000000000000000000"], 0x1, 0x5505, &(0x7f0000000340)="$eJzs3E1rY9UbAPAn7XTe//Mv4sLdXBiEFiZh0nlBd6PO4At2KKMuXGmapCEzSW5p0rR25cKluPCbiIIrl34GF67diQvFnaDknlud+gJC08ZOfz+4ee45OXnuc8Iw8NxbEsCptZj9/GMlrsSFiJiPiMsRxXmlPAp3U3guIq5GxNwTR6Wc/33ibERcjIgrk+QpZ6V869Pr42u3f3jjp6++OXfm0mdffju7XQOz9nxE9DfT+U4/xbyT4qNyvjHuFrF/a1zG9Eb/cTnOU9xprxcZdhr76xpFvNlJ6/PN7eEkbvQazUnsdDeK+c1BuuBw3NnPU3zgUWOrGLfa60XsDvMidvZSXbt76f+2veEo5WmV+T4o0sdotB/TfHu3nfaz+biIzcGonE9581Z7dxLHZSwvF8281yrqWD/MN/3f9mZ3sL2bjdtbw24+yG7X6i/U6neq9a281R61b1Ub/dadW9lSpzdZVh21G/27nTzv9Nq1Zt5fzpY6zWa1Xs+W7rXXu41BVq/XbtZuVG8vl2fXs1cfvJP1WtnSJL7cHWyPur1htpFvZekTy9lK7eaLy9m1evbW6lq29vD+/dW1t9+79+6Dl1Zff6Vc9JeysqWVGysr1fqN6kp9+RTt/6Oy6CnuHw6lMusCAE4e/T8wC0fX/289jDj6/j/0/1Nxovrf097/H8H+4VD0/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp9Z3C5+/VpwspvGlcv5/5dQz5bgSEXMR8evfmI+zB3LOl3kW/mH9wp9q+LoSRYbJNc6Vx8WIuFsev/z/qL8FAAAAeHp98eHVT1K3nl4WZ10QxyndtJm7/P6U8lUiYmHx+yllm5u8PDulZMW/7zOxO6VsxQ2s81NKlm65nZlWtn9l/kA4/0SopDB3rOUAAADH4mAncLxdCAAAAMfp41kXwGxUYv9R5v6z4OIv7/94IHjhwAgAAAA4gSqzLgAAAAA4ckX/7/f/AAAA4OmWfv8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfmPnfm4TB6I4AD8bvLD/tGi1921lb1DGlrDHPUYUkCYoIAfSQhqgBnJLCRFEeBwCEYdIHttK9H2SMxnL/HiD4DAz0gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF26r9aL26vf121zdvt28owGAAAAuGRbrRf1P7PU/9rc/97c+tn0i4goI+LS3H0Un84yR01O9fL8zenz1asa7iLqhMN7TJrrS0T8aa7HH11/CgAAAPBxbZareZqtpz+zoQuiT2nRpvz2N1NeERHV7CFTWnnI+5UprP5+j+N/prR6AWuaKSwtuY1zpb1J/XM/rtpNT5oiNeXFlx2LzDZ2AACgR6Ozpt9ZCAAAAH36N3QBDKOI563M41bgJDXN9t7nsx4AAADwDhVDFwAAAAB0rp7/93T+3975fwAAADCMdP4fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXdpW68VmuZq3zdnt28kzGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHhif95RIATCIAz2ru9M5v6HlQZNTU2qQPj4G4MBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA3v/vL/4mpcSaZe20sPY8ka6fG1qmxd24c/WF8/RoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIv9eUmBEAiCKJgz/nfS9z+sJOgZRIiAhkcVtWgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4It+98v/ialxJpk7bSwdjyRrV42tq8beg8bRg/H2bwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIud+3mNo4oDAP5mZmdrq+IaZQ8RUfCgF7vd1tbexIMSPPgnCCHd1titP9ocbCliLt4k515EjyKCEm/9H3JOIJd4y2EPETwrMzuTnfwA118zm+TzgTfvu8Mw7/tmIeQ77yUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACURm9P4iQ7dMZxXJzb3Hu4lPVbh/rM47Xt+axlcVRn0ifDi9UPUbe5RAAAADg7krK+DyHspOsLWR938vo/La/Jav5vnx7HZT1/uO4v+7L2z9ovP+8+vz9QZzxOdtOby8PBpaOptP6/Wc62Z/7yilb+5PN3L0n+hcTvrT43SvPnGX29sfFOOw/P1ZEtAPBPXCz7Iih/H8r6fpOJAXBmtCqFd1n/J51mcwIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQN3+DAAA//962D6S") +openat(0xffffffffffffff9c, &(0x7f00000000c0)='./file1\x00', 0x8042, 0x0) +mount$bind(0x0, &(0x7f0000005b00)='./bus\x00', 0x0, 0x0, 0x0) +openat(0xffffffffffffff9c, &(0x7f0000000080)='./file0\x00', 0x183341, 0x0) +truncate(&(0x7f0000000280)='./file1\x00', 0x1fefff) +r0 = openat(0xffffffffffffff9c, &(0x7f0000000040)='./file1\x00', 0x42, 0x0) +fallocate(r0, 0x0, 0xeffb, 0x9) +r1 = openat(0xffffffffffffff9c, &(0x7f0000000340)='./file1\x00', 0x44042, 0x1ff) +r2 = openat$nullb(0xffffffffffffff9c, &(0x7f0000000140), 0x2002, 0x0) +sendfile(r1, r2, 0x0, 0x20fffe82) +quotactl$Q_SYNC(0xffffffff80000102, 0x0, 0x0, 0x0) + +// syz_mount_image$f2fs arguments: [ +// fs: ptr[in, buffer] { +// buffer: {66 32 66 73 00} (length 0x5) +// } +// dir: ptr[in, buffer] { +// buffer: {2e 2f 66 69 6c 65 30 00} (length 0x8) +// } +// flags: mount_flags = 0x8 (8 bytes) +// opts: ptr[inout, array[ANYUNION]] { +// array[ANYUNION] { +// union ANYUNION { +// ANYBLOB: buffer: {6e 6f 64 69 73 63 61 72 64 2c 6e 6f 63 68 65 63 6b +// 70 6f 69 6e 74 5f 6d 65 72 67 65 2c 61 6c 6c 6f 63 5f 6d 6f 64 65 3d +// 64 65 66 61 75 6c 74 2c 61 63 74 69 76 65 5f 6c 6f 67 73 3d 36 2c 66 +// 6c 75 73 68 5f 6d 65 72 67 65 2c 66 61 75 6c 74 5f 69 6e 6a 65 63 74 +// 69 6f 6e 3d 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 32 +// 33 2c 64 69 73 63 61 72 64 2c 6e 6f 61 63 6c 2c 66 73 79 6e 63 5f 6d +// 6f 64 65 3d 70 6f 73 69 78 2c 61 6c 6c 6f 63 5f 6d 6f 64 65 3d 64 65 +// 66 61 75 6c 74 2c 6e 6f 65 78 74 65 6e 74 5f 63 61 63 68 65 2c 61 63 +// 74 69 76 65 5f 6c 6f 67 73 3d 32 2c 66 61 75 6c 74 5f 74 79 70 65 3d +// 30 30 30 30 30 30 30 30 30 30 30 30 31 36 37 37 37 32 31 34 2c 00 71 +// b1 a3 32 5f 83 48 2c 09 61 b0 e8 89 44 92 3b 0c 03 9b 57 13 44 0e 8b +// fe 9b 03 cd 73 58 39 57 7b dc 22 06 c9 4f 19 91 55 32 12 10 69 d3 1d +// 5b 83 7b fe 56 62 13 ca 84 86 79 68 55 40 de 5a a7 94 f2 bd f4 da f3 +// 74 cc 29 c1 f1 f1 2d ab 5e 09 56 06 94 bd a1 b8 3f 5d 21 c8 21 f7 1f +// da fb 60 6c 82 9f a1 b4 d0 ab 1c 7c 2d d2 17 dc ca 94 6a bf 12 57 c4 +// b6 cf 95 ae 6b 5d ca f7 3d 49 49 1e fb 2e 99 18 a3 81 56 8b 5a 08 1b +// ad df 1c bb 01 cc bb 81 b5 0c 7c 81 02 87 97 70 01 95 ad f5 fd 02 a2 +// 8c 78 06 61 33 dd 0c b0 01 4f 44 ea fe a1 ab 50 2d 21 92 e8 ce 9f 60 +// 7d 39 2a 23 94 0f c9 5a 5a 48 67 f4 0a d2 33 5d b9 a6 af 21 94 33 f7 +// fd a7 40 40 7b f1 68 5b 16 72 a9 03 a2 ec 80 19 c0 00 00 00 00 00 00 +// 00 00 00} (length 0x1c9) +// } +// } +// } +// chdir: int8 = 0x1 (1 bytes) +// size: len = 0x5505 (8 bytes) +// img: ptr[in, buffer] { +// buffer: (compressed buffer with length 0x5505) +// } +// ] +// returns fd_dir +syz_mount_image(/*fs=*/0x200000000000, /*dir=*/0x200000000040, /*flags=MS_NOEXEC*/8, /*opts=*/0x200000005880, /*chdir=*/1, /*size=*/0x5505, /*img=*/0x200000000340) +// openat arguments: [ +// fd: fd_dir (resource) +// file: ptr[in, buffer] { +// buffer: {2e 2f 66 69 6c 65 31 00} (length 0x8) +// } +// flags: open_flags = 0x8042 (4 bytes) +// mode: open_mode = 0x0 (2 bytes) +// ] +// returns fd +syscall(__NR_openat, /*fd=*/0xffffff9c, /*file=*/0x2000000000c0ul, /*flags=O_LARGEFILE|O_CREAT|O_RDWR*/0x8042, /*mode=*/0) +// mount$bind arguments: [ +// src: nil +// dst: ptr[in, buffer] { +// buffer: {2e 2f 62 75 73 00} (length 0x6) +// } +// type: nil +// flags: mount_flags = 0x0 (8 bytes) +// data: const = 0x0 (8 bytes) +// ] +syscall(__NR_mount, /*src=*/0ul, /*dst=*/0x200000005b00ul, /*type=*/0ul, /*flags=*/0ul, /*data=*/0ul) +// openat arguments: [ +// fd: fd_dir (resource) +// file: ptr[in, buffer] { +// buffer: {2e 2f 66 69 6c 65 30 00} (length 0x8) +// } +// flags: open_flags = 0x183341 (4 bytes) +// mode: open_mode = 0x0 (2 bytes) +// ] +// returns fd +syscall(__NR_openat, /*fd=*/0xffffff9c, /*file=*/0x200000000080ul, /*flags=O_TRUNC|O_SYNC|O_NOCTTY|O_CREAT|O_CLOEXEC|FASYNC|0x1*/0x183341, /*mode=*/0) +// truncate arguments: [ +// file: ptr[in, buffer] { +// buffer: {2e 2f 66 69 6c 65 31 00} (length 0x8) +// } +// len: intptr = 0x1fefff (8 bytes) +// ] +syscall(__NR_truncate, /*file=*/0x200000000280ul, /*len=*/0x1feffful) +// openat arguments: [ +// fd: fd_dir (resource) +// file: ptr[in, buffer] { +// buffer: {2e 2f 66 69 6c 65 31 00} (length 0x8) +// } +// flags: open_flags = 0x42 (4 bytes) +// mode: open_mode = 0x0 (2 bytes) +// ] +// returns fd +syscall(__NR_openat, /*fd=*/0xffffff9c, /*file=*/0x200000000040ul, /*flags=O_CREAT|O_RDWR*/0x42, /*mode=*/0) +// fallocate arguments: [ +// fd: fd (resource) +// mode: fallocate_mode = 0x0 (8 bytes) +// off: intptr = 0xeffb (8 bytes) +// len: intptr = 0x9 (8 bytes) +// ] +syscall(__NR_fallocate, /*fd=*/r[0], /*mode=*/0ul, /*off=*/0xeffbul, /*len=*/9ul) +// openat arguments: [ +// fd: fd_dir (resource) +// file: ptr[in, buffer] { +// buffer: {2e 2f 66 69 6c 65 31 00} (length 0x8) +// } +// flags: open_flags = 0x44042 (4 bytes) +// mode: open_mode = 0x1ff (2 bytes) +// ] +// returns fd +syscall(__NR_openat, /*fd=*/0xffffff9c, /*file=*/0x200000000340ul, /*flags=O_NOATIME|O_DIRECT|O_CREAT|O_RDWR*/0x44042, /*mode=S_IXOTH|S_IWOTH|S_IROTH|S_IXGRP|S_IWGRP|S_IRGRP|S_IXUSR|S_IWUSR|0x100*/0x1ff) +// openat$nullb arguments: [ +// fd: const = 0xffffffffffffff9c (8 bytes) +// file: ptr[in, buffer] { +// buffer: {2f 64 65 76 2f 6e 75 6c 6c 62 30 00} (length 0xc) +// } +// flags: open_flags = 0x2002 (4 bytes) +// mode: const = 0x0 (2 bytes) +// ] +// returns fd_block +syscall(__NR_openat, /*fd=*/0xffffffffffffff9cul, /*file=*/0x200000000140ul, /*flags=FASYNC|O_RDWR*/0x2002, /*mode=*/0) +// sendfile arguments: [ +// fdout: fd (resource) +// fdin: fd (resource) +// off: nil +// count: intptr = 0x20fffe82 (8 bytes) +// ] +syscall(__NR_sendfile, /*fdout=*/r[1], /*fdin=*/r[2], /*off=*/0ul, /*count=*/0x20fffe82ul) +// quotactl$Q_SYNC arguments: [ +// cmd: quota_cmd_sync = 0xffffffff80000102 (8 bytes) +// special: const = 0x0 (8 bytes) +// id: const = 0x0 (8 bytes) +// addr: const = 0x0 (8 bytes) +// ] +syscall(__NR_quotactl, /*cmd=Q_SYNC_PRJ*/0xffffffff80000102ul, /*special=*/0ul, /*id=*/0ul, /*addr=*/0ul)
\ No newline at end of file |
