diff --git a/cmd/tools/fast/fast.v b/cmd/tools/fast/fast.v index ffda1b1467..01293ea630 100644 --- a/cmd/tools/fast/fast.v +++ b/cmd/tools/fast/fast.v @@ -70,7 +70,8 @@ fn main() { date := time.unix(commit_date.int()) mut out := os.create('table.html') ? // Place the new row on top - table = ' + table = + ' $date.format() $commit $message @@ -80,15 +81,15 @@ fn main() { ${diff4}ms \n' + table.trim_space() - out.writeln(table) + out.writeln(table) ? out.close() // Regenerate index.html header := os.read_file('header.html') ? footer := os.read_file('footer.html') ? mut res := os.create('index.html') ? - res.writeln(header) - res.writeln(table) - res.writeln(footer) + res.writeln(header) ? + res.writeln(table) ? + res.writeln(footer) ? res.close() } exec('git checkout master') @@ -96,9 +97,7 @@ fn main() { } fn exec(s string) string { - e := os.exec(s) or { - panic(err) - } + e := os.exec(s) or { panic(err) } return e.output.trim_right('\r\n') } @@ -112,7 +111,7 @@ fn measure(cmd string, description string) int { println(' Building...') mut runs := []int{} for r in 0 .. 5 { - println(' Sample ${r+1}/5') + println(' Sample ${r + 1}/5') sw := time.new_stopwatch({}) exec(cmd) runs << int(sw.elapsed().milliseconds()) diff --git a/cmd/tools/modules/scripting/scripting.v b/cmd/tools/modules/scripting/scripting.v index 826115bb01..2e406a1ec4 100644 --- a/cmd/tools/modules/scripting/scripting.v +++ b/cmd/tools/modules/scripting/scripting.v @@ -12,21 +12,20 @@ pub fn set_verbose(on bool) { // but V does not have globals normally. if on { os.setenv('VERBOSE', '1', true) - } - else { + } else { os.unsetenv('VERBOSE') } } pub fn cprintln(message string) { mut omessage := message - omessage = if term_colors { term.green(omessage) } else { omessage } + omessage = if scripting.term_colors { term.green(omessage) } else { omessage } println(omessage) } pub fn verbose_trace(label string, message string) { if os.getenv('VERBOSE').len > 0 { - slabel := 'scripting.${label}' + slabel := 'scripting.$label' cprintln('# ${slabel:-25s} : $message') } } @@ -54,9 +53,9 @@ pub fn rmrf(path string) { verbose_trace(@FN, 'rm -rf $path') if os.exists(path) { if os.is_dir(path) { - os.rmdir_all(path) - }else{ - os.rm(path) + os.rmdir_all(path) or { panic(err) } + } else { + os.rm(path) or { panic(err) } } } } @@ -97,7 +96,7 @@ pub fn exit_0_status(cmd string) bool { return false } -pub fn tool_must_exist (toolcmd string) { +pub fn tool_must_exist(toolcmd string) { verbose_trace(@FN, toolcmd) if exit_0_status('type $toolcmd') { return diff --git a/cmd/tools/modules/testing/common.v b/cmd/tools/modules/testing/common.v index 6d32597c01..d810eb9e37 100644 --- a/cmd/tools/modules/testing/common.v +++ b/cmd/tools/modules/testing/common.v @@ -210,7 +210,7 @@ pub fn (mut ts TestSession) test() { // cleanup generated .tmp.c files after successfull tests: if ts.benchmark.nfail == 0 { if ts.rm_binaries { - os.rmdir_all(ts.vtmp_dir) + os.rmdir_all(ts.vtmp_dir) or { panic(err) } } } } @@ -241,7 +241,7 @@ fn worker_trunner(mut p sync.PoolProcessor, idx int, thread_id int) voidptr { generated_binary_fpath := os.join_path(tmpd, generated_binary_fname) if os.exists(generated_binary_fpath) { if ts.rm_binaries { - os.rm(generated_binary_fpath) + os.rm(generated_binary_fpath) or { panic(err) } } } mut cmd_options := [ts.vargs] @@ -294,7 +294,7 @@ fn worker_trunner(mut p sync.PoolProcessor, idx int, thread_id int) voidptr { } if os.exists(generated_binary_fpath) { if ts.rm_binaries { - os.rm(generated_binary_fpath) + os.rm(generated_binary_fpath) or { panic(err) } } } return sync.no_result @@ -422,7 +422,7 @@ pub fn header(msg string) { pub fn setup_new_vtmp_folder() string { now := time.sys_mono_now() new_vtmp_dir := os.join_path(os.temp_dir(), 'v', 'test_session_$now') - os.mkdir_all(new_vtmp_dir) + os.mkdir_all(new_vtmp_dir) or { panic(err) } os.setenv('VTMP', new_vtmp_dir, true) return new_vtmp_dir } diff --git a/cmd/tools/test_if_v_test_system_works.v b/cmd/tools/test_if_v_test_system_works.v index f1b94d3437..11596cee27 100644 --- a/cmd/tools/test_if_v_test_system_works.v +++ b/cmd/tools/test_if_v_test_system_works.v @@ -28,26 +28,26 @@ fn get_vexe_path() string { fn new_tdir() string { tdir_ := os.join_path(os.temp_dir(), rand.ulid()) if os.exists(tdir_) { - os.rmdir(tdir_) + os.rmdir(tdir_) or { panic(err) } } - os.mkdir(tdir_) + os.mkdir(tdir_) or { panic(err) } C.atexit(cleanup_tdir) return tdir_ } fn cleanup_tdir() { println('... removing tdir: $tdir') - os.rmdir_all(tdir) + os.rmdir_all(tdir) or { panic(err) } } fn main() { println('> vroot: $vroot | vexe: $vexe | tdir: $tdir') ok_fpath := os.join_path(tdir, 'single_test.v') - os.write_file(ok_fpath, 'fn test_ok(){ assert true }') + os.write_file(ok_fpath, 'fn test_ok(){ assert true }') ? check_ok('"$vexe" $ok_fpath') check_ok('"$vexe" test $ok_fpath') fail_fpath := os.join_path(tdir, 'failing_test.v') - os.write_file(fail_fpath, 'fn test_fail(){ assert 1 == 2 }') + os.write_file(fail_fpath, 'fn test_fail(){ assert 1 == 2 }') ? check_fail('"$vexe" $fail_fpath') check_fail('"$vexe" test $fail_fpath') check_fail('"$vexe" test $tdir') diff --git a/cmd/tools/vbin2v.v b/cmd/tools/vbin2v.v index 8e3ddf8ef8..1396900a57 100644 --- a/cmd/tools/vbin2v.v +++ b/cmd/tools/vbin2v.v @@ -68,7 +68,6 @@ fn (context Context) file2v(bname string, fbytes []byte, bn_max int) string { sb.write('$b, ') line_len += b.len + 2 } - } sb.write(']!\n') return sb.str() @@ -76,8 +75,8 @@ fn (context Context) file2v(bname string, fbytes []byte, bn_max int) string { fn (context Context) bname_and_bytes(file string) ?(string, []byte) { fname := os.file_name(file) - fname_escpaed := fname.replace_each(['.', '_', '-', '_']) - byte_name := '$context.prefix$fname_escpaed'.to_lower() + fname_escaped := fname.replace_each(['.', '_', '-', '_']) + byte_name := '$context.prefix$fname_escaped'.to_lower() fbytes := os.read_bytes(file) or { return error('Error: $err') } return byte_name, fbytes } @@ -131,12 +130,12 @@ fn main() { } max_bname := context.max_bname_len(file_byte_map.keys()) if context.write_file.len > 0 { - mut out_file := os.create(context.write_file) or { panic(err) } - out_file.write_str(context.header()) + mut out_file := os.create(context.write_file) ? + out_file.write_str(context.header()) ? for bname, fbytes in file_byte_map { - out_file.write_str(context.file2v(bname, fbytes, max_bname)) + out_file.write_str(context.file2v(bname, fbytes, max_bname)) ? } - out_file.write_str(context.footer()) + out_file.write_str(context.footer()) ? } else { print(context.header()) for bname, fbytes in file_byte_map { diff --git a/cmd/tools/vbuild-tools.v b/cmd/tools/vbuild-tools.v index ded3eb18f4..3a06e7479f 100644 --- a/cmd/tools/vbuild-tools.v +++ b/cmd/tools/vbuild-tools.v @@ -55,9 +55,14 @@ fn main() { // tpath := os.join_path(session.vtmp_dir, texe) if tname in tools_in_subfolders { - os.mv_by_cp(tpath, os.join_path(tfolder, tname, texe)) + os.mv_by_cp(tpath, os.join_path(tfolder, tname, texe)) or { panic(err) } + continue + } + os.mv_by_cp(tpath, os.join_path(tfolder, texe)) or { + if !err.contains('vbuild-tools') { + eprintln(err) + } continue } - os.mv_by_cp(tpath, os.join_path(tfolder, texe)) } } diff --git a/cmd/tools/vcreate.v b/cmd/tools/vcreate.v index 6a2c766408..6d17249a48 100644 --- a/cmd/tools/vcreate.v +++ b/cmd/tools/vcreate.v @@ -58,7 +58,7 @@ fn (c &Create) write_vmod(new bool) { cerror(err) exit(1) } - vmod.write_str(vmod_content(c.name, c.description)) + vmod.write_str(vmod_content(c.name, c.description)) or { panic(err) } vmod.close() } @@ -67,12 +67,12 @@ fn (c &Create) write_main(new bool) { return } main_path := if new { '$c.name/${c.name}.v' } else { '${c.name}.v' } - mut main := os.create(main_path) or { + mut mainfile := os.create(main_path) or { cerror(err) exit(2) } - main.write_str(main_content()) - main.close() + mainfile.write_str(main_content()) or { panic(err) } + mainfile.close() } fn (c &Create) create_git_repo(dir string) { @@ -87,7 +87,7 @@ fn (c &Create) create_git_repo(dir string) { // We don't really need a .gitignore, it's just a nice-to-have return } - fl.write_str(gen_gitignore(c.name)) + fl.write_str(gen_gitignore(c.name)) or { panic(err) } fl.close() } } @@ -110,9 +110,7 @@ fn create() { } c.description = os.input('Input your project description: ') println('Initialising ...') - os.mkdir(c.name) or { - panic(err) - } + os.mkdir(c.name) or { panic(err) } c.write_vmod(true) c.write_main(true) c.create_git_repo(c.name) diff --git a/cmd/tools/vdoc/html.v b/cmd/tools/vdoc/html.v index a885db973a..f69735fbbb 100644 --- a/cmd/tools/vdoc/html.v +++ b/cmd/tools/vdoc/html.v @@ -126,7 +126,7 @@ fn (vd VDoc) render_search_index(out Output) { js_search_index.writeln('];') js_search_data.writeln('];') out_file_path := os.join_path(out.path, 'search_index.js') - os.write_file(out_file_path, js_search_index.str() + js_search_data.str()) + os.write_file(out_file_path, js_search_index.str() + js_search_data.str()) or { panic(err) } } fn (mut vd VDoc) render_static_html(out Output) { @@ -162,7 +162,7 @@ fn (vd VDoc) get_resource(name string, out Output) string { output_path := os.join_path(out.path, name) if !os.exists(output_path) { println('Generating $out.typ in "$output_path"') - os.write_file(output_path, res) + os.write_file(output_path, res) or { panic(err) } } return name } diff --git a/cmd/tools/vdoc/vdoc.v b/cmd/tools/vdoc/vdoc.v index 70c2324215..fc022cfd51 100644 --- a/cmd/tools/vdoc/vdoc.v +++ b/cmd/tools/vdoc/vdoc.v @@ -162,7 +162,7 @@ fn (vd VDoc) work_processor(mut work sync.Channel, mut wg sync.WaitGroup) { file_name, content := vd.render_doc(pdoc.d, pdoc.out) output_path := os.join_path(pdoc.out.path, file_name) println('Generating $pdoc.out.typ in "$output_path"') - os.write_file(output_path, content) + os.write_file(output_path, content) or { panic(err) } } wg.done() } @@ -358,7 +358,7 @@ fn (mut vd VDoc) generate_docs_from_file() { os.mkdir(out.path) or { panic(err) } } else { for fname in css_js_assets { - os.rm(os.join_path(out.path, fname)) + os.rm(os.join_path(out.path, fname)) or { panic(err) } } } } @@ -376,7 +376,7 @@ fn (mut vd VDoc) generate_docs_from_file() { for favicon in favicons { favicon_path := os.join_path(favicons_path, favicon) destination_path := os.join_path(out.path, favicon) - os.cp(favicon_path, destination_path) + os.cp(favicon_path, destination_path) or { panic(err) } } } } diff --git a/cmd/tools/vfmt.v b/cmd/tools/vfmt.v index e4a92acfe1..cf9dbbfafc 100644 --- a/cmd/tools/vfmt.v +++ b/cmd/tools/vfmt.v @@ -176,7 +176,7 @@ fn (foptions &FormatOptions) format_file(file string) { file_name := os.file_name(file) ulid := rand.ulid() vfmt_output_path := os.join_path(vtmp_folder, 'vfmt_${ulid}_$file_name') - os.write_file(vfmt_output_path, formatted_content) + os.write_file(vfmt_output_path, formatted_content) or { panic(err) } if foptions.is_verbose { eprintln('fmt.fmt worked and $formatted_content.len bytes were written to $vfmt_output_path .') } @@ -258,7 +258,8 @@ fn (foptions &FormatOptions) post_process_file(file string, formatted_file_path } fn (f FormatOptions) str() string { - return 'FormatOptions{ is_l: $f.is_l, is_w: $f.is_w, is_diff: $f.is_diff, is_verbose: $f.is_verbose,' + + return + 'FormatOptions{ is_l: $f.is_l, is_w: $f.is_w, is_diff: $f.is_diff, is_verbose: $f.is_verbose,' + ' is_all: $f.is_all, is_worker: $f.is_worker, is_debug: $f.is_debug, is_noerror: $f.is_noerror,' + ' is_verify: $f.is_verify" }' } diff --git a/cmd/tools/vpm.v b/cmd/tools/vpm.v index dafe053b98..e6d8c3a56a 100644 --- a/cmd/tools/vpm.v +++ b/cmd/tools/vpm.v @@ -19,15 +19,15 @@ const ( supported_vcs_folders = ['.git', '.hg'] supported_vcs_update_cmds = { 'git': 'git pull' - 'hg': 'hg pull --update' + 'hg': 'hg pull --update' } supported_vcs_install_cmds = { 'git': 'git clone --depth=1' - 'hg': 'hg clone' + 'hg': 'hg clone' } supported_vcs_outdated_steps = { 'git': ['git fetch', 'git rev-parse @', 'git rev-parse @{u}'] - 'hg': ['hg incoming'] + 'hg': ['hg incoming'] } ) @@ -71,9 +71,7 @@ fn main() { 'install' { if module_names.len == 0 && os.exists('./v.mod') { println('Detected v.mod file inside the project directory. Using it...') - manifest := vmod.from_file('./v.mod') or { - panic(err) - } + manifest := vmod.from_file('./v.mod') or { panic(err) } module_names = manifest.dependencies } vpm_install(module_names) @@ -227,15 +225,11 @@ fn vpm_update(m []string) { } mut errors := 0 for name in module_names { - final_module_path := valid_final_path_of_existing_module(name) or { - continue - } + final_module_path := valid_final_path_of_existing_module(name) or { continue } os.chdir(final_module_path) println('Updating module "$name"...') verbose_println(' work folder: $final_module_path') - vcs := vcs_used_in_dir(final_module_path) or { - continue - } + vcs := vcs_used_in_dir(final_module_path) or { continue } vcs_cmd := supported_vcs_update_cmds[vcs[0]] verbose_println(' command: $vcs_cmd') vcs_res := os.exec('$vcs_cmd') or { @@ -265,13 +259,9 @@ fn get_outdated() ?[]string { module_names := get_installed_modules() mut outdated := []string{} for name in module_names { - final_module_path := valid_final_path_of_existing_module(name) or { - continue - } + final_module_path := valid_final_path_of_existing_module(name) or { continue } os.chdir(final_module_path) - vcs := vcs_used_in_dir(final_module_path) or { - continue - } + vcs := vcs_used_in_dir(final_module_path) or { continue } vcs_cmd_steps := supported_vcs_outdated_steps[vcs[0]] mut outputs := []string{} for step in vcs_cmd_steps { @@ -296,9 +286,7 @@ fn get_outdated() ?[]string { } fn vpm_upgrade() { - outdated := get_outdated() or { - exit(1) - } + outdated := get_outdated() or { exit(1) } if outdated.len > 0 { vpm_update(outdated) } else { @@ -307,9 +295,7 @@ fn vpm_upgrade() { } fn vpm_outdated() { - outdated := get_outdated() or { - exit(1) - } + outdated := get_outdated() or { exit(1) } if outdated.len > 0 { println('Outdated modules:') for m in outdated { @@ -342,18 +328,16 @@ fn vpm_remove(module_names []string) { exit(2) } for name in module_names { - final_module_path := valid_final_path_of_existing_module(name) or { - continue - } + final_module_path := valid_final_path_of_existing_module(name) or { continue } println('Removing module "$name"...') verbose_println('removing folder $final_module_path') - os.rmdir_all(final_module_path) + os.rmdir_all(final_module_path) or { panic(err) } // delete author directory if it is empty author := name.split('.')[0] author_dir := os.real_path(os.join_path(settings.vmodules_path, author)) if os.is_dir_empty(author_dir) { verbose_println('removing author folder $author_dir') - os.rmdir(author_dir) + os.rmdir(author_dir) or { panic(err) } } } } @@ -380,9 +364,7 @@ fn valid_final_path_of_existing_module(name string) ?string { fn ensure_vmodules_dir_exist() { if !os.is_dir(settings.vmodules_path) { println('Creating $settings.vmodules_path/ ...') - os.mkdir(settings.vmodules_path) or { - panic(err) - } + os.mkdir(settings.vmodules_path) or { panic(err) } } } @@ -405,9 +387,7 @@ fn vcs_used_in_dir(dir string) ?[]string { } fn get_installed_modules() []string { - dirs := os.ls(settings.vmodules_path) or { - return [] - } + dirs := os.ls(settings.vmodules_path) or { return [] } mut modules := []string{} for dir in dirs { adir := os.join_path(settings.vmodules_path, dir) @@ -420,13 +400,9 @@ fn get_installed_modules() []string { continue } author := dir - mods := os.ls(adir) or { - continue - } + mods := os.ls(adir) or { continue } for m in mods { - vcs_used_in_dir(os.join_path(adir, m)) or { - continue - } + vcs_used_in_dir(os.join_path(adir, m)) or { continue } modules << '${author}.$m' } } @@ -435,9 +411,7 @@ fn get_installed_modules() []string { fn get_all_modules() []string { url := get_working_server_url() - r := http.get(url) or { - panic(err) - } + r := http.get(url) or { panic(err) } if r.status_code != 200 { println('Failed to search vpm.vlang.io. Status code: $r.status_code') exit(1) @@ -476,9 +450,7 @@ fn resolve_dependencies(name string, module_path string, module_names []string) if !os.exists(vmod_path) { return } - data := os.read_file(vmod_path) or { - return - } + data := os.read_file(vmod_path) or { return } vmod := parse_vmod(data) mut deps := []string{} // filter out dependencies that were already specified by the user @@ -497,14 +469,12 @@ fn resolve_dependencies(name string, module_path string, module_names []string) fn parse_vmod(data string) Vmod { keys := ['name', 'version', 'deps'] mut m := { - 'name': '' + 'name': '' 'version': '' - 'deps': '' + 'deps': '' } for key in keys { - mut key_index := data.index('$key:') or { - continue - } + mut key_index := data.index('$key:') or { continue } key_index += key.len + 1 m[key] = data[key_index..data.index_after('\n', key_index)].trim_space().replace("'", '').replace('[', '').replace(']', '') @@ -519,7 +489,11 @@ fn parse_vmod(data string) Vmod { } fn get_working_server_url() string { - server_urls := if settings.server_urls.len > 0 { settings.server_urls } else { default_vpm_server_urls } + server_urls := if settings.server_urls.len > 0 { + settings.server_urls + } else { + default_vpm_server_urls + } for url in server_urls { verbose_println('Trying server url: $url') http.head(url) or { @@ -572,13 +546,11 @@ fn get_module_meta_info(name string) ?Mod { continue } if r.status_code == 404 || r.text.contains('404') { - errors << - 'Skipping module "$name", since $server_url reported that "$name" does not exist.' + errors << 'Skipping module "$name", since $server_url reported that "$name" does not exist.' continue } if r.status_code != 200 { - errors << - 'Skipping module "$name", since $server_url responded with $r.status_code http status code. Please try again later.' + errors << 'Skipping module "$name", since $server_url responded with $r.status_code http status code. Please try again later.' continue } s := r.text diff --git a/cmd/tools/vrepl.v b/cmd/tools/vrepl.v index 1b90fbef3c..82e917b880 100644 --- a/cmd/tools/vrepl.v +++ b/cmd/tools/vrepl.v @@ -11,10 +11,10 @@ import v.util struct Repl { mut: - readline readline.Readline - indent int // indentation level - in_func bool // are we inside a new custom user function - line string // the current line entered by the user + readline readline.Readline + indent int // indentation level + in_func bool // are we inside a new custom user function + line string // the current line entered by the user // modules []string // all the import modules includes []string // all the #include statements @@ -109,21 +109,7 @@ fn run_repl(workdir string, vrepl_prefix string) { if !is_stdin_a_pipe { println('') } - os.rm(file) - os.rm(temp_file) - $if windows { - os.rm(file[..file.len - 2] + '.exe') - os.rm(temp_file[..temp_file.len - 2] + '.exe') - $if msvc { - os.rm(file[..file.len - 2] + '.ilk') - os.rm(file[..file.len - 2] + '.pdb') - os.rm(temp_file[..temp_file.len - 2] + '.ilk') - os.rm(temp_file[..temp_file.len - 2] + '.pdb') - } - } $else { - os.rm(file[..file.len - 2]) - os.rm(temp_file[..temp_file.len - 2]) - } + cleanup_files([file, temp_file]) } mut r := new_repl() vexe := os.getenv('VEXE') @@ -198,7 +184,7 @@ fn run_repl(workdir string, vrepl_prefix string) { } if r.line.starts_with('print') { source_code := r.current_source_code(false) + '\n$r.line\n' - os.write_file(file, source_code) + os.write_file(file, source_code) or { panic(err) } s := os.exec('"$vexe" -repl run "$file"') or { rerror(err) return @@ -208,7 +194,7 @@ fn run_repl(workdir string, vrepl_prefix string) { mut temp_line := r.line mut temp_flag := false func_call := r.function_call(r.line) - filter_line := r.line.replace(r.line.find_between("\'", "\'"), '').replace(r.line.find_between('"', + filter_line := r.line.replace(r.line.find_between("'", "'"), '').replace(r.line.find_between('"', '"'), '') possible_statement_patterns := [ '=', @@ -268,7 +254,7 @@ fn run_repl(workdir string, vrepl_prefix string) { } temp_source_code = r.current_source_code(true) + '\n$temp_line\n' } - os.write_file(temp_file, temp_source_code) + os.write_file(temp_file, temp_source_code) or { panic(err) } s := os.exec('"$vexe" -repl run "$temp_file"') or { rerror(err) return @@ -355,3 +341,18 @@ fn (mut r Repl) get_one_line(prompt string) ?string { rline := r.readline.read_line(prompt) or { return none } return rline } + +fn cleanup_files(files []string) { + for file in files { + os.rm(file) or { } + $if windows { + os.rm(file[..file.len - 2] + '.exe') or { } + $if msvc { + os.rm(file[..file.len - 2] + '.ilk') or { } + os.rm(file[..file.len - 2] + '.pdb') or { } + } + } $else { + os.rm(file[..file.len - 2]) or { } + } + } +} diff --git a/cmd/tools/vsymlink.v b/cmd/tools/vsymlink.v index ddc73210e4..4eb2e0800f 100644 --- a/cmd/tools/vsymlink.v +++ b/cmd/tools/vsymlink.v @@ -4,6 +4,7 @@ import v.pref $if windows { $if tinyc { #flag -lAdvapi32 + #flag -lUser32 } } @@ -19,20 +20,16 @@ fn main() { fn setup_symlink(vexe string) { link_dir := '/usr/local/bin' if !os.exists(link_dir) { - os.mkdir_all(link_dir) + os.mkdir_all(link_dir) or { panic(err) } } mut link_path := link_dir + '/v' - mut ret := os.exec('ln -sf $vexe $link_path') or { - panic(err) - } + mut ret := os.exec('ln -sf $vexe $link_path') or { panic(err) } if ret.exit_code == 0 { println('Symlink "$link_path" has been created') - } else if os.system("uname -o | grep -q \'[A/a]ndroid\'") == 0 { + } else if os.system("uname -o | grep -q '[A/a]ndroid'") == 0 { println('Failed to create symlink "$link_path". Trying again with Termux path for Android.') link_path = '/data/data/com.termux/files/usr/bin/v' - ret = os.exec('ln -sf $vexe $link_path') or { - panic(err) - } + ret = os.exec('ln -sf $vexe $link_path') or { panic(err) } if ret.exit_code == 0 { println('Symlink "$link_path" has been created') } else { @@ -52,9 +49,9 @@ fn setup_symlink_windows(vexe string) { vsymlinkdir := os.join_path(vdir, '.bin') mut vsymlink := os.join_path(vsymlinkdir, 'v.exe') if !os.exists(vsymlinkdir) { - os.mkdir_all(vsymlinkdir) // will panic if fails + os.mkdir_all(vsymlinkdir) or { panic(err) } // will panic if fails } else { - os.rm(vsymlink) + os.rm(vsymlink) or { panic(err) } } // First, try to create a native symlink at .\.bin\v.exe os.symlink(vsymlink, vexe) or { @@ -64,9 +61,9 @@ fn setup_symlink_windows(vexe string) { eprintln('Creating a batch file instead...') vsymlink = os.join_path(vsymlinkdir, 'v.bat') if os.exists(vsymlink) { - os.rm(vsymlink) + os.rm(vsymlink) or { panic(err) } } - os.write_file(vsymlink, '@echo off\n$vexe %*') + os.write_file(vsymlink, '@echo off\n$vexe %*') or { panic(err) } eprintln('$vsymlink file written.') } if !os.exists(vsymlink) { @@ -83,9 +80,7 @@ fn setup_symlink_windows(vexe string) { // C.RegCloseKey(reg_sys_env_handle) // } // if the above succeeded, and we cannot get the value, it may simply be empty - sys_env_path := get_reg_value(reg_sys_env_handle, 'Path') or { - '' - } + sys_env_path := get_reg_value(reg_sys_env_handle, 'Path') or { '' } current_sys_paths := sys_env_path.split(os.path_delimiter).map(it.trim('/$os.path_separator')) mut new_paths := [vsymlinkdir] for p in current_sys_paths { @@ -171,8 +166,7 @@ fn set_reg_value(reg_key voidptr, key string, value string) ?bool { // letting them know that the system environment has changed and should be reloaded fn send_setting_change_msg(message_data string) ?bool { $if windows { - if C.SendMessageTimeout(os.hwnd_broadcast, os.wm_settingchange, 0, message_data.to_wide(), os.smto_abortifhung, 5000, 0) == - 0 { + if C.SendMessageTimeout(os.hwnd_broadcast, os.wm_settingchange, 0, message_data.to_wide(), os.smto_abortifhung, 5000, 0) == 0 { return error('Could not broadcast WM_SETTINGCHANGE') } return true diff --git a/cmd/tools/vup.v b/cmd/tools/vup.v index 63354b3bcd..225e48f782 100644 --- a/cmd/tools/vup.v +++ b/cmd/tools/vup.v @@ -108,9 +108,9 @@ fn (app App) show_current_v_version() { fn (app App) backup(file string) { backup_file := '${file}_old.exe' if os.exists(backup_file) { - os.rm(backup_file) + os.rm(backup_file) or { panic(err) } } - os.mv(file, backup_file) + os.mv(file, backup_file) or { panic(err) } } fn (app App) git_command(command string) { diff --git a/cmd/tools/vwipe-cache.v b/cmd/tools/vwipe-cache.v index a72be1c845..e5761def40 100644 --- a/cmd/tools/vwipe-cache.v +++ b/cmd/tools/vwipe-cache.v @@ -7,7 +7,7 @@ fn main() { mut cm := vcache.new_cache_manager([]) cpath := cm.basepath if os.exists(cpath) && os.is_dir(cpath) { - os.rmdir_all(cpath) + os.rmdir_all(cpath) or { } } println('V cache folder $cpath was wiped.') } diff --git a/examples/net_raw_http.v b/examples/net_raw_http.v index 4acff57c7e..1b71183e0b 100644 --- a/examples/net_raw_http.v +++ b/examples/net_raw_http.v @@ -3,12 +3,14 @@ import io fn main() { // Make a new connection - mut conn := net.dial_tcp('google.com:80')? - defer { conn.close() } + mut conn := net.dial_tcp('google.com:80') ? + defer { + conn.close() or { } + } // Simple http HEAD request for a file - conn.write_str('HEAD /index.html HTTP/1.0\r\n\r\n')? + conn.write_str('HEAD /index.html HTTP/1.0\r\n\r\n') ? // Read all the data that is waiting - result := io.read_all(reader: conn)? + result := io.read_all(reader: conn) ? // Cast to string and print result println(result.bytestr()) } diff --git a/examples/path_tracing.v b/examples/path_tracing.v index 588cd22ecc..b07503499b 100644 --- a/examples/path_tracing.v +++ b/examples/path_tracing.v @@ -35,67 +35,63 @@ const ( f_0 = 0.0 ) -/***************************** 3D Vector utility struct **********************/ +//**************************** 3D Vector utility struct ********************* struct Vec { mut: - x f64 = 0.0 - y f64 = 0.0 - z f64 = 0.0 + x f64 = 0.0 + y f64 = 0.0 + z f64 = 0.0 } [inline] -fn (v Vec) + (b Vec) Vec{ - return Vec{ v.x + b.x , v.y + b.y, v.z + b.z } +fn (v Vec) + (b Vec) Vec { + return Vec{v.x + b.x, v.y + b.y, v.z + b.z} } [inline] -fn (v Vec) - (b Vec) Vec{ - return Vec{ v.x - b.x , v.y - b.y, v.z - b.z } +fn (v Vec) - (b Vec) Vec { + return Vec{v.x - b.x, v.y - b.y, v.z - b.z} } [inline] -fn (v Vec) * (b Vec) Vec{ - return Vec{ v.x * b.x , v.y * b.y, v.z * b.z } +fn (v Vec) * (b Vec) Vec { + return Vec{v.x * b.x, v.y * b.y, v.z * b.z} } [inline] -fn (v Vec) dot (b Vec) f64{ +fn (v Vec) dot(b Vec) f64 { return v.x * b.x + v.y * b.y + v.z * b.z } [inline] -fn (v Vec) mult_s (b f64) Vec{ - return Vec{ v.x * b , v.y * b, v.z * b } +fn (v Vec) mult_s(b f64) Vec { + return Vec{v.x * b, v.y * b, v.z * b} } [inline] -fn (v Vec) cross (b Vec) Vec{ - return Vec{ - v.y * b.z - v.z * b.y, - v.z * b.x - v.x * b.z, - v.x * b.y - v.y * b.x - } +fn (v Vec) cross(b Vec) Vec { + return Vec{v.y * b.z - v.z * b.y, v.z * b.x - v.x * b.z, v.x * b.y - v.y * b.x} } [inline] -fn (v Vec) norm () Vec { +fn (v Vec) norm() Vec { tmp_norm := 1.0 / math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z) - return Vec{ v.x * tmp_norm , v.y * tmp_norm, v.z * tmp_norm } + return Vec{v.x * tmp_norm, v.y * tmp_norm, v.z * tmp_norm} } -/*********************************Image***************************************/ +//********************************Image************************************** struct Image { - width int + width int height int - data &Vec + data &Vec } fn new_image(w int, h int) Image { vecsize := int(sizeof(Vec)) return Image{ - width: w, - height: h, - data: &Vec(vcalloc(vecsize*w*h)) + width: w + height: h + data: &Vec(vcalloc(vecsize * w * h)) } } @@ -103,19 +99,19 @@ fn new_image(w int, h int) Image { fn (image Image) save_as_ppm(file_name string) { npixels := image.width * image.height mut f_out := os.create(file_name) or { panic(err) } - f_out.writeln('P3') - f_out.writeln('${image.width} ${image.height}') - f_out.writeln('255') - for i in 0..npixels { - c_r := to_int(unsafe{image.data[i]}.x) - c_g := to_int(unsafe{image.data[i]}.y) - c_b := to_int(unsafe{image.data[i]}.z) - f_out.write_str('$c_r $c_g $c_b ') + f_out.writeln('P3') or { panic(err) } + f_out.writeln('$image.width $image.height') or { panic(err) } + f_out.writeln('255') or { panic(err) } + for i in 0 .. npixels { + c_r := to_int(unsafe { image.data[i] }.x) + c_g := to_int(unsafe { image.data[i] }.y) + c_b := to_int(unsafe { image.data[i] }.z) + f_out.write_str('$c_r $c_g $c_b ') or { panic(err) } } f_out.close() } -/*********************************** Ray *************************************/ +//********************************** Ray ************************************ struct Ray { o Vec d Vec @@ -128,19 +124,19 @@ enum Refl_t { refr } -/********************************* Sphere ************************************/ +//******************************** Sphere *********************************** struct Sphere { - rad f64 = 0.0 // radius - p Vec // position - e Vec // emission - c Vec // color - refl Refl_t // reflection type => [diffuse, specular, refractive] + rad f64 = 0.0 // radius + p Vec // position + e Vec // emission + c Vec // color + refl Refl_t // reflection type => [diffuse, specular, refractive] } -fn (sp Sphere) intersect (r Ray) f64 { - op := sp.p - r.o // Solve t^2*d.d + 2*t*(o-p).d + (o-p).(o-p)-R^2 = 0 - b := op.dot(r.d) - mut det := b * b - op.dot(op) + sp.rad * sp.rad +fn (sp Sphere) intersect(r Ray) f64 { + op := sp.p - r.o // Solve t^2*d.d + 2*t*(o-p).d + (o-p).(o-p)-R^2 = 0 + b := op.dot(r.d) + mut det := b * b - op.dot(op) + sp.rad * sp.rad if det < 0 { return 0 @@ -167,82 +163,181 @@ fn (sp Sphere) intersect (r Ray) f64 { * The sphere fileds are: Sphere{radius, position, emission, color, material} ******************************************************************************/ const ( -cen = Vec{50, 40.8, -860} // used by scene 1 -spheres = [ -[// scene 0 cornnel box - Sphere{rad: 1e+5, p: Vec{ 1e+5 +1,40.8,81.6} , e: Vec{} , c: Vec{.75,.25,.25} , refl: .diff},//Left - Sphere{rad: 1e+5, p: Vec{-1e+5 +99,40.8,81.6}, e: Vec{} , c: Vec{.25,.25,.75} , refl: .diff},//Rght - Sphere{rad: 1e+5, p: Vec{50,40.8, 1e+5} , e: Vec{} , c: Vec{.75,.75,.75} , refl: .diff},//Back - Sphere{rad: 1e+5, p: Vec{50,40.8,-1e+5 +170} , e: Vec{} , c: Vec{} , refl: .diff},//Frnt - Sphere{rad: 1e+5, p: Vec{50, 1e+5, 81.6} , e: Vec{} , c: Vec{.75,.75,.75} , refl: .diff},//Botm - Sphere{rad: 1e+5, p: Vec{50,-1e+5 +81.6,81.6}, e: Vec{} , c: Vec{.75,.75,.75} , refl: .diff},//Top - Sphere{rad: 16.5, p: Vec{27,16.5,47} , e: Vec{} , c: Vec{1,1,1}.mult_s(.999) , refl: .spec},//Mirr - Sphere{rad: 16.5, p: Vec{73,16.5,78} , e: Vec{} , c: Vec{1,1,1}.mult_s(.999) , refl: .refr},//Glas - Sphere{rad: 600 , p: Vec{50,681.6-.27,81.6} , e: Vec{12,12,12}, c: Vec{}, refl: .diff} //Lite -], - -[// scene 1 sunset - Sphere{rad: 1600, p: Vec{1.0,0.0,2.0}.mult_s(3000), e: Vec{1.0,.9,.8}.mult_s(1.2e+1*1.56*2) , c: Vec{} , refl: .diff}, // sun - Sphere{rad: 1560, p: Vec{1,0,2}.mult_s(3500) , e: Vec{1.0,.5,.05}.mult_s(4.8e+1*1.56*2) , c: Vec{} , refl: .diff}, // horizon sun2 - Sphere{rad: 10000, p: cen+Vec{0,0,-200}, e: Vec{0.00063842, 0.02001478, 0.28923243}.mult_s(6e-2*8), c: Vec{.7,.7,1}.mult_s(.25), refl: .diff}, // sky - - Sphere{rad: 100000, p: Vec{50, -100000, 0} , e: Vec{} , c: Vec{.3,.3,.3} , refl: .diff}, // grnd - Sphere{rad: 110000, p: Vec{50, -110048.5, 0} , e: Vec{.9,.5,.05}.mult_s(4) , c: Vec{}, refl: .diff},// horizon brightener - Sphere{rad: 4e+4 , p: Vec{50, -4e+4-30, -3000}, e: Vec{} , c: Vec{.2,.2,.2} , refl: .diff},// mountains - - Sphere{rad: 26.5, p: Vec{22,26.5,42}, e: Vec{}, c: Vec{1,1,1}.mult_s(.596) , refl: .spec}, // white Mirr - Sphere{rad: 13, p: Vec{75,13,82 }, e: Vec{}, c: Vec{.96,.96,.96}.mult_s(.96), refl: .refr},// Glas - Sphere{rad: 22, p: Vec{87,22,24 }, e: Vec{}, c: Vec{.6,.6,.6}.mult_s(.696) , refl: .refr} // Glas2 -], - - -[// scene 3 Psychedelic - Sphere{rad: 150, p: Vec{50+75,28,62}, e: Vec{1,1,1}.mult_s(0e-3), c: Vec{1,.9,.8}.mult_s(.93), refl: .refr}, - Sphere{rad: 28 , p: Vec{50+5,-28,62}, e: Vec{1,1,1}.mult_s(1e+1), c: Vec{1,1,1}.mult_s(0) , refl: .diff}, - Sphere{rad: 300, p: Vec{50,28,62} , e: Vec{1,1,1}.mult_s(0e-3), c: Vec{1,1,1}.mult_s(.93) , refl: .spec} -] - -] // end of scene array - + cen = Vec{50, 40.8, -860} // used by scene 1 + spheres = [ + [/* scene 0 cornnel box */ Sphere{ + rad: 1e+5 + p: Vec{1e+5 + 1, 40.8, 81.6} + e: Vec{} + c: Vec{.75, .25, .25} + refl: .diff + }, /* Left */ Sphere{ + rad: 1e+5 + p: Vec{-1e+5 + 99, 40.8, 81.6} + e: Vec{} + c: Vec{.25, .25, .75} + refl: .diff + }, /* Rght */ Sphere{ + rad: 1e+5 + p: Vec{50, 40.8, 1e+5} + e: Vec{} + c: Vec{.75, .75, .75} + refl: .diff + }, /* Back */ Sphere{ + rad: 1e+5 + p: Vec{50, 40.8, -1e+5 + 170} + e: Vec{} + c: Vec{} + refl: .diff + }, /* Frnt */ Sphere{ + rad: 1e+5 + p: Vec{50, 1e+5, 81.6} + e: Vec{} + c: Vec{.75, .75, .75} + refl: .diff + }, /* Botm */ Sphere{ + rad: 1e+5 + p: Vec{50, -1e+5 + 81.6, 81.6} + e: Vec{} + c: Vec{.75, .75, .75} + refl: .diff + }, /* Top */ Sphere{ + rad: 16.5 + p: Vec{27, 16.5, 47} + e: Vec{} + c: Vec{1, 1, 1}.mult_s(.999) + refl: .spec + }, /* Mirr */ Sphere{ + rad: 16.5 + p: Vec{73, 16.5, 78} + e: Vec{} + c: Vec{1, 1, 1}.mult_s(.999) + refl: .refr + }, /* Glas */ Sphere{ + rad: 600 + p: Vec{50, 681.6 - .27, 81.6} + e: Vec{12, 12, 12} + c: Vec{} + refl: .diff + } /* Lite */], + [/* scene 1 sunset */ Sphere{ + rad: 1600 + p: Vec{1.0, 0.0, 2.0}.mult_s(3000) + e: Vec{1.0, .9, .8}.mult_s(1.2e+1 * 1.56 * 2) + c: Vec{} + refl: .diff + }, /* sun */ Sphere{ + rad: 1560 + p: Vec{1, 0, 2}.mult_s(3500) + e: Vec{1.0, .5, .05}.mult_s(4.8e+1 * 1.56 * 2) + c: Vec{} + refl: .diff + }, /* horizon sun2 */ Sphere{ + rad: 10000 + p: cen + Vec{0, 0, -200} + e: Vec{0.00063842, 0.02001478, 0.28923243}.mult_s(6e-2 * 8) + c: Vec{.7, .7, 1}.mult_s(.25) + refl: .diff + }, /* sky */ Sphere{ + rad: 100000 + p: Vec{50, -100000, 0} + e: Vec{} + c: Vec{.3, .3, .3} + refl: .diff + }, /* grnd */ Sphere{ + rad: 110000 + p: Vec{50, -110048.5, 0} + e: Vec{.9, .5, .05}.mult_s(4) + c: Vec{} + refl: .diff + }, /* horizon brightener */ Sphere{ + rad: 4e+4 + p: Vec{50, -4e+4 - 30, -3000} + e: Vec{} + c: Vec{.2, .2, .2} + refl: .diff + }, /* mountains */ Sphere{ + rad: 26.5 + p: Vec{22, 26.5, 42} + e: Vec{} + c: Vec{1, 1, 1}.mult_s(.596) + refl: .spec + }, /* white Mirr */ Sphere{ + rad: 13 + p: Vec{75, 13, 82} + e: Vec{} + c: Vec{.96, .96, .96}.mult_s(.96) + refl: .refr + }, /* Glas */ Sphere{ + rad: 22 + p: Vec{87, 22, 24} + e: Vec{} + c: Vec{.6, .6, .6}.mult_s(.696) + refl: .refr + } /* Glas2 */], + [/* scene 3 Psychedelic */ Sphere{ + rad: 150 + p: Vec{50 + 75, 28, 62} + e: Vec{1, 1, 1}.mult_s(0e-3) + c: Vec{1, .9, .8}.mult_s(.93) + refl: .refr + }, Sphere{ + rad: 28 + p: Vec{50 + 5, -28, 62} + e: Vec{1, 1, 1}.mult_s(1e+1) + c: Vec{1, 1, 1}.mult_s(0) + refl: .diff + }, Sphere{ + rad: 300 + p: Vec{50, 28, 62} + e: Vec{1, 1, 1}.mult_s(0e-3) + c: Vec{1, 1, 1}.mult_s(.93) + refl: .spec + }], + ] // end of scene array ) -/*********************************** Utilities *******************************/ +//********************************** Utilities ****************************** [inline] fn clamp(x f64) f64 { - if x < 0 { return 0 } - if x > 1 { return 1 } + if x < 0 { + return 0 + } + if x > 1 { + return 1 + } return x } [inline] fn to_int(x f64) int { - p := math.pow(clamp(x), 1.0/2.2) - return int(p*255.0+0.5) + p := math.pow(clamp(x), 1.0 / 2.2) + return int(p * 255.0 + 0.5) } -fn intersect(r Ray, spheres &Sphere, nspheres int) (bool, f64, int){ - mut d := 0.0 - mut t := inf +fn intersect(r Ray, spheres &Sphere, nspheres int) (bool, f64, int) { + mut d := 0.0 + mut t := inf mut id := 0 - for i:=nspheres-1; i >= 0; i-- { - d = unsafe{spheres[i]}.intersect(r) + for i := nspheres - 1; i >= 0; i-- { + d = unsafe { spheres[i] }.intersect(r) if d > 0 && d < t { t = d id = i } } - return (t < inf) , t, id + return (t < inf), t, id } // some casual random function, try to avoid the 0 fn rand_f64() f64 { x := rand.u32() & 0x3FFF_FFFF - return f64(x)/f64(0x3FFF_FFFF) + return f64(x) / f64(0x3FFF_FFFF) } -const( - cache_len = 65536 // the 2*pi angle will be splitted in 65536 part - cache_mask = cache_len - 1 // mask to speed-up the module process +const ( + cache_len = 65536 // the 2*pi angle will be splitted in 65536 part + cache_mask = cache_len - 1 // mask to speed-up the module process ) struct Cache { @@ -254,7 +349,7 @@ mut: fn new_tabs() Cache { mut c := Cache{} inv_len := 1.0 / f64(cache_len) - for i in 0..cache_len { + for i in 0 .. cache_len { x := f64(i) * math.pi * 2.0 * inv_len c.sin_tab[i] = math.sin(x) c.cos_tab[i] = math.cos(x) @@ -262,31 +357,34 @@ fn new_tabs() Cache { return c } -/************* Cache for sin/cos speed-up table and scene selector ***********/ +//************ Cache for sin/cos speed-up table and scene selector ********** const ( tabs = new_tabs() ) -/******************* main function for the radiance calculation **************/ +//****************** main function for the radiance calculation ************* fn radiance(r Ray, depthi int, scene_id int) Vec { if depthi > 1024 { eprintln('depthi: $depthi') return Vec{} } - mut depth := depthi // actual depth in the reflection tree - mut t := 0.0 // distance to intersection - mut id := 0 // id of intersected object - mut res := false // result of intersect + mut depth := depthi // actual depth in the reflection tree + mut t := 0.0 // distance to intersection + mut id := 0 // id of intersected object + mut res := false // result of intersect v_1 := 1.0 - //v_2 := f64(2.0) + // v_2 := f64(2.0) scene := spheres[scene_id] - //res, t, id = intersect(r, id, tb.scene) + // res, t, id = intersect(r, id, tb.scene) res, t, id = intersect(r, scene.data, scene.len) - if !res { return Vec{} } //if miss, return black + if !res { + return Vec{} + } + // if miss, return black - obj := scene[id] // the hit object + obj := scene[id] // the hit object x := r.o + r.d.mult_s(t) n := (x - obj.p).norm() @@ -308,100 +406,95 @@ fn radiance(r Ray, depthi int, scene_id int) Vec { depth++ if depth > 5 { if rand_f64() < p { - f = f.mult_s(f64(1.0)/p) + f = f.mult_s(f64(1.0) / p) } else { - return obj.e //R.R. + return obj.e // R.R. } } - if obj.refl == .diff { // Ideal DIFFUSE reflection + if obj.refl == .diff { // Ideal DIFFUSE reflection // **Full Precision** - //r1 := f64(2.0 * math.pi) * rand_f64() + // r1 := f64(2.0 * math.pi) * rand_f64() // tabbed speed-up r1 := rand.u32() & cache_mask - r2 := rand_f64() + r2 := rand_f64() r2s := math.sqrt(r2) - w := nl + w := nl - mut u := if math.abs(w.x) > f64(0.1) { - Vec{0, 1, 0} - } else { - Vec{1, 0, 0} - } + mut u := if math.abs(w.x) > f64(0.1) { Vec{0, 1, 0} } else { Vec{1, 0, 0} } u = u.cross(w).norm() v := w.cross(u) // **Full Precision** - //d := (u.mult_s(math.cos(r1) * r2s) + v.mult_s(math.sin(r1) * r2s) + w.mult_s(1.0 - r2)).norm() + // d := (u.mult_s(math.cos(r1) * r2s) + v.mult_s(math.sin(r1) * r2s) + w.mult_s(1.0 - r2)).norm() // tabbed speed-up - d := (u.mult_s(tabs.cos_tab[r1] * r2s) + v.mult_s(tabs.sin_tab[r1] * r2s) + w.mult_s(math.sqrt(f64(1.0) - r2))).norm() + d := (u.mult_s(tabs.cos_tab[r1] * r2s) + v.mult_s(tabs.sin_tab[r1] * r2s) + + w.mult_s(math.sqrt(f64(1.0) - r2))).norm() return obj.e + f * radiance(Ray{x, d}, depth, scene_id) } else { - if obj.refl == .spec { // Ideal SPECULAR reflection - return obj.e + f * radiance(Ray{x, r.d - n.mult_s(2.0 * n.dot(r.d)) }, depth, scene_id) + if obj.refl == .spec { // Ideal SPECULAR reflection + return obj.e + f * radiance(Ray{x, r.d - n.mult_s(2.0 * n.dot(r.d))}, depth, scene_id) } } - refl_ray := Ray{x, r.d - n.mult_s(2.0 * n.dot(r.d))} // Ideal dielectric REFRACTION - into := n.dot(nl) > 0 // Ray from outside going in? + refl_ray := Ray{x, r.d - n.mult_s(2.0 * n.dot(r.d))} // Ideal dielectric REFRACTION + into := n.dot(nl) > 0 // Ray from outside going in? - nc := f64(1.0) - nt := f64(1.5) + nc := f64(1.0) + nt := f64(1.5) nnt := if into { nc / nt } else { nt / nc } - ddn := r.d.dot(nl) + ddn := r.d.dot(nl) cos2t := v_1 - nnt * nnt * (v_1 - ddn * ddn) - if cos2t < 0.0 { // Total internal reflection + if cos2t < 0.0 { // Total internal reflection return obj.e + f * radiance(refl_ray, depth, scene_id) } dirc := if into { f64(1) } else { f64(-1) } tdir := (r.d.mult_s(nnt) - n.mult_s(dirc * (ddn * nnt + math.sqrt(cos2t)))).norm() - a := nt - nc - b := nt + nc + a := nt - nc + b := nt + nc r0 := a * a / (b * b) - c := if into { v_1 + ddn } else { v_1 - tdir.dot(n) } + c := if into { v_1 + ddn } else { v_1 - tdir.dot(n) } re := r0 + (v_1 - r0) * c * c * c * c * c tr := v_1 - re - pp := f64(.25) + f64(.5) * re + pp := f64(.25) + f64(.5) * re rp := re / pp tp := tr / (v_1 - pp) mut tmp := Vec{} if depth > 2 { // Russian roulette - tmp = if rand_f64() < pp { - radiance(refl_ray, depth, scene_id).mult_s(rp) - } else { - radiance(Ray{x, tdir}, depth, scene_id).mult_s(tp) - } + tmp = if rand_f64() < pp { radiance(refl_ray, depth, scene_id).mult_s(rp) } else { radiance(Ray{x, tdir}, + depth, scene_id).mult_s(tp) } } else { - tmp = (radiance(refl_ray, depth, scene_id).mult_s(re)) + (radiance( Ray{x, tdir}, depth, scene_id).mult_s(tr)) + tmp = (radiance(refl_ray, depth, scene_id).mult_s(re)) + + (radiance(Ray{x, tdir}, depth, scene_id).mult_s(tr)) } return obj.e + (f * tmp) } -/************************ beam scan routine **********************************/ +//*********************** beam scan routine ********************************* fn ray_trace(w int, h int, samps int, file_name string, scene_id int) Image { image := new_image(w, h) // inverse costants - w1 := f64(1.0 / f64(w)) - h1 := f64(1.0 / f64(h)) + w1 := f64(1.0 / f64(w)) + h1 := f64(1.0 / f64(h)) samps1 := f64(1.0 / f64(samps)) - cam := Ray{Vec{50, 52, 295.6}, Vec{0, -0.042612, -1}.norm()} // cam position, direction - cx := Vec{ f64(w) * 0.5135 / f64(h), 0, 0} - cy := cx.cross(cam.d).norm().mult_s(0.5135) + cam := Ray{Vec{50, 52, 295.6}, Vec{0, -0.042612, -1}.norm()} // cam position, direction + cx := Vec{f64(w) * 0.5135 / f64(h), 0, 0} + cy := cx.cross(cam.d).norm().mult_s(0.5135) mut r := Vec{} // speed-up constants @@ -409,28 +502,28 @@ fn ray_trace(w int, h int, samps int, file_name string, scene_id int) Image { v_2 := f64(2.0) // OpenMP injection point! #pragma omp parallel for schedule(dynamic, 1) shared(c) - for y:=0; y < h; y++ { - eprint("\rRendering (${samps * 4} spp) ${(100.0 * f64(y)) / (f64(h) - 1.0):5.2f}%") - for x in 0..w { - + for y := 0; y < h; y++ { + eprint('\rRendering (${samps * 4} spp) ${(100.0 * f64(y)) / (f64(h) - 1.0):5.2f}%') + for x in 0 .. w { i := (h - y - 1) * w + x - mut ivec := unsafe{&image.data[i]} + mut ivec := unsafe { &image.data[i] } // we use sx and sy to perform a square subsampling of 4 samples - for sy := 0; sy < 2; sy ++ { - for sx := 0; sx < 2; sx ++ { - r = Vec{0,0,0} - for _ in 0..samps { + for sy := 0; sy < 2; sy++ { + for sx := 0; sx < 2; sx++ { + r = Vec{0, 0, 0} + for _ in 0 .. samps { r1 := v_2 * rand_f64() dx := if r1 < v_1 { math.sqrt(r1) - v_1 } else { v_1 - math.sqrt(v_2 - r1) } r2 := v_2 * rand_f64() dy := if r2 < v_1 { math.sqrt(r2) - v_1 } else { v_1 - math.sqrt(v_2 - r2) } - d := cx.mult_s( ( (f64(sx) + 0.5 + dx)*0.5 + f64(x))*w1 - .5) + - cy.mult_s( ( (f64(sy) + 0.5 + dy)*0.5 + f64(y))*h1 - .5) + cam.d - r = r + radiance(Ray{cam.o+d.mult_s(140.0), d.norm()}, 0, scene_id).mult_s(samps1) + d := cx.mult_s(((f64(sx) + 0.5 + dx) * 0.5 + f64(x)) * w1 - .5) + + cy.mult_s(((f64(sy) + 0.5 + dy) * 0.5 + f64(y)) * h1 - .5) + cam.d + r = r + radiance(Ray{cam.o + + d.mult_s(140.0), d.norm()}, 0, scene_id).mult_s(samps1) } - tmp_vec := Vec{clamp(r.x),clamp(r.y),clamp(r.z)}.mult_s(.25) + tmp_vec := Vec{clamp(r.x), clamp(r.y), clamp(r.z)}.mult_s(.25) (*ivec) = *ivec + tmp_vec } } @@ -446,7 +539,7 @@ fn main() { } mut width := 320 // width of the rendering in pixels mut height := 200 // height of the rendering in pixels - mut samples := 4 // number of samples per pixel, increase for better quality + mut samples := 4 // number of samples per pixel, increase for better quality mut scene_id := 0 // scene to render [0 cornell box,1 sunset,2 psyco] mut file_name := 'image.ppm' // name of the output file in .ppm format @@ -465,20 +558,18 @@ fn main() { if os.args.len == 6 { height = os.args[5].int() } - // change the seed for a different result rand.seed([u32(2020), 0]) - t1:=time.ticks() + t1 := time.ticks() image := ray_trace(width, height, samples, file_name, scene_id) - t2:=time.ticks() + t2 := time.ticks() + eprintln('\nRendering finished. Took: ${(t2 - t1):5}ms') - eprintln('\nRendering finished. Took: ${(t2-t1):5}ms') + image.save_as_ppm(file_name) + t3 := time.ticks() - image.save_as_ppm( file_name ) - t3:=time.ticks() - - eprintln('Image saved as [${file_name}]. Took: ${(t3-t2):5}ms') + eprintln('Image saved as [$file_name]. Took: ${(t3 - t2):5}ms') } diff --git a/examples/term.ui/cursor_chaser.v b/examples/term.ui/cursor_chaser.v index 72b51f6166..c8e4545258 100644 --- a/examples/term.ui/cursor_chaser.v +++ b/examples/term.ui/cursor_chaser.v @@ -2,12 +2,12 @@ import term.ui as tui const ( colors = [ - tui.Color{33, 150, 243} - tui.Color{0, 150, 136} - tui.Color{205, 220, 57} - tui.Color{255, 152, 0} - tui.Color{244, 67, 54} - tui.Color{156, 39, 176} + tui.Color{33, 150, 243}, + tui.Color{0, 150, 136}, + tui.Color{205, 220, 57}, + tui.Color{255, 152, 0}, + tui.Color{244, 67, 54}, + tui.Color{156, 39, 176}, ] ) @@ -66,27 +66,33 @@ fn event(e &tui.Event, x voidptr) { } .space, .enter { app.color_idx++ - if app.color_idx == colors.len { app.color_idx = 0 } + if app.color_idx == colors.len { + app.color_idx = 0 + } app.color = colors[app.color_idx] - } else {} + } + else {} } - } .mouse_move, .mouse_drag, .mouse_down { - app.points << Point{ e.x, e.y } - } .mouse_scroll { + } + .mouse_move, .mouse_drag, .mouse_down { + app.points << Point{e.x, e.y} + } + .mouse_scroll { d := if e.direction == .up { 0.1 } else { -0.1 } app.cut_rate += d - if app.cut_rate < 1 { app.cut_rate = 1 } - } else {} + if app.cut_rate < 1 { + app.cut_rate = 1 + } + } + else {} } } mut app := &App{} app.tui = tui.init( - user_data: app, - frame_fn: frame, - event_fn: event, - + user_data: app + frame_fn: frame + event_fn: event hide_cursor: true ) - -app.tui.run() +app.tui.run() ? diff --git a/examples/term.ui/event_viewer.v b/examples/term.ui/event_viewer.v index d78bf372c5..50dd0bd683 100644 --- a/examples/term.ui/event_viewer.v +++ b/examples/term.ui/event_viewer.v @@ -11,29 +11,35 @@ fn event(e &tui.Event, x voidptr) { app.tui.set_cursor_position(0, 0) app.tui.write('V term.input event viewer (press `esc` to exit)\n\n') app.tui.write('$e') - app.tui.write('\n\nRaw event bytes: "${e.utf8.bytes().hex()}" = ${e.utf8.bytes()}') + app.tui.write('\n\nRaw event bytes: "$e.utf8.bytes().hex()" = $e.utf8.bytes()') if e.modifiers != 0 { app.tui.write('\nModifiers: $e.modifiers = ') - if e.modifiers & tui.ctrl != 0 { app.tui.write('ctrl. ') } - if e.modifiers & tui.shift != 0 { app.tui.write('shift ') } - if e.modifiers & tui.alt != 0 { app.tui.write('alt. ') } + if e.modifiers & tui.ctrl != 0 { + app.tui.write('ctrl. ') + } + if e.modifiers & tui.shift != 0 { + app.tui.write('shift ') + } + if e.modifiers & tui.alt != 0 { + app.tui.write('alt. ') + } } app.tui.flush() - if e.typ == .key_down && e.code == .escape { exit(0) } + if e.typ == .key_down && e.code == .escape { + exit(0) + } } mut app := &App{} app.tui = tui.init( - user_data: app, + user_data: app event_fn: event - window_title: 'V term.ui event viewer' hide_cursor: true capture_events: true frame_rate: 60 use_alternate_buffer: false ) - println('V term.ui event viewer (press `esc` to exit)\n\n') -app.tui.run() +app.tui.run() ? diff --git a/examples/term.ui/pong.v b/examples/term.ui/pong.v index 93af6c970d..925b9d4fb7 100644 --- a/examples/term.ui/pong.v +++ b/examples/term.ui/pong.v @@ -19,7 +19,7 @@ const ( struct App { mut: tui &ui.Context = 0 - mode Mode = Mode.menu + mode Mode = Mode.menu width int height int game &Game = 0 @@ -35,10 +35,10 @@ fn (mut a App) init() { a.width = w a.height = h term.erase_del_clear() - term.set_cursor_position({ + term.set_cursor_position( x: 0 y: 0 - }) + ) } fn (mut a App) start_game() { @@ -66,10 +66,10 @@ fn (mut a App) quit() { a.game.quit() return } - term.set_cursor_position({ + term.set_cursor_position( x: 0 y: 0 - }) + ) exit(0) } @@ -482,7 +482,7 @@ fn event(e &ui.Event, x voidptr) { // main mut app := &App{} -app.tui = ui.init({ +app.tui = ui.init( user_data: app init_fn: init frame_fn: frame @@ -492,5 +492,5 @@ app.tui = ui.init({ capture_events: true hide_cursor: true frame_rate: 60 -}) -app.tui.run() +) +app.tui.run() ? diff --git a/examples/term.ui/rectangles.v b/examples/term.ui/rectangles.v index 20d0fa81e1..d316fee672 100644 --- a/examples/term.ui/rectangles.v +++ b/examples/term.ui/rectangles.v @@ -34,8 +34,8 @@ fn event(e &tui.Event, x voidptr) { app.is_drag = true app.cur_rect = { c: random_color() - x: e.x - y: e.y + x: e.x + y: e.y x2: e.x y2: e.y } @@ -43,20 +43,28 @@ fn event(e &tui.Event, x voidptr) { .mouse_drag { app.cur_rect.x2 = e.x app.cur_rect.y2 = e.y - } .mouse_up { + } + .mouse_up { app.rects << app.cur_rect app.is_drag = false - } .key_down { - if e.code == .c { app.rects.clear() } - else if e.code == .escape { exit(0) } - } else {} + } + .key_down { + if e.code == .c { + app.rects.clear() + } else if e.code == .escape { + exit(0) + } + } + else {} } app.redraw = true } fn frame(x voidptr) { mut app := &App(x) - if !app.redraw { return } + if !app.redraw { + return + } app.tui.clear() @@ -76,15 +84,12 @@ fn frame(x voidptr) { app.redraw = false } - mut app := &App{} app.tui = tui.init( - user_data: app, - event_fn: event, + user_data: app + event_fn: event frame_fn: frame - hide_cursor: true frame_rate: 60 ) - -app.tui.run() +app.tui.run() ? diff --git a/examples/term.ui/term_drawing.v b/examples/term.ui/term_drawing.v index c6b91b2a9c..e6fd25880f 100644 --- a/examples/term.ui/term_drawing.v +++ b/examples/term.ui/term_drawing.v @@ -3,73 +3,73 @@ // that can be found in the LICENSE file. module main -import term.ui as tui +import term.ui // The color palette, taken from Google's Material design const ( colors = [ [ - tui.Color{239, 154, 154}, - tui.Color{244, 143, 177}, - tui.Color{206, 147, 216}, - tui.Color{179, 157, 219}, - tui.Color{159, 168, 218}, - tui.Color{144, 202, 249}, - tui.Color{129, 212, 250}, - tui.Color{128, 222, 234}, - tui.Color{128, 203, 196}, - tui.Color{165, 214, 167}, - tui.Color{197, 225, 165}, - tui.Color{230, 238, 156}, - tui.Color{255, 245, 157}, - tui.Color{255, 224, 130}, - tui.Color{255, 204, 128}, - tui.Color{255, 171, 145}, - tui.Color{188, 170, 164}, - tui.Color{238, 238, 238}, - tui.Color{176, 190, 197}, + ui.Color{239, 154, 154}, + ui.Color{244, 143, 177}, + ui.Color{206, 147, 216}, + ui.Color{179, 157, 219}, + ui.Color{159, 168, 218}, + ui.Color{144, 202, 249}, + ui.Color{129, 212, 250}, + ui.Color{128, 222, 234}, + ui.Color{128, 203, 196}, + ui.Color{165, 214, 167}, + ui.Color{197, 225, 165}, + ui.Color{230, 238, 156}, + ui.Color{255, 245, 157}, + ui.Color{255, 224, 130}, + ui.Color{255, 204, 128}, + ui.Color{255, 171, 145}, + ui.Color{188, 170, 164}, + ui.Color{238, 238, 238}, + ui.Color{176, 190, 197}, ], [ - tui.Color{244, 67, 54}, - tui.Color{233, 30, 99}, - tui.Color{156, 39, 176}, - tui.Color{103, 58, 183}, - tui.Color{63, 81, 181}, - tui.Color{33, 150, 243}, - tui.Color{3, 169, 244}, - tui.Color{0, 188, 212}, - tui.Color{0, 150, 136}, - tui.Color{76, 175, 80}, - tui.Color{139, 195, 74}, - tui.Color{205, 220, 57}, - tui.Color{255, 235, 59}, - tui.Color{255, 193, 7}, - tui.Color{255, 152, 0}, - tui.Color{255, 87, 34}, - tui.Color{121, 85, 72}, - tui.Color{120, 120, 120}, - tui.Color{96, 125, 139}, + ui.Color{244, 67, 54}, + ui.Color{233, 30, 99}, + ui.Color{156, 39, 176}, + ui.Color{103, 58, 183}, + ui.Color{63, 81, 181}, + ui.Color{33, 150, 243}, + ui.Color{3, 169, 244}, + ui.Color{0, 188, 212}, + ui.Color{0, 150, 136}, + ui.Color{76, 175, 80}, + ui.Color{139, 195, 74}, + ui.Color{205, 220, 57}, + ui.Color{255, 235, 59}, + ui.Color{255, 193, 7}, + ui.Color{255, 152, 0}, + ui.Color{255, 87, 34}, + ui.Color{121, 85, 72}, + ui.Color{120, 120, 120}, + ui.Color{96, 125, 139}, ], [ - tui.Color{198, 40, 40}, - tui.Color{173, 20, 87}, - tui.Color{106, 27, 154}, - tui.Color{69, 39, 160}, - tui.Color{40, 53, 147}, - tui.Color{21, 101, 192}, - tui.Color{2, 119, 189}, - tui.Color{0, 131, 143}, - tui.Color{0, 105, 92}, - tui.Color{46, 125, 50}, - tui.Color{85, 139, 47}, - tui.Color{158, 157, 36}, - tui.Color{249, 168, 37}, - tui.Color{255, 143, 0}, - tui.Color{239, 108, 0}, - tui.Color{216, 67, 21}, - tui.Color{78, 52, 46}, - tui.Color{33, 33, 33}, - tui.Color{55, 71, 79}, + ui.Color{198, 40, 40}, + ui.Color{173, 20, 87}, + ui.Color{106, 27, 154}, + ui.Color{69, 39, 160}, + ui.Color{40, 53, 147}, + ui.Color{21, 101, 192}, + ui.Color{2, 119, 189}, + ui.Color{0, 131, 143}, + ui.Color{0, 105, 92}, + ui.Color{46, 125, 50}, + ui.Color{85, 139, 47}, + ui.Color{158, 157, 36}, + ui.Color{249, 168, 37}, + ui.Color{255, 143, 0}, + ui.Color{239, 108, 0}, + ui.Color{216, 67, 21}, + ui.Color{78, 52, 46}, + ui.Color{33, 33, 33}, + ui.Color{55, 71, 79}, ], ] ) @@ -90,18 +90,18 @@ const ( struct App { mut: - tui &tui.Context = 0 + ui &ui.Context = 0 header_text []string mouse_pos Point msg string msg_hide_tick int - primary_color tui.Color = colors[1][6] - secondary_color tui.Color = colors[1][9] - primary_color_idx int = 25 - secondary_color_idx int = 28 - bg_color tui.Color = tui.Color{0, 0, 0} - drawing [][]tui.Color = [][]tui.Color{len: h, init: []tui.Color{len: w}} - size int = 1 + primary_color ui.Color = colors[1][6] + secondary_color ui.Color = colors[1][9] + primary_color_idx int = 25 + secondary_color_idx int = 28 + bg_color ui.Color = ui.Color{0, 0, 0} + drawing [][]ui.Color = [][]ui.Color{len: h, init: []ui.Color{len: w}} + size int = 1 should_redraw bool = true is_dragging bool } @@ -114,24 +114,24 @@ mut: fn main() { mut app := &App{} - app.tui = tui.init({ + app.ui = ui.init( user_data: app frame_fn: frame event_fn: event frame_rate: frame_rate hide_cursor: true window_title: 'V terminal pixelart drawing app' - }) + ) app.mouse_pos.x = 40 app.mouse_pos.y = 15 - app.tui.clear() - app.tui.run() + app.ui.clear() + app.ui.run() ? } fn frame(x voidptr) { mut app := &App(x) mut redraw := app.should_redraw - if app.msg != '' && app.tui.frame_count >= app.msg_hide_tick { + if app.msg != '' && app.ui.frame_count >= app.msg_hide_tick { app.msg = '' redraw = true } @@ -141,12 +141,12 @@ fn frame(x voidptr) { } } -fn event(event &tui.Event, x voidptr) { +fn event(event &ui.Event, x voidptr) { mut app := &App(x) match event.typ { .mouse_down { app.is_dragging = true - if app.tui.window_height - event.y < 5 { + if app.ui.window_height - event.y < 5 { app.footer_click(event) } else { app.paint(event) @@ -174,8 +174,8 @@ fn event(event &tui.Event, x voidptr) { y: event.y } d := event.direction == .down - if event.modifiers & tui.ctrl != 0 { - p := event.modifiers & tui.shift == 0 + if event.modifiers & ui.ctrl != 0 { + p := event.modifiers & ui.shift == 0 c := if d { if p { app.primary_color_idx - 1 } else { app.secondary_color_idx - 1 } } else { @@ -183,53 +183,72 @@ fn event(event &tui.Event, x voidptr) { } app.select_color(p, c) } else { - if d { app.inc_size() } else { app.dec_size() } + if d { + app.inc_size() + } else { + app.dec_size() + } } } .key_down { match event.code { .f1, ._1 { oevent := *event - nevent := tui.Event{ ...oevent, button: tui.MouseButton.left, x: app.mouse_pos.x , y: app.mouse_pos.y } + nevent := ui.Event{ + ...oevent + button: ui.MouseButton.left + x: app.mouse_pos.x + y: app.mouse_pos.y + } app.paint(nevent) } .f2, ._2 { oevent := *event - nevent := tui.Event{ ...oevent, button: tui.MouseButton.right, x: app.mouse_pos.x , y: app.mouse_pos.y } + nevent := ui.Event{ + ...oevent + button: ui.MouseButton.right + x: app.mouse_pos.x + y: app.mouse_pos.y + } app.paint(nevent) } .space { oevent := *event - nevent := tui.Event{ ...oevent, button: tui.MouseButton.middle, x: app.mouse_pos.x , y: app.mouse_pos.y } + nevent := ui.Event{ + ...oevent + button: ui.MouseButton.middle + x: app.mouse_pos.x + y: app.mouse_pos.y + } app.paint(nevent) } .j, .down { - if event.modifiers & tui.shift != 0 { + if event.modifiers & ui.shift != 0 { app.set_pixel((1 + app.mouse_pos.x) / 2, app.mouse_pos.y, app.primary_color) } app.mouse_pos.y++ } .k, .up { - if event.modifiers & tui.shift != 0 { + if event.modifiers & ui.shift != 0 { app.set_pixel((1 + app.mouse_pos.x) / 2, app.mouse_pos.y, app.primary_color) } app.mouse_pos.y-- } .h, .left { - if event.modifiers & tui.shift != 0 { + if event.modifiers & ui.shift != 0 { app.set_pixel((1 + app.mouse_pos.x) / 2, app.mouse_pos.y, app.primary_color) } app.mouse_pos.x -= 2 } .l, .right { - if event.modifiers & tui.shift != 0 { + if event.modifiers & ui.shift != 0 { app.set_pixel((1 + app.mouse_pos.x) / 2, app.mouse_pos.y, app.primary_color) } app.mouse_pos.x += 2 } .t { - p := event.modifiers & tui.alt == 0 - c := if event.modifiers & tui.shift != 0 { + p := event.modifiers & ui.alt == 0 + c := if event.modifiers & ui.shift != 0 { if p { app.primary_color_idx - 19 } else { app.secondary_color_idx - 19 } } else { if p { app.primary_color_idx + 19 } else { app.secondary_color_idx + 19 } @@ -237,8 +256,8 @@ fn event(event &tui.Event, x voidptr) { app.select_color(p, c) } .r { - p := event.modifiers & tui.alt == 0 - c := if event.modifiers & tui.shift != 0 { + p := event.modifiers & ui.alt == 0 + c := if event.modifiers & ui.shift != 0 { if p { app.primary_color_idx - 1 } else { app.secondary_color_idx - 1 } } else { if p { app.primary_color_idx + 1 } else { app.secondary_color_idx + 1 } @@ -252,7 +271,7 @@ fn event(event &tui.Event, x voidptr) { app.dec_size() } .c { - app.drawing = [][]tui.Color{len: h, init: []tui.Color{len: w}} + app.drawing = [][]ui.Color{len: h, init: []ui.Color{len: w}} } .q, .escape { app.render(true) @@ -267,14 +286,14 @@ fn event(event &tui.Event, x voidptr) { } fn (mut app App) render(paint_only bool) { - app.tui.clear() + app.ui.clear() app.draw_header() app.draw_content() if !paint_only { app.draw_footer() app.draw_cursor() } - app.tui.flush() + app.ui.flush() } fn (mut app App) select_color(primary bool, idx int) { @@ -293,10 +312,10 @@ fn (mut app App) select_color(primary bool, idx int) { app.show_msg('set $c_str color idx: $idx', 1) } -fn (mut app App) set_pixel(x_ int, y_ int, c tui.Color) { +fn (mut app App) set_pixel(x_ int, y_ int, c ui.Color) { // Term coords start at 1, and adjust for the header x, y := x_ - 1, y_ - 4 - if y < 0 || app.tui.window_height - y < 3 { + if y < 0 || app.ui.window_height - y < 3 { return } if y >= app.drawing.len || x < 0 || x >= app.drawing[0].len { @@ -305,8 +324,8 @@ fn (mut app App) set_pixel(x_ int, y_ int, c tui.Color) { app.drawing[y][x] = c } -fn (mut app App) paint(event &tui.Event) { - if event.y < 4 || app.tui.window_height - event.y < 4 { +fn (mut app App) paint(event &ui.Event) { + if event.y < 4 || app.ui.window_height - event.y < 4 { return } x_start, y_start := int(f32((event.x - 1) / 2) - app.size / 2 + 1), event.y - app.size / 2 @@ -323,38 +342,38 @@ fn (mut app App) paint(event &tui.Event) { } fn (mut app App) draw_content() { - w_, mut h_ := app.tui.window_width / 2, app.tui.window_height - 8 + w_, mut h_ := app.ui.window_width / 2, app.ui.window_height - 8 if h_ > app.drawing.len { h_ = app.drawing.len } for row_idx, row in app.drawing[..h_] { - app.tui.set_cursor_position(0, row_idx + 4) - mut last := tui.Color{0, 0, 0} + app.ui.set_cursor_position(0, row_idx + 4) + mut last := ui.Color{0, 0, 0} for cell in row[..w_] { if cell.r == 0 && cell.g == 0 && cell.b == 0 { if !(cell.r == last.r && cell.g == last.g && cell.b == last.b) { - app.tui.reset() + app.ui.reset() } } else { if !(cell.r == last.r && cell.g == last.g && cell.b == last.b) { - app.tui.set_bg_color(cell) + app.ui.set_bg_color(cell) } } - app.tui.write(spaces) + app.ui.write(spaces) last = cell } - app.tui.reset() + app.ui.reset() } } fn (mut app App) draw_cursor() { - if app.mouse_pos.y in [3, app.tui.window_height - 5] { + if app.mouse_pos.y in [3, app.ui.window_height - 5] { // inside the horizontal separators return } - cursor_color := if app.is_dragging { tui.Color{220, 220, 220} } else { tui.Color{160, 160, 160} } - app.tui.set_bg_color(cursor_color) - if app.mouse_pos.y >= 3 && app.mouse_pos.y <= app.tui.window_height - 4 { + cursor_color := if app.is_dragging { ui.Color{220, 220, 220} } else { ui.Color{160, 160, 160} } + app.ui.set_bg_color(cursor_color) + if app.mouse_pos.y >= 3 && app.mouse_pos.y <= app.ui.window_height - 4 { // inside the main content mut x_start := int(f32((app.mouse_pos.x - 1) / 2) - app.size / 2 + 1) * 2 - 1 mut y_start := app.mouse_pos.y - app.size / 2 @@ -366,70 +385,71 @@ fn (mut app App) draw_cursor() { if y_start < 4 { y_start = 4 } - if x_end > app.tui.window_width { - x_end = app.tui.window_width + if x_end > app.ui.window_width { + x_end = app.ui.window_width } - if y_end > app.tui.window_height - 5 { - y_end = app.tui.window_height - 5 + if y_end > app.ui.window_height - 5 { + y_end = app.ui.window_height - 5 } - app.tui.draw_rect(x_start, y_start, x_end, y_end) + app.ui.draw_rect(x_start, y_start, x_end, y_end) } else { - app.tui.draw_text(app.mouse_pos.x, app.mouse_pos.y, space) + app.ui.draw_text(app.mouse_pos.x, app.mouse_pos.y, space) } - app.tui.reset() + app.ui.reset() } fn (mut app App) draw_header() { if app.msg != '' { - app.tui.set_color({ + app.ui.set_color( r: 0 g: 0 b: 0 - }) - app.tui.set_bg_color({ + ) + app.ui.set_bg_color( r: 220 g: 220 b: 220 - }) - app.tui.draw_text(0, 0, ' $app.msg ') - app.tui.reset() + ) + app.ui.draw_text(0, 0, ' $app.msg ') + app.ui.reset() } - app.tui.draw_text(3, 2, /* 'tick: $app.tui.frame_count | ' + */ 'terminal size: ($app.tui.window_width, $app.tui.window_height) | primary color: $app.primary_color.hex() | secondary color: $app.secondary_color.hex()') - app.tui.horizontal_separator(3) + //'tick: $app.ui.frame_count | ' + + app.ui.draw_text(3, 2, 'terminal size: ($app.ui.window_width, $app.ui.window_height) | primary color: $app.primary_color.hex() | secondary color: $app.secondary_color.hex()') + app.ui.horizontal_separator(3) } fn (mut app App) draw_footer() { - _, wh := app.tui.window_width, app.tui.window_height - app.tui.horizontal_separator(wh - 4) + _, wh := app.ui.window_width, app.ui.window_height + app.ui.horizontal_separator(wh - 4) for i, color_row in colors { for j, color in color_row { x := j * 3 + 19 y := wh - 3 + i - app.tui.set_bg_color(color) + app.ui.set_bg_color(color) if app.primary_color_idx == j + (i * 19) { - app.tui.set_color(r: 0, g: 0, b: 0) - app.tui.draw_text(x, y, '><') - app.tui.reset_color() + app.ui.set_color(r: 0, g: 0, b: 0) + app.ui.draw_text(x, y, '><') + app.ui.reset_color() } else if app.secondary_color_idx == j + (i * 19) { - app.tui.set_color(r: 255, g: 255, b: 255) - app.tui.draw_text(x, y, '><') - app.tui.reset_color() + app.ui.set_color(r: 255, g: 255, b: 255) + app.ui.draw_text(x, y, '><') + app.ui.reset_color() } else { - app.tui.draw_rect(x, y, x + 1, y) + app.ui.draw_rect(x, y, x + 1, y) } } } - app.tui.reset_bg_color() - app.tui.draw_text(3, wh - 3, select_color) - app.tui.bold() - app.tui.draw_text(3, wh - 1, '$select_size $app.size') - app.tui.reset() + app.ui.reset_bg_color() + app.ui.draw_text(3, wh - 3, select_color) + app.ui.bold() + app.ui.draw_text(3, wh - 1, '$select_size $app.size') + app.ui.reset() // TODO: help button // if ww >= 90 { - // app.tui.draw_text(80, wh - 3, help_1) - // app.tui.draw_text(80, wh - 2, help_2) - // app.tui.draw_text(80, wh - 1, help_3) + // app.ui.draw_text(80, wh - 3, help_1) + // app.ui.draw_text(80, wh - 2, help_2) + // app.ui.draw_text(80, wh - 1, help_3) // } } @@ -449,8 +469,8 @@ fn (mut app App) dec_size() { app.show_msg('dec. size: $app.size', 1) } -fn (mut app App) footer_click(event &tui.Event) { - footer_y := 3 - (app.tui.window_height - event.y) +fn (mut app App) footer_click(event &ui.Event) { + footer_y := 3 - (app.ui.window_height - event.y) match event.x { 8...11 { app.inc_size() @@ -464,7 +484,9 @@ fn (mut app App) footer_click(event &tui.Event) { return } idx := footer_y * 19 - 6 + event.x / 3 - if idx < 0 || idx > 56 { return } + if idx < 0 || idx > 56 { + return + } app.select_color(event.button == .left, idx) } else {} @@ -473,6 +495,6 @@ fn (mut app App) footer_click(event &tui.Event) { fn (mut app App) show_msg(text string, time int) { frames := time * frame_rate - app.msg_hide_tick = if time > 0 { int(app.tui.frame_count) + frames } else { -1 } + app.msg_hide_tick = if time > 0 { int(app.ui.frame_count) + frames } else { -1 } app.msg = text } diff --git a/examples/term.ui/text_editor.v b/examples/term.ui/text_editor.v index 49b389b407..525797a8bc 100644 --- a/examples/term.ui/text_editor.v +++ b/examples/term.ui/text_editor.v @@ -26,7 +26,7 @@ pub: struct App { mut: tui &tui.Context = 0 - ed &Buffer = 0 + ed &Buffer = 0 current_file int files []string status string @@ -44,7 +44,7 @@ fn (mut a App) set_status(msg string, duration_ms int) { fn (mut a App) save() { if a.cfile().len > 0 { b := a.ed - os.write_file(a.cfile(), b.raw()) + os.write_file(a.cfile(), b.raw()) or { panic(err) } a.set_status('Saved', 2000) } else { a.set_status('No file loaded', 4000) @@ -79,7 +79,6 @@ fn (mut a App) visit_next_file() { a.init_file() } - fn (mut a App) footer() { w, h := a.tui.window_width, a.tui.window_height mut b := a.ed @@ -99,16 +98,16 @@ fn (mut a App) footer() { if a.t <= 0 { status = '' } else { - a.tui.set_bg_color({ + a.tui.set_bg_color( r: 200 g: 200 b: 200 - }) - a.tui.set_color({ + ) + a.tui.set_color( r: 0 g: 0 b: 0 - }) + ) a.tui.draw_text((w + 4 - status.len) / 2, h - 1, ' $status ') a.tui.reset() a.t -= 33 @@ -118,8 +117,8 @@ fn (mut a App) footer() { struct Buffer { tab_width int = 4 pub mut: - lines []string - cursor Cursor + lines []string + cursor Cursor } fn (b Buffer) flat() string { @@ -303,7 +302,7 @@ fn (mut b Buffer) free() { for line in b.lines { line.free() } - unsafe {b.lines.free()} + unsafe { b.lines.free() } } fn (mut b Buffer) move_updown(amount int) { @@ -334,7 +333,7 @@ fn (mut b Buffer) move_cursor(amount int, movement Movement) { b.move_updown(-dlines) } .page_down { - dlines := imin(b.lines.len-1, b.cursor.pos_y + amount) - b.cursor.pos_y + dlines := imin(b.lines.len - 1, b.cursor.pos_y + amount) - b.cursor.pos_y b.move_updown(dlines) } .left { @@ -374,13 +373,19 @@ fn (mut b Buffer) move_to_word(movement Movement) { x = 0 } // first, move past all non-`a-zA-Z0-9_` characters - for x+a >= 0 && x+a < line.len && !(line[x+a].is_letter() || line[x+a].is_digit() || line[x+a] == `_`) { x += a } + for x + a >= 0 && x + a < line.len && !(line[x + a].is_letter() + || line[x + a].is_digit()|| line[x + a] == `_`) { + x += a + } // then, move past all the letters and numbers - for x+a >= 0 && x+a < line.len && (line[x+a].is_letter() || line[x+a].is_digit() || line[x+a] == `_`) { x += a } + for x + a >= 0 && x + a < line.len && (line[x + a].is_letter() + || line[x + a].is_digit()|| line[x + a] == `_`) { + x += a + } // if the cursor is out of bounds, move it to the next/previous line if x + a >= 0 && x + a <= line.len { x += a - } else if a < 0 && y+1 > b.lines.len && y-1 >= 0 { + } else if a < 0 && y + 1 > b.lines.len && y - 1 >= 0 { y += a x = 0 } @@ -388,11 +393,19 @@ fn (mut b Buffer) move_to_word(movement Movement) { } fn imax(x int, y int) int { - return if x < y { y } else { x } + return if x < y { + y + } else { + x + } } fn imin(x int, y int) int { - return if x < y { x } else { y } + return if x < y { + x + } else { + y + } } struct Cursor { @@ -443,9 +456,7 @@ fn (mut a App) init_file() { // 'vico: ' + a.tui.set_window_title(a.files[a.current_file]) mut b := a.ed - content := os.read_file(a.files[a.current_file]) or { - panic(err) - } + content := os.read_file(a.files[a.current_file]) or { panic(err) } b.put(content) a.ed.cursor.pos_x = init_x a.ed.cursor.pos_y = init_y @@ -573,12 +584,12 @@ fn main() { mut a := &App{ files: files } - a.tui = tui.init({ + a.tui = tui.init( user_data: a init_fn: init frame_fn: frame event_fn: event capture_events: true - }) - a.tui.run() + ) + a.tui.run() ? } diff --git a/examples/term.ui/vyper.v b/examples/term.ui/vyper.v index 810ebb06fd..34966f7945 100644 --- a/examples/term.ui/vyper.v +++ b/examples/term.ui/vyper.v @@ -60,12 +60,12 @@ fn (mut v Vec) randomize(min_x int, min_y int, max_x int, max_y int) { // part of snake's body representation struct BodyPart { mut: - pos Vec = { - x: block_size - y: block_size -} + pos Vec = { + x: block_size + y: block_size + } color termui.Color = green - facing Orientation = .top + facing Orientation = .top } // snake representation @@ -75,9 +75,9 @@ mut: direction Orientation body []BodyPart velocity Vec = Vec{ - x: 0 - y: 0 -} + x: 0 + y: 0 + } } // length returns the snake's current length @@ -125,8 +125,16 @@ fn (mut s Snake) move() { piece.facing = s.direction new_x := piece.pos.x + s.velocity.x new_y := piece.pos.y + s.velocity.y - piece.pos.x += if new_x > block_size && new_x < width - block_size { s.velocity.x } else { 0 } - piece.pos.y += if new_y > block_size && new_y < height - block_size { s.velocity.y } else { 0 } + piece.pos.x += if new_x > block_size && new_x < width - block_size { + s.velocity.x + } else { + 0 + } + piece.pos.y += if new_y > block_size && new_y < height - block_size { + s.velocity.y + } else { + 0 + } } s.body[i] = piece } @@ -205,10 +213,10 @@ fn (s Snake) check_overlap() bool { fn (s Snake) check_out_of_bounds() bool { h := s.get_head() - return h.pos.x + s.velocity.x <= block_size || - h.pos.x + s.velocity.x > s.app.width - s.velocity.x || h.pos.y + s.velocity.y <= block_size || - h.pos.y + s.velocity.y > - s.app.height - block_size - s.velocity.y + return h.pos.x + s.velocity.x <= block_size + || h.pos.x + s.velocity.x > s.app.width - s.velocity.x + || h.pos.y + s.velocity.y <= block_size + || h.pos.y + s.velocity.y > s.app.height - block_size - s.velocity.y } // draw draws the parts of the snake @@ -233,10 +241,10 @@ fn (s Snake) draw() { // rat representation struct Rat { mut: - pos Vec = { - x: block_size - y: block_size -} + pos Vec = { + x: block_size + y: block_size + } captured bool color termui.Color = grey app &App @@ -244,8 +252,8 @@ mut: // randomize spawn the rat in a new spot within the playable field fn (mut r Rat) randomize() { - r.pos.randomize(2 * block_size + buffer, 2 * block_size + buffer, r.app.width - block_size - - buffer, r.app.height - block_size - buffer) + r.pos.randomize(2 * block_size + buffer, 2 * block_size + buffer, r.app.width - block_size - buffer, + r.app.height - block_size - buffer) } struct App { @@ -255,7 +263,7 @@ mut: rat Rat width int height int - redraw bool = true + redraw bool = true state GameState = .game } @@ -387,9 +395,8 @@ fn (mut a App) move_snake(direction Orientation) { fn (a App) check_capture() bool { snake_pos := a.snake.get_head().pos rat_pos := a.rat.pos - return snake_pos.x <= rat_pos.x + block_size && - snake_pos.x + block_size >= rat_pos.x && snake_pos.y <= rat_pos.y + block_size && snake_pos.y + - block_size >= rat_pos.y + return snake_pos.x <= rat_pos.x + block_size && snake_pos.x + block_size >= rat_pos.x + && snake_pos.y <= rat_pos.y + block_size&& snake_pos.y + block_size >= rat_pos.y } fn (mut a App) draw_snake() { @@ -454,12 +461,12 @@ fn (mut a App) draw_gameover() { } mut app := &App{} -app.termui = termui.init({ +app.termui = termui.init( user_data: app event_fn: event frame_fn: frame init_fn: init hide_cursor: true frame_rate: 10 -}) -app.termui.run() +) +app.termui.run() ? diff --git a/examples/x/websocket/client-server/client.v b/examples/x/websocket/client-server/client.v index 71f2c31f04..5b1b1c289e 100644 --- a/examples/x/websocket/client-server/client.v +++ b/examples/x/websocket/client-server/client.v @@ -12,22 +12,20 @@ fn main() { println(term.green('client $ws.id ready')) println('Write message and enter to send...') for { - line := os.get_line() + line := os.get_line() if line == '' { break } - ws.write_str(line) - } - ws.close(1000, 'normal') or { - println(term.red('panicing $err')) + ws.write_str(line) ? } + ws.close(1000, 'normal') or { println(term.red('panicing $err')) } unsafe { ws.free() } } fn start_client() ?&websocket.Client { - mut ws := websocket.new_client('ws://localhost:30000')? + mut ws := websocket.new_client('ws://localhost:30000') ? // mut ws := websocket.new_client('wss://echo.websocket.org:443')? // use on_open_ref if you want to send any reference object ws.on_open(fn (mut ws websocket.Client) ? { @@ -49,12 +47,8 @@ fn start_client() ?&websocket.Client { } }) - ws.connect() or { - println(term.red('error on connect: $err')) - } - - go ws.listen() or { - println(term.red('error on listen $err')) - } + ws.connect() or { println(term.red('error on connect: $err')) } + + go ws.listen() or { println(term.red('error on listen $err')) } return ws } diff --git a/vlib/cli/command.v b/vlib/cli/command.v index 6689e66899..92c0a55764 100644 --- a/vlib/cli/command.v +++ b/vlib/cli/command.v @@ -259,7 +259,7 @@ fn (cmd Command) check_version_flag() { version_flag := cmd.flags.get_bool('version') or { return } // ignore error and handle command normally if version_flag { version_cmd := cmd.commands.get('version') or { return } // ignore error and handle command normally - version_cmd.execute(version_cmd) + version_cmd.execute(version_cmd) or { panic(err) } exit(0) } } @@ -280,7 +280,7 @@ fn (cmd Command) check_required_flags() { pub fn (cmd Command) execute_help() { if cmd.commands.contains('help') { help_cmd := cmd.commands.get('help') or { return } // ignore error and handle command normally - help_cmd.execute(help_cmd) + help_cmd.execute(help_cmd) or { panic(err) } } else { print(cmd.help_message()) } diff --git a/vlib/dl/example/use_test.v b/vlib/dl/example/use_test.v index a03f1e9034..7f42fe423c 100644 --- a/vlib/dl/example/use_test.v +++ b/vlib/dl/example/use_test.v @@ -22,7 +22,7 @@ fn test_vexe() { fn test_can_compile_library() { os.chdir(cfolder) - os.rm(library_file_name) + os.rm(library_file_name) or { } res := v_compile('-d no_backtrace -o library -shared library.v') eprintln('res: $res') assert os.is_file(library_file_name) @@ -34,7 +34,7 @@ fn test_can_compile_main_program() { result := v_compile('run use.v') eprintln('result: $result') assert result.output.contains('res: 4') - os.rm(library_file_name) + os.rm(library_file_name) or { } } fn v_compile(vopts string) os.Result { diff --git a/vlib/io/util/util_test.v b/vlib/io/util/util_test.v index ddc08db963..ff09e7e5dd 100644 --- a/vlib/io/util/util_test.v +++ b/vlib/io/util/util_test.v @@ -10,16 +10,16 @@ const ( fn testsuite_begin() { eprintln('testsuite_begin, tfolder = $tfolder') - os.rmdir_all(tfolder) + os.rmdir_all(tfolder) or { } assert !os.is_dir(tfolder) - os.mkdir_all(tfolder) + os.mkdir_all(tfolder) or { panic(err) } os.chdir(tfolder) assert os.is_dir(tfolder) } fn testsuite_end() { os.chdir(os.wd_at_startup) - os.rmdir_all(tfolder) + os.rmdir_all(tfolder) or { } assert !os.is_dir(tfolder) // eprintln('testsuite_end , tfolder = $tfolder removed.') } @@ -38,9 +38,9 @@ fn test_temp_file() { assert f.is_opened // Test pattern f.close() - f, path = util.temp_file({ + f, path = util.temp_file( pattern: 'some_*_test.file' - }) or { + ) or { assert false return } @@ -58,9 +58,9 @@ fn test_temp_file() { // Test custom path prev_path = path f.close() - f, path = util.temp_file({ + f, path = util.temp_file( path: tfolder - }) or { + ) or { assert false return } @@ -88,9 +88,9 @@ fn test_temp_dir() { assert writable mut prev_path := path // Test pattern - path = util.temp_dir({ + path = util.temp_dir( pattern: 'some_*_test_dir' - }) or { + ) or { assert false return } @@ -106,9 +106,9 @@ fn test_temp_dir() { } // Test custom path prev_path = path - path = util.temp_dir({ + path = util.temp_dir( path: tfolder - }) or { + ) or { assert false return } diff --git a/vlib/log/log.v b/vlib/log/log.v index 701443b9a0..4ba9e5e45e 100644 --- a/vlib/log/log.v +++ b/vlib/log/log.v @@ -49,10 +49,10 @@ interface Logger { // Log represents a logging object pub struct Log { mut: - level Level - output_label string - ofile os.File - output_to_file bool // if true output to file else use stdout/stderr. + level Level + output_label string + ofile os.File + output_to_file bool // if true output to file else use stdout/stderr. pub mut: output_file_name string // log output to this file } @@ -106,7 +106,7 @@ pub fn (mut l Log) close() { fn (mut l Log) log_file(s string, level Level) { timestamp := time.now().format_ss() e := tag_to_file(level) - l.ofile.writeln('$timestamp [$e] $s') + l.ofile.writeln('$timestamp [$e] $s') or { panic(err) } } // log_cli writes log line `s` with `level` to stdout. diff --git a/vlib/net/errors.v b/vlib/net/errors.v index 1b9fb52956..ec5f4069dd 100644 --- a/vlib/net/errors.v +++ b/vlib/net/errors.v @@ -36,7 +36,7 @@ pub fn socket_error(potential_code int) ?int { pub fn wrap_error(error_code int) ? { $if windows { enum_error := wsa_error(error_code) - return error_with_code('socket error: $enum_error', error_code) + return error_with_code('net: socket error: $enum_error', error_code) } $else { if error_code == 0 { diff --git a/vlib/net/ftp/ftp.v b/vlib/net/ftp/ftp.v index 03f2f68fbe..21e65fa95b 100644 --- a/vlib/net/ftp/ftp.v +++ b/vlib/net/ftp/ftp.v @@ -36,7 +36,7 @@ const ( struct DTP { mut: - conn net.TcpConn + conn &net.TcpConn reader io.BufferedReader ip string port int @@ -56,31 +56,31 @@ fn (mut dtp DTP) read() ?[]byte { } fn (mut dtp DTP) close() { - dtp.conn.close() + dtp.conn.close() or { panic(err) } } struct FTP { mut: - conn net.TcpConn + conn &net.TcpConn reader io.BufferedReader buffer_size int } pub fn new() FTP { - mut f := FTP{} + mut f := FTP{ conn: 0 } f.buffer_size = 1024 return f } -fn (mut ftp FTP) write(data string) ? { +fn (mut zftp FTP) write(data string) ? { $if debug { println('FTP.v >>> $data') } - ftp.conn.write('$data\r\n'.bytes()) ? + zftp.conn.write('$data\r\n'.bytes()) ? } -fn (mut ftp FTP) read() ?(int, string) { - mut data := ftp.reader.read_line() ? +fn (mut zftp FTP) read() ?(int, string) { + mut data := zftp.reader.read_line() ? $if debug { println('FTP.v <<< $data') } @@ -90,7 +90,7 @@ fn (mut ftp FTP) read() ?(int, string) { code := data[..3].int() if data[3] == `-` { for { - data = ftp.reader.read_line() ? + data = zftp.reader.read_line() ? if data[..3].int() == code && data[3] != `-` { break } @@ -99,51 +99,51 @@ fn (mut ftp FTP) read() ?(int, string) { return code, data } -pub fn (mut ftp FTP) connect(ip string) ?bool { - ftp.conn = net.dial_tcp('$ip:21') ? - ftp.reader = io.new_buffered_reader(reader: io.make_reader(ftp.conn)) - code, _ := ftp.read() ? - if code == connected { +pub fn (mut zftp FTP) connect(ip string) ?bool { + zftp.conn = net.dial_tcp('$ip:21') ? + zftp.reader = io.new_buffered_reader(reader: io.make_reader(zftp.conn)) + code, _ := zftp.read() ? + if code == ftp.connected { return true } return false } -pub fn (mut ftp FTP) login(user string, passwd string) ?bool { - ftp.write('USER $user') or { +pub fn (mut zftp FTP) login(user string, passwd string) ?bool { + zftp.write('USER $user') or { $if debug { println('ERROR sending user') } return false } - mut code, _ := ftp.read() ? - if code == logged_in { + mut code, _ := zftp.read() ? + if code == ftp.logged_in { return true } - if code != specify_password { + if code != ftp.specify_password { return false } - ftp.write('PASS $passwd') or { + zftp.write('PASS $passwd') or { $if debug { println('ERROR sending password') } return false } - code, _ = ftp.read() ? - if code == logged_in { + code, _ = zftp.read() ? + if code == ftp.logged_in { return true } return false } -pub fn (mut ftp FTP) close() ? { - ftp.write('QUIT') ? - ftp.conn.close() +pub fn (mut zftp FTP) close() ? { + zftp.write('QUIT') ? + zftp.conn.close() ? } -pub fn (mut ftp FTP) pwd() ?string { - ftp.write('PWD') ? - _, data := ftp.read() ? +pub fn (mut zftp FTP) pwd() ?string { + zftp.write('PWD') ? + _, data := zftp.read() ? spl := data.split('"') // " if spl.len >= 2 { return spl[1] @@ -151,17 +151,17 @@ pub fn (mut ftp FTP) pwd() ?string { return data } -pub fn (mut ftp FTP) cd(dir string) ? { - ftp.write('CWD $dir') or { return } - mut code, mut data := ftp.read() ? +pub fn (mut zftp FTP) cd(dir string) ? { + zftp.write('CWD $dir') or { return } + mut code, mut data := zftp.read() ? match int(code) { - denied { + ftp.denied { $if debug { println('CD $dir denied!') } } - complete { - code, data = ftp.read() ? + ftp.complete { + code, data = zftp.read() ? } else {} } @@ -178,6 +178,7 @@ fn new_dtp(msg string) ?&DTP { mut dtp := &DTP{ ip: ip port: port + conn: 0 } conn := net.dial_tcp('$ip:$port') or { return error('Cannot connect to the data channel') } dtp.conn = conn @@ -185,32 +186,32 @@ fn new_dtp(msg string) ?&DTP { return dtp } -fn (mut ftp FTP) pasv() ?&DTP { - ftp.write('PASV') ? - code, data := ftp.read() ? +fn (mut zftp FTP) pasv() ?&DTP { + zftp.write('PASV') ? + code, data := zftp.read() ? $if debug { println('pass: $data') } - if code != passive_mode { + if code != ftp.passive_mode { return error('pasive mode not allowed') } dtp := new_dtp(data) ? return dtp } -pub fn (mut ftp FTP) dir() ?[]string { - mut dtp := ftp.pasv() or { return error('Cannot establish data connection') } - ftp.write('LIST') ? - code, _ := ftp.read() ? - if code == denied { +pub fn (mut zftp FTP) dir() ?[]string { + mut dtp := zftp.pasv() or { return error('Cannot establish data connection') } + zftp.write('LIST') ? + code, _ := zftp.read() ? + if code == ftp.denied { return error('`LIST` denied') } - if code != open_data_connection { + if code != ftp.open_data_connection { return error('Data channel empty') } list_dir := dtp.read() ? - result, _ := ftp.read() ? - if result != close_data_connection { + result, _ := zftp.read() ? + if result != ftp.close_data_connection { println('`LIST` not ok') } dtp.close() @@ -225,14 +226,14 @@ pub fn (mut ftp FTP) dir() ?[]string { return dir } -pub fn (mut ftp FTP) get(file string) ?[]byte { - mut dtp := ftp.pasv() or { return error('Cannot stablish data connection') } - ftp.write('RETR $file') ? - code, _ := ftp.read() ? - if code == denied { +pub fn (mut zftp FTP) get(file string) ?[]byte { + mut dtp := zftp.pasv() or { return error('Cannot stablish data connection') } + zftp.write('RETR $file') ? + code, _ := zftp.read() ? + if code == ftp.denied { return error('Permission denied') } - if code != open_data_connection { + if code != ftp.open_data_connection { return error('Data connection not ready') } blob := dtp.read() ? diff --git a/vlib/net/ftp/ftp_test.v b/vlib/net/ftp/ftp_test.v index 22ade360ee..bc64236e97 100644 --- a/vlib/net/ftp/ftp_test.v +++ b/vlib/net/ftp/ftp_test.v @@ -1,42 +1,49 @@ import net.ftp -// NB: this function makes network calls to external servers, -// that is why it is not a very good idea to run it in CI. -// If you want to run it manually, use `v -d network vlib/net/ftp/ftp_test.v` -fn ftp_client_test_inside() ? { - $if !network ? { return } - mut ftp := ftp.new() - defer { - ftp.close() +fn test_ftp_cleint() { + $if !network ? { + return } - connect_result := ftp.connect('ftp.redhat.com')? + // NB: this function makes network calls to external servers, + // that is why it is not a very good idea to run it in CI. + // If you want to run it manually, use: + // `v -d network vlib/net/ftp/ftp_test.v` + ftp_client_test_inside() or { panic(err) } +} + +fn ftp_client_test_inside() ? { + mut zftp := ftp.new() + // eprintln(zftp) + defer { + zftp.close() or { panic(err) } + } + connect_result := zftp.connect('ftp.redhat.com') ? assert connect_result - login_result := ftp.login('ftp', 'ftp')? + login_result := zftp.login('ftp', 'ftp') ? assert login_result - pwd := ftp.pwd()? + pwd := zftp.pwd() ? assert pwd.len > 0 - ftp.cd('/') - dir_list1 := ftp.dir() or { + zftp.cd('/') or { + assert false + return + } + dir_list1 := zftp.dir() or { assert false return } assert dir_list1.len > 0 - ftp.cd('/suse/linux/enterprise/11Server/en/SAT-TOOLS/SRPMS/') - dir_list2 := ftp.dir() or { + zftp.cd('/suse/linux/enterprise/11Server/en/SAT-TOOLS/SRPMS/') or { + assert false + return + } + dir_list2 := zftp.dir() or { assert false return } assert dir_list2.len > 0 - blob := ftp.get('katello-host-tools-3.3.5-8.sles11_4sat.src.rpm') or { + blob := zftp.get('katello-host-tools-3.3.5-8.sles11_4sat.src.rpm') or { assert false return } assert blob.len > 0 } - - -fn test_ftp_cleint() { - ftp_client_test_inside() or { - panic(err) - } -} diff --git a/vlib/net/http/download.v b/vlib/net/http/download.v index 2599cfc180..036e611c69 100644 --- a/vlib/net/http/download.v +++ b/vlib/net/http/download.v @@ -5,13 +5,11 @@ module http import os -pub fn download_file(url string, out string)? { - $if debug_http? { +pub fn download_file(url string, out string) ? { + $if debug_http ? { println('download file url=$url out=$out') } - s := get(url) or { - return error(err) - } - os.write_file(out, s.text) + s := get(url) or { return error(err) } + os.write_file(out, s.text) ? // download_file_with_progress(url, out, empty, empty) } diff --git a/vlib/net/http/http.v b/vlib/net/http/http.v index 9d5920c498..91a0b44c52 100644 --- a/vlib/net/http/http.v +++ b/vlib/net/http/http.v @@ -67,33 +67,48 @@ pub fn get(url string) ?Response { } pub fn post(url string, data string) ?Response { - return fetch_with_method(.post, url, data: data, headers: { - 'Content-Type': content_type_default - }) + return fetch_with_method(.post, url, + data: data + headers: { + 'Content-Type': http.content_type_default + } + ) } pub fn post_json(url string, data string) ?Response { - return fetch_with_method(.post, url, data: data, headers: { + return fetch_with_method(.post, url, + data: data + headers: { 'Content-Type': 'application/json' - }) + } + ) } pub fn post_form(url string, data map[string]string) ?Response { - return fetch_with_method(.post, url, headers: { + return fetch_with_method(.post, url, + headers: { 'Content-Type': 'application/x-www-form-urlencoded' - }, data: url_encode_form_data(data)) + } + data: url_encode_form_data(data) + ) } pub fn put(url string, data string) ?Response { - return fetch_with_method(.put, url, data: data, headers: { - 'Content-Type': content_type_default - }) + return fetch_with_method(.put, url, + data: data + headers: { + 'Content-Type': http.content_type_default + } + ) } pub fn patch(url string, data string) ?Response { - return fetch_with_method(.patch, url, data: data, headers: { - 'Content-Type': content_type_default - }) + return fetch_with_method(.patch, url, + data: data + headers: { + 'Content-Type': http.content_type_default + } + ) } pub fn head(url string) ?Response { @@ -165,11 +180,11 @@ fn build_url_from_fetch(_url string, config FetchConfig) ?string { } fn (mut req Request) free() { - unsafe {req.headers.free()} + unsafe { req.headers.free() } } fn (mut resp Response) free() { - unsafe {resp.headers.free()} + unsafe { resp.headers.free() } } // add_header adds the key and value of an HTTP request header @@ -199,8 +214,8 @@ pub fn (req &Request) do() ?Response { mut resp := Response{} mut no_redirects := 0 for { - if no_redirects == max_redirects { - return error('http.request.do: maximum number of redirects reached ($max_redirects)') + if no_redirects == http.max_redirects { + return error('http.request.do: maximum number of redirects reached ($http.max_redirects)') } qresp := req.method_and_url_to_response(req.method, rurl) ? resp = qresp @@ -366,7 +381,7 @@ fn (req &Request) http_do(host string, method Method, path string) ?Response { // TODO this really needs to be exposed somehow client.write(s.bytes()) ? mut bytes := io.read_all(reader: client) ? - client.close() + client.close() ? return parse_response(bytes.bytestr()) } diff --git a/vlib/net/smtp/smtp.v b/vlib/net/smtp/smtp.v index 4e78c78801..8da824ab16 100644 --- a/vlib/net/smtp/smtp.v +++ b/vlib/net/smtp/smtp.v @@ -96,8 +96,8 @@ pub fn (mut c Client) send(config Mail) ? { // quit closes the connection to the server pub fn (mut c Client) quit() ? { - c.send_str('QUIT\r\n') - c.expect_reply(.close) + c.send_str('QUIT\r\n') ? + c.expect_reply(.close) ? c.conn.close() ? c.is_open = false } @@ -166,7 +166,7 @@ fn (mut c Client) send_mailto(to string) ? { fn (mut c Client) send_data() ? { c.send_str('DATA\r\n') ? - c.expect_reply(.mail_start) + c.expect_reply(.mail_start) ? } fn (mut c Client) send_body(cfg Mail) ? { diff --git a/vlib/net/tcp.v b/vlib/net/tcp.v index bf515fc387..d20bcc87ee 100644 --- a/vlib/net/tcp.v +++ b/vlib/net/tcp.v @@ -22,8 +22,8 @@ pub fn dial_tcp(address string) ?&TcpConn { s.connect(address) ? return &TcpConn{ sock: s - read_timeout: tcp_default_read_timeout - write_timeout: tcp_default_write_timeout + read_timeout: net.tcp_default_read_timeout + write_timeout: net.tcp_default_write_timeout } } @@ -35,7 +35,8 @@ pub fn (mut c TcpConn) close() ? { // write_ptr blocks and attempts to write all data pub fn (mut c TcpConn) write_ptr(b byteptr, len int) ? { $if trace_tcp ? { - eprintln('>>> TcpConn.write_ptr | c.sock.handle: $c.sock.handle | b: ${ptr_str(b)} len: $len |\n' + + eprintln( + '>>> TcpConn.write_ptr | c.sock.handle: $c.sock.handle | b: ${ptr_str(b)} len: $len |\n' + unsafe { b.vstring_with_len(len) }) } unsafe { @@ -48,7 +49,7 @@ pub fn (mut c TcpConn) write_ptr(b byteptr, len int) ? { if sent < 0 { code := error_code() if code == int(error_ewouldblock) { - c.wait_for_write() + c.wait_for_write() ? continue } else { wrap_error(code) ? @@ -164,9 +165,9 @@ pub fn (c &TcpConn) peer_ip() ?string { return res } -pub fn (c &TcpConn) str() string { - // TODO - return 'TcpConn {write_deadline: $c.write_deadline, read_deadline: $c.read_deadline, read_timeout: $c.read_timeout, write_timeout: $c.write_timeout, sock: $c.sock}' +pub fn (c TcpConn) str() string { + s := c.sock.str().replace('\n', ' ').replace(' ', ' ') + return 'TcpConn{ write_deadline: $c.write_deadline, read_deadline: $c.read_deadline, read_timeout: $c.read_timeout, write_timeout: $c.write_timeout, sock: $s }' } pub struct TcpListener { @@ -213,8 +214,8 @@ pub fn (mut l TcpListener) accept() ?&TcpConn { new_sock := tcp_socket_from_handle(new_handle) ? return &TcpConn{ sock: new_sock - read_timeout: tcp_default_read_timeout - write_timeout: tcp_default_write_timeout + read_timeout: net.tcp_default_read_timeout + write_timeout: net.tcp_default_write_timeout } } @@ -266,7 +267,7 @@ fn new_tcp_socket() ?TcpSocket { t := true socket_error(C.ioctlsocket(sockfd, fionbio, &t)) ? } $else { - socket_error(C.fcntl(sockfd, C.F_SETFL, C.fcntl(sockfd, C.F_GETFL) | C.O_NONBLOCK)) + socket_error(C.fcntl(sockfd, C.F_SETFL, C.fcntl(sockfd, C.F_GETFL) | C.O_NONBLOCK)) ? } return s } @@ -281,7 +282,7 @@ fn tcp_socket_from_handle(sockfd int) ?TcpSocket { t := true socket_error(C.ioctlsocket(sockfd, fionbio, &t)) ? } $else { - socket_error(C.fcntl(sockfd, C.F_SETFL, C.fcntl(sockfd, C.F_GETFL) | C.O_NONBLOCK)) + socket_error(C.fcntl(sockfd, C.F_SETFL, C.fcntl(sockfd, C.F_GETFL) | C.O_NONBLOCK)) ? } return s } @@ -322,12 +323,12 @@ fn (mut s TcpSocket) connect(a string) ? { return none } _ := error_code() - write_result := s.@select(.write, connect_timeout) ? + write_result := s.@select(.write, net.connect_timeout) ? if write_result { // succeeded return none } - except_result := s.@select(.except, connect_timeout) ? + except_result := s.@select(.except, net.connect_timeout) ? if except_result { return err_connect_failed } diff --git a/vlib/net/tcp_simple_client_server_test.v b/vlib/net/tcp_simple_client_server_test.v index 51e572c1db..dffe45edf3 100644 --- a/vlib/net/tcp_simple_client_server_test.v +++ b/vlib/net/tcp_simple_client_server_test.v @@ -64,7 +64,10 @@ fn test_socket_write_and_read() { message1 := 'a message 1' socket.write_str(message1) or { assert false } mut rbuf := []byte{len: message1.len} - client.read(mut rbuf) + client.read(mut rbuf) or { + assert false + return + } line := rbuf.bytestr() assert line == message1 } @@ -127,8 +130,14 @@ fn test_socket_read_line_long_line_without_eol() { cleanup(mut server, mut client, mut socket) } message := strings.repeat_string('123', 400) - socket.write_str(message) - socket.write_str('\n') + socket.write_str(message) or { + assert false + return + } + socket.write_str('\n') or { + assert false + return + } line := reader.read_line() or { assert false return diff --git a/vlib/net/udp.v b/vlib/net/udp.v index a823c3670f..e69cf39ab1 100644 --- a/vlib/net/udp.v +++ b/vlib/net/udp.v @@ -33,8 +33,8 @@ pub fn dial_udp(laddr string, raddr string) ?&UdpConn { } return &UdpConn{ sock: sock - read_timeout: udp_default_read_timeout - write_timeout: udp_default_write_timeout + read_timeout: net.udp_default_read_timeout + write_timeout: net.udp_default_write_timeout } } @@ -162,8 +162,8 @@ pub fn listen_udp(port int) ?&UdpConn { s := new_udp_socket(port) ? return &UdpConn{ sock: s - read_timeout: udp_default_read_timeout - write_timeout: udp_default_write_timeout + read_timeout: net.udp_default_read_timeout + write_timeout: net.udp_default_write_timeout } } @@ -183,7 +183,7 @@ fn new_udp_socket(local_port int) ?&UdpSocket { t := true socket_error(C.ioctlsocket(sockfd, fionbio, &t)) ? } $else { - socket_error(C.fcntl(sockfd, C.F_SETFD, C.O_NONBLOCK)) + socket_error(C.fcntl(sockfd, C.F_SETFD, C.O_NONBLOCK)) ? } // In UDP we always have to bind to a port validate_port(local_port) ? diff --git a/vlib/net/urllib/urllib.v b/vlib/net/urllib/urllib.v index 6aba9189f6..6c3d989f2d 100644 --- a/vlib/net/urllib/urllib.v +++ b/vlib/net/urllib/urllib.v @@ -53,8 +53,8 @@ fn should_escape(c byte, mode EncodingMode) bool { // we could possibly allow, and parse will reject them if we // escape them (because hosts can`t use %-encoding for // ASCII bytes). - if c in - [`!`, `$`, `&`, `\\`, `(`, `)`, `*`, `+`, `,`, `;`, `=`, `:`, `[`, `]`, `<`, `>`, `"`] { + if + c in [`!`, `$`, `&`, `\\`, `(`, `)`, `*`, `+`, `,`, `;`, `=`, `:`, `[`, `]`, `<`, `>`, `"`] { return false } } @@ -162,7 +162,7 @@ fn unescape(s_ string, mode EncodingMode) ?string { if s.len > 3 { s = s[..3] } - return error(error_msg(err_msg_escape, s)) + return error(error_msg(urllib.err_msg_escape, s)) } // Per https://tools.ietf.org/html/rfc3986#page-21 // in the host component %-encoding can only be used @@ -171,7 +171,7 @@ fn unescape(s_ string, mode EncodingMode) ?string { // introduces %25 being allowed to escape a percent sign // in IPv6 scoped-address literals. Yay. if mode == .encode_host && unhex(s[i + 1]) < 8 && s[i..i + 3] != '%25' { - return error(error_msg(err_msg_escape, s[i..i + 3])) + return error(error_msg(urllib.err_msg_escape, s[i..i + 3])) } if mode == .encode_zone { // RFC 6874 says basically 'anything goes' for zone identifiers @@ -183,7 +183,7 @@ fn unescape(s_ string, mode EncodingMode) ?string { // But Windows puts spaces here! Yay. v := ((unhex(s[i + 1]) << byte(4)) | unhex(s[i + 2])) if s[i..i + 3] != '%25' && v != ` ` && should_escape(v, .encode_host) { - error(error_msg(err_msg_escape, s[i..i + 3])) + error(error_msg(urllib.err_msg_escape, s[i..i + 3])) } } i += 3 @@ -193,9 +193,8 @@ fn unescape(s_ string, mode EncodingMode) ?string { i++ } else { - if (mode == .encode_host || - mode == .encode_zone) && - s[i] < 0x80 && should_escape(s[i], mode) { + if (mode == .encode_host || mode == .encode_zone) && s[i] < 0x80 + && should_escape(s[i], mode) { error(error_msg('unescape: invalid character in host name', s[i..i + 1])) } i++ @@ -429,11 +428,12 @@ fn split(s string, sep byte, cutc bool) (string, string) { pub fn parse(rawurl string) ?URL { // Cut off #frag u, frag := split(rawurl, `#`, true) - mut url := parse_url(u, false) or { return error(error_msg(err_msg_parse, u)) } + mut url := parse_url(u, false) or { return error(error_msg(urllib.err_msg_parse, u)) } if frag == '' { return url } - f := unescape(frag, .encode_fragment) or { return error(error_msg(err_msg_parse, u)) } + f := unescape(frag, .encode_fragment) or { return error(error_msg(urllib.err_msg_parse, + u)) } url.fragment = f return url } @@ -570,7 +570,7 @@ fn parse_host(host string) ?string { // parse an IP-Literal in RFC 3986 and RFC 6874. // E.g., '[fe80::1]', '[fe80::1%25en0]', '[fe80::1]:80'. mut i := host.last_index(']') or { - return error(error_msg("parse_host: missing \']\' in host", '')) + return error(error_msg("parse_host: missing ']' in host", '')) } mut colon_port := host[i + 1..] if !valid_optional_port(colon_port) { @@ -785,7 +785,7 @@ pub fn parse_query(query string) ?Values { // but any errors will be silent fn parse_query_silent(query string) Values { mut m := new_values() - parse_query_values(mut m, query) + parse_query_values(mut m, query) or { } return m } @@ -1029,7 +1029,8 @@ pub fn valid_userinfo(s string) bool { continue } match r { - `-`, `.`, `_`, `:`, `~`, `!`, `$`, `&`, `\\`, `(`, `)`, `*`, `+`, `,`, `;`, `=`, `%`, `@` { + `-`, `.`, `_`, `:`, `~`, `!`, `$`, `&`, `\\`, `(`, `)`, `*`, `+`, `,`, `;`, `=`, `%`, + `@` { continue } else { diff --git a/vlib/os/inode_test.v b/vlib/os/inode_test.v index c2b5aa781d..395756e228 100644 --- a/vlib/os/inode_test.v +++ b/vlib/os/inode_test.v @@ -9,16 +9,16 @@ const ( fn testsuite_begin() { eprintln('testsuite_begin, tfolder = $tfolder') - os.rmdir_all(tfolder) + os.rmdir_all(tfolder) or { } assert !os.is_dir(tfolder) - os.mkdir_all(tfolder) + os.mkdir_all(tfolder) or { panic(err) } os.chdir(tfolder) assert os.is_dir(tfolder) } fn testsuite_end() { os.chdir(os.wd_at_startup) - os.rmdir_all(tfolder) + os.rmdir_all(tfolder) or { panic(err) } assert !os.is_dir(tfolder) } @@ -27,7 +27,7 @@ fn test_inode_file_type() { mut file := os.open_file(filename, 'w', 0o600) or { return } file.close() mode := os.inode(filename) - os.rm(filename) + os.rm(filename) or { panic(err) } assert mode.typ == .regular } @@ -36,7 +36,7 @@ fn test_inode_file_owner_permission() { mut file := os.open_file(filename, 'w', 0o600) or { return } file.close() mode := os.inode(filename) - os.rm(filename) + os.rm(filename) or { } assert mode.owner.read assert mode.owner.write assert !mode.owner.execute diff --git a/vlib/os/os.v b/vlib/os/os.v index 86c83baaae..f1d25d70af 100644 --- a/vlib/os/os.v +++ b/vlib/os/os.v @@ -46,7 +46,7 @@ pub fn cp_all(src string, dst string, overwrite bool) ? { } if exists(adjusted_path) { if overwrite { - rm(adjusted_path) + rm(adjusted_path) ? } else { return error('Destination file path already exist') } @@ -65,7 +65,7 @@ pub fn cp_all(src string, dst string, overwrite bool) ? { mkdir(dp) ? } cp_all(sp, dp, overwrite) or { - rmdir(dp) + rmdir(dp) or { return error(err) } return error(err) } } @@ -144,7 +144,7 @@ pub fn file_exists(_path string) bool { [deprecated] pub fn rmdir_recursive(path string) { eprintln('warning: `os.rmdir_recursive` has been deprecated, use `os.rmdir_all` instead') - rmdir_all(path) + rmdir_all(path) or { panic(err) } } // rmdir_all recursively removes the specified directory. @@ -154,7 +154,7 @@ pub fn rmdir_all(path string) ? { for item in items { fullpath := join_path(path, item) if is_dir(fullpath) { - rmdir_all(fullpath) + rmdir_all(fullpath) or { ret_err = err } } rm(fullpath) or { ret_err = err } } @@ -315,7 +315,7 @@ pub fn home_dir() string { // write_file writes `text` data to a file in `path`. pub fn write_file(path string, text string) ? { mut f := create(path) ? - f.write(text.bytes()) + f.write(text.bytes()) ? f.close() } diff --git a/vlib/os/os_nix.c.v b/vlib/os/os_nix.c.v index cccd975c70..a44cf63487 100644 --- a/vlib/os/os_nix.c.v +++ b/vlib/os/os_nix.c.v @@ -280,7 +280,7 @@ pub fn is_writable_folder(folder string) ?bool { } C.close(x) } - rm(tmp_perm_check) + rm(tmp_perm_check) ? return true } diff --git a/vlib/os/os_test.v b/vlib/os/os_test.v index b17f9e5ebb..430e750e30 100644 --- a/vlib/os/os_test.v +++ b/vlib/os/os_test.v @@ -13,9 +13,9 @@ const args_at_start = os.args.clone() fn testsuite_begin() { eprintln('testsuite_begin, tfolder = $tfolder') - os.rmdir_all(tfolder) + os.rmdir_all(tfolder) or { } assert !os.is_dir(tfolder) - os.mkdir_all(tfolder) + os.mkdir_all(tfolder) or { panic(err) } os.chdir(tfolder) assert os.is_dir(tfolder) // println('args_at_start: $args_at_start') @@ -25,7 +25,7 @@ fn testsuite_begin() { fn testsuite_end() { os.chdir(os.wd_at_startup) - os.rmdir_all(tfolder) + os.rmdir_all(tfolder) or { } assert !os.is_dir(tfolder) // eprintln('testsuite_end , tfolder = $tfolder removed.') } @@ -38,12 +38,12 @@ fn test_open_file() { os.File{} } mut file := os.open_file(filename, 'w+', 0o666) or { panic(err) } - file.write_str(hello) + file.write_str(hello) or { panic(err) } file.close() assert hello.len == os.file_size(filename) read_hello := os.read_file(filename) or { panic('error reading file $filename') } assert hello == read_hello - os.rm(filename) + os.rm(filename) or { panic(err) } } fn test_open_file_binary() { @@ -60,7 +60,7 @@ fn test_open_file_binary() { assert hello.len == os.file_size(filename) read_hello := os.read_bytes(filename) or { panic('error reading file $filename') } assert bytes == read_hello - os.rm(filename) + os.rm(filename) or { panic(err) } } // fn test_file_get_line() { @@ -87,23 +87,23 @@ fn test_create_file() { filename := './test1.txt' hello := 'hello world!' mut f := os.create(filename) or { panic(err) } - f.write_str(hello) + f.write_str(hello) or { panic(err) } f.close() assert hello.len == os.file_size(filename) - os.rm(filename) + os.rm(filename) or { panic(err) } } fn test_is_file() { // Setup work_dir := os.join_path(os.getwd(), 'is_file_test') - os.mkdir_all(work_dir) + os.mkdir_all(work_dir) or { panic(err) } tfile := os.join_path(work_dir, 'tmp_file') // Test things that shouldn't be a file assert os.is_file(work_dir) == false assert os.is_file('non-existent_file.tmp') == false // Test file tfile_content := 'temporary file' - os.write_file(tfile, tfile_content) + os.write_file(tfile, tfile_content) or { panic(err) } assert os.is_file(tfile) // Test dir symlinks $if windows { @@ -126,11 +126,11 @@ fn test_is_file() { fn test_write_and_read_string_to_file() { filename := './test1.txt' hello := 'hello world!' - os.write_file(filename, hello) + os.write_file(filename, hello) or { panic(err) } assert hello.len == os.file_size(filename) read_hello := os.read_file(filename) or { panic('error reading file $filename') } assert hello == read_hello - os.rm(filename) + os.rm(filename) or { panic(err) } } // test_write_and_read_bytes checks for regressions made in the functions @@ -166,7 +166,7 @@ fn test_write_and_read_bytes() { assert nread == 0 file_read.close() // We finally delete the test file. - os.rm(file_name) + os.rm(file_name) or { panic(err) } } fn test_create_and_delete_folder() { @@ -175,7 +175,7 @@ fn test_create_and_delete_folder() { assert os.is_dir(folder) folder_contents := os.ls(folder) or { panic(err) } assert folder_contents.len == 0 - os.rmdir(folder) + os.rmdir(folder) or { panic(err) } folder_exists := os.is_dir(folder) assert folder_exists == false } @@ -191,61 +191,61 @@ fn test_walk() { folder := 'test_walk' os.mkdir(folder) or { panic(err) } file1 := folder + os.path_separator + 'test1' - os.write_file(file1, 'test-1') + os.write_file(file1, 'test-1') or { panic(err) } os.walk(folder, walk_callback) - os.rm(file1) - os.rmdir(folder) + os.rm(file1) or { panic(err) } + os.rmdir(folder) or { panic(err) } } fn test_cp() { old_file_name := 'cp_example.txt' new_file_name := 'cp_new_example.txt' - os.write_file(old_file_name, 'Test data 1 2 3, V is awesome #$%^[]!~⭐') + os.write_file(old_file_name, 'Test data 1 2 3, V is awesome #$%^[]!~⭐') or { panic(err) } os.cp(old_file_name, new_file_name) or { panic('$err: errcode: $errcode') } old_file := os.read_file(old_file_name) or { panic(err) } new_file := os.read_file(new_file_name) or { panic(err) } assert old_file == new_file - os.rm(old_file_name) - os.rm(new_file_name) + os.rm(old_file_name) or { panic(err) } + os.rm(new_file_name) or { panic(err) } } fn test_mv() { work_dir := os.join_path(os.getwd(), 'mv_test') - os.mkdir_all(work_dir) + os.mkdir_all(work_dir) or { panic(err) } // Setup test files tfile1 := os.join_path(work_dir, 'file') tfile2 := os.join_path(work_dir, 'file.test') tfile3 := os.join_path(work_dir, 'file.3') tfile_content := 'temporary file' - os.write_file(tfile1, tfile_content) - os.write_file(tfile2, tfile_content) + os.write_file(tfile1, tfile_content) or { panic(err) } + os.write_file(tfile2, tfile_content) or { panic(err) } // Setup test dirs tdir1 := os.join_path(work_dir, 'dir') tdir2 := os.join_path(work_dir, 'dir2') tdir3 := os.join_path(work_dir, 'dir3') - mkdir(tdir1) - mkdir(tdir2) + os.mkdir(tdir1) or { panic(err) } + os.mkdir(tdir2) or { panic(err) } // Move file with no extension to dir - os.mv(tfile1, tdir1) + os.mv(tfile1, tdir1) or { panic(err) } mut expected := os.join_path(tdir1, 'file') assert os.exists(expected) && !is_dir(expected) == true // Move dir with contents to other dir - os.mv(tdir1, tdir2) + os.mv(tdir1, tdir2) or { panic(err) } expected = os.join_path(tdir2, 'dir') assert os.exists(expected) && is_dir(expected) == true expected = os.join_path(tdir2, 'dir', 'file') assert os.exists(expected) && !is_dir(expected) == true // Move dir with contents to other dir (by renaming) - os.mv(os.join_path(tdir2, 'dir'), tdir3) + os.mv(os.join_path(tdir2, 'dir'), tdir3) or { panic(err) } expected = tdir3 assert os.exists(expected) && is_dir(expected) == true assert os.is_dir_empty(tdir2) == true // Move file with extension to dir - os.mv(tfile2, tdir2) + os.mv(tfile2, tdir2) or { panic(err) } expected = os.join_path(tdir2, 'file.test') assert os.exists(expected) && !is_dir(expected) == true // Move file to dir (by renaming) - os.mv(os.join_path(tdir2, 'file.test'), tfile3) + os.mv(os.join_path(tdir2, 'file.test'), tfile3) or { panic(err) } expected = tfile3 assert os.exists(expected) && !is_dir(expected) == true } @@ -253,14 +253,14 @@ fn test_mv() { fn test_cp_r() { // fileX -> dir/fileX // NB: clean up of the files happens inside the cleanup_leftovers function - os.write_file('ex1.txt', 'wow!') + os.write_file('ex1.txt', 'wow!') or { panic(err) } os.mkdir('ex') or { panic(err) } os.cp_all('ex1.txt', 'ex', false) or { panic(err) } old := os.read_file('ex1.txt') or { panic(err) } new := os.read_file('ex/ex1.txt') or { panic(err) } assert old == new os.mkdir('ex/ex2') or { panic(err) } - os.write_file('ex2.txt', 'great!') + os.write_file('ex2.txt', 'great!') or { panic(err) } os.cp_all('ex2.txt', 'ex/ex2', false) or { panic(err) } old2 := os.read_file('ex2.txt') or { panic(err) } new2 := os.read_file('ex/ex2/ex2.txt') or { panic(err) } @@ -274,12 +274,12 @@ fn test_tmpdir() { assert t.len > 0 assert os.is_dir(t) tfile := t + os.path_separator + 'tmpfile.txt' - os.rm(tfile) // just in case + os.rm(tfile) or { } // just in case tfile_content := 'this is a temporary file' - os.write_file(tfile, tfile_content) + os.write_file(tfile, tfile_content) or { panic(err) } tfile_content_read := os.read_file(tfile) or { panic(err) } assert tfile_content_read == tfile_content - os.rm(tfile) + os.rm(tfile) or { panic(err) } } fn test_is_writable_folder() { @@ -299,15 +299,15 @@ fn test_make_symlink_check_is_link_and_remove_symlink() { } folder := 'tfolder' symlink := 'tsymlink' - os.rm(symlink) - os.rm(folder) + os.rm(symlink) or { } + os.rm(folder) or { } os.mkdir(folder) or { panic(err) } folder_contents := os.ls(folder) or { panic(err) } assert folder_contents.len == 0 os.system('ln -s $folder $symlink') assert os.is_link(symlink) == true - os.rm(symlink) - os.rm(folder) + os.rm(symlink) or { panic(err) } + os.rm(folder) or { panic(err) } folder_exists := os.is_dir(folder) assert folder_exists == false symlink_exists := os.is_link(symlink) @@ -343,8 +343,8 @@ fn test_symlink() { os.symlink('symlink', 'symlink2') or { panic(err) } assert os.exists('symlink2') // cleanup - os.rm('symlink') - os.rm('symlink2') + os.rm('symlink') or { panic(err) } + os.rm('symlink2') or { panic(err) } } fn test_is_executable_writable_readable() { @@ -367,7 +367,7 @@ fn test_is_executable_writable_readable() { assert os.is_executable(file_name) } // We finally delete the test file. - os.rm(file_name) + os.rm(file_name) or { panic(err) } } fn test_ext() { @@ -438,7 +438,7 @@ fn test_write_file_array_bytes() { for i in 0 .. maxn { arr[i] = 65 + byte(i) } - os.write_file_array(fpath, arr) + os.write_file_array(fpath, arr) or { panic(err) } rarr := os.read_bytes(fpath) or { panic(err) } assert arr == rarr // eprintln(arr.str()) @@ -451,7 +451,7 @@ fn test_write_file_array_structs() { for i in 0 .. maxn { arr[i] = IntPoint{65 + i, 65 + i + 10} } - os.write_file_array(fpath, arr) + os.write_file_array(fpath, arr) or { panic(err) } rarr := os.read_file_array(fpath) assert rarr == arr assert rarr.len == maxn @@ -519,6 +519,6 @@ fn test_posix_set_bit() { } mode = u32(s.st_mode) & 0o7777 assert mode == 0o0755 - rm(fpath) + rm(fpath) or { } } } diff --git a/vlib/term/ui/termios_nix.c.v b/vlib/term/ui/termios_nix.c.v index 26160b6891..c1b17d3336 100644 --- a/vlib/term/ui/termios_nix.c.v +++ b/vlib/term/ui/termios_nix.c.v @@ -9,9 +9,10 @@ import time #include #include #include - fn C.tcgetattr() + fn C.tcsetattr() + fn C.ioctl(fd int, request u64, arg voidptr) int struct C.termios { @@ -103,7 +104,6 @@ fn (mut ctx Context) termios_setup() ? { // feature-test rgb (truecolor) support ctx.enable_rgb = supports_truecolor() } - // Prevent stdin from blocking by making its read time 0 termios.c_cc[C.VTIME] = 0 termios.c_cc[C.VMIN] = 0 @@ -124,7 +124,7 @@ fn (mut ctx Context) termios_setup() ? { os.signal(C.SIGCONT, fn () { mut c := ctx_ptr if c != 0 { - c.termios_setup() + c.termios_setup() or { panic(err) } c.window_height, c.window_width = get_terminal_size() mut event := &Event{ typ: .resized @@ -136,7 +136,7 @@ fn (mut ctx Context) termios_setup() ? { } }) for code in ctx.cfg.reset { - os.signal(code, fn() { + os.signal(code, fn () { mut c := ctx_ptr if c != 0 { c.cleanup() @@ -145,7 +145,7 @@ fn (mut ctx Context) termios_setup() ? { }) } - os.signal(C.SIGWINCH, fn() { + os.signal(C.SIGWINCH, fn () { mut c := ctx_ptr if c != 0 { c.window_height, c.window_width = get_terminal_size() @@ -166,10 +166,14 @@ fn get_cursor_position() (int, int) { print('\033[6n') buf := malloc(25) len := C.read(C.STDIN_FILENO, buf, 24) - unsafe { buf[len] = 0 } + unsafe { + buf[len] = 0 + } s := tos(buf, len) a := s[2..].split(';') - if a.len != 2 { return -1, -1 } + if a.len != 2 { + return -1, -1 + } return a[0].int(), a[1].int() } @@ -184,14 +188,16 @@ fn supports_truecolor() bool { print('\x1bP\$qm\x1b\\') buf := malloc(25) len := C.read(C.STDIN_FILENO, buf, 24) - unsafe { buf[len] = 0 } + unsafe { + buf[len] = 0 + } s := tos(buf, len) return '1:2:3' in s - } fn termios_reset() { - C.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH /* C.TCSANOW ?? */, &termios_at_startup) + // C.TCSANOW ?? + C.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH, &ui.termios_at_startup) print('\x1b[?1003l\x1b[?1006l\x1b[?25h') c := ctx_ptr if c != 0 && c.cfg.use_alternate_buffer { @@ -201,7 +207,6 @@ fn termios_reset() { } /////////////////////////////////////////// - // TODO: do multiple sleep/read cycles, rather than one big one fn (mut ctx Context) termios_loop() { frame_time := 1_000_000 / ctx.cfg.frame_rate @@ -221,7 +226,8 @@ fn (mut ctx Context) termios_loop() { sw.restart() if ctx.cfg.event_fn != voidptr(0) { unsafe { - len := C.read(C.STDIN_FILENO, byteptr(ctx.read_buf.data) + ctx.read_buf.len, ctx.read_buf.cap - ctx.read_buf.len) + len := C.read(C.STDIN_FILENO, byteptr(ctx.read_buf.data) + ctx.read_buf.len, + ctx.read_buf.cap - ctx.read_buf.len) ctx.resize_arr(ctx.read_buf.len + len) } if ctx.read_buf.len > 0 { @@ -243,7 +249,9 @@ fn (mut ctx Context) parse_events() { mut nr_iters := 0 for ctx.read_buf.len > 0 { nr_iters++ - if nr_iters > 100 { ctx.shift(1) } + if nr_iters > 100 { + ctx.shift(1) + } mut event := &Event(0) if ctx.read_buf[0] == 0x1b { e, len := escape_sequence(ctx.read_buf.bytestr()) @@ -272,41 +280,52 @@ fn single_char(buf string) &Event { match ch { // special handling for `ctrl + letter` - // TODO: Fix assoc in V and remove this workaround :/ // 1 ... 26 { event = Event{ ...event, code: KeyCode(96 | ch), modifiers: ctrl } } // 65 ... 90 { event = Event{ ...event, code: KeyCode(32 | ch), modifiers: shift } } - - // The bit `or`s here are really just `+`'s, just written in this way for a tiny performance improvement // don't treat tab, enter as ctrl+i, ctrl+j - 1 ... 8, 11 ... 26 { event = &Event{ typ: event.typ, ascii: event.ascii, utf8: event.utf8, code: KeyCode(96 | ch), modifiers: ctrl } } - 65 ... 90 { event = &Event{ typ: event.typ, ascii: event.ascii, utf8: event.utf8, code: KeyCode(32 | ch), modifiers: shift } } - + 1...8, 11...26 { event = &Event{ + typ: event.typ + ascii: event.ascii + utf8: event.utf8 + code: KeyCode(96 | ch) + modifiers: ctrl + } } + 65...90 { event = &Event{ + typ: event.typ + ascii: event.ascii + utf8: event.utf8 + code: KeyCode(32 | ch) + modifiers: shift + } } else {} } return event } -[inline] // Gets an entire, independent escape sequence from the buffer // Normally, this just means reading until the first letter, but there are some exceptions... fn escape_end(buf string) int { mut i := 0 for { - if i + 1 == buf.len { return buf.len } + if i + 1 == buf.len { + return buf.len + } if buf[i].is_letter() || buf[i] == `~` { if buf[i] == `O` && i + 2 <= buf.len { - n := buf[i+1] + n := buf[i + 1] if (n >= `A` && n <= `D`) || (n >= `P` && n <= `S`) || n == `F` || n == `H` { return i + 2 } } return i + 1 - // escape hatch to avoid potential issues/crashes, although ideally this should never eval to true - } else if buf[i + 1] == 0x1b { return i + 1 } + // escape hatch to avoid potential issues/crashes, although ideally this should never eval to true + } else if buf[i + 1] == 0x1b { + return i + 1 + } i++ } // this point should be unreachable @@ -339,51 +358,85 @@ fn escape_sequence(buf_ string) (&Event, int) { modifiers: c.modifiers | alt }, 2 } - // ---------------- // Mouse events // ---------------- - // Documentation: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking if buf.len > 2 && buf[1] == `<` { split := buf[2..].split(';') - if split.len < 3 { return &Event(0), 0 } + if split.len < 3 { + return &Event(0), 0 + } typ, x, y := split[0].int(), split[1].int(), split[2].int() lo := typ & 0b00011 hi := typ & 0b11100 mut modifiers := u32(0) - if hi & 4 != 0 { modifiers |= shift } - if hi & 8 != 0 { modifiers |= alt } - if hi & 16 != 0 { modifiers |= ctrl } + if hi & 4 != 0 { + modifiers |= shift + } + if hi & 8 != 0 { + modifiers |= alt + } + if hi & 16 != 0 { + modifiers |= ctrl + } match typ { 0...31 { last := buf[buf.len - 1] button := if lo < 3 { MouseButton(lo + 1) } else { MouseButton.unknown } - event := if last == `m` || lo == 3 { EventType.mouse_up } else { EventType.mouse_down } + event := if last == `m` || lo == 3 { + EventType.mouse_up + } else { + EventType.mouse_down + } - return &Event{ typ: event, x: x, y: y, button: button, modifiers: modifiers utf8: single }, end + return &Event{ + typ: event + x: x + y: y + button: button + modifiers: modifiers + utf8: single + }, end } 32...63 { button, event := if lo < 3 { - MouseButton(lo + 1), EventType.mouse_drag - } else { - MouseButton.unknown, EventType.mouse_move - } + MouseButton(lo + 1), EventType.mouse_drag + } else { + MouseButton.unknown, EventType.mouse_move + } - return &Event{ typ: event, x: x, y: y, button: button, modifiers: modifiers, utf8: single }, end + return &Event{ + typ: event + x: x + y: y + button: button + modifiers: modifiers + utf8: single + }, end } 64...95 { direction := if typ & 1 == 0 { Direction.down } else { Direction.up } - return &Event{ typ: .mouse_scroll, x: x, y: y, direction: direction, modifiers: modifiers, utf8: single }, end - } else { - return &Event{ typ: .unknown, utf8: single }, end + return &Event{ + typ: .mouse_scroll + x: x + y: y + direction: direction + modifiers: modifiers + utf8: single + }, end + } + else { + return &Event{ + typ: .unknown + utf8: single + }, end } } } - // ---------------------------- // Special key combinations // ---------------------------- @@ -391,29 +444,29 @@ fn escape_sequence(buf_ string) (&Event, int) { mut code := KeyCode.null mut modifiers := u32(0) match buf { - '[A', 'OA' { code = .up } - '[B', 'OB' { code = .down } - '[C', 'OC' { code = .right } - '[D', 'OD' { code = .left } - '[5~', '[[5~' { code = .page_up } - '[6~', '[[6~' { code = .page_down } + '[A', 'OA' { code = .up } + '[B', 'OB' { code = .down } + '[C', 'OC' { code = .right } + '[D', 'OD' { code = .left } + '[5~', '[[5~' { code = .page_up } + '[6~', '[[6~' { code = .page_down } '[F', 'OF', '[4~', '[[8~' { code = .end } '[H', 'OH', '[1~', '[[7~' { code = .home } - '[2~' { code = .insert } - '[3~' { code = .delete } - 'OP', '[11~' { code = .f1 } - 'OQ', '[12~' { code = .f2 } - 'OR', '[13~' { code = .f3 } - 'OS', '[14~' { code = .f4 } - '[15~' { code = .f5 } - '[17~' { code = .f6 } - '[18~' { code = .f7 } - '[19~' { code = .f8 } - '[20~' { code = .f9 } - '[21~' { code = .f10 } - '[23~' { code = .f11 } - '[24~' { code = .f12 } - else {} + '[2~' { code = .insert } + '[3~' { code = .delete } + 'OP', '[11~' { code = .f1 } + 'OQ', '[12~' { code = .f2 } + 'OR', '[13~' { code = .f3 } + 'OS', '[14~' { code = .f4 } + '[15~' { code = .f5 } + '[17~' { code = .f6 } + '[18~' { code = .f7 } + '[19~' { code = .f8 } + '[20~' { code = .f9 } + '[21~' { code = .f10 } + '[23~' { code = .f11 } + '[24~' { code = .f12 } + else {} } if buf == '[Z' { @@ -455,5 +508,10 @@ fn escape_sequence(buf_ string) (&Event, int) { } } - return &Event{ typ: .key_down, code: code, utf8: single, modifiers: modifiers }, end + return &Event{ + typ: .key_down + code: code + utf8: single + modifiers: modifiers + }, end } diff --git a/vlib/v/builder/c.v b/vlib/v/builder/c.v index 70ef58e71f..e18d1a5fee 100644 --- a/vlib/v/builder/c.v +++ b/vlib/v/builder/c.v @@ -35,7 +35,7 @@ pub fn (mut b Builder) build_c(v_files []string, out_file string) { b.info('build_c($out_file)') output2 := b.gen_c(v_files) mut f := os.create(out_file) or { panic(err) } - f.writeln(output2) + f.writeln(output2) or { panic(err) } f.close() // os.write_file(out_file, b.gen_c(v_files)) } @@ -75,9 +75,9 @@ pub fn (mut b Builder) compile_c() { bundle_name := b.pref.out_name.split('/').last() bundle_id := if b.pref.bundle_id != '' { b.pref.bundle_id } else { 'app.vlang.$bundle_name' } display_name := if b.pref.display_name != '' { b.pref.display_name } else { bundle_name } - os.mkdir('${display_name}.app') + os.mkdir('${display_name}.app') or { panic(err) } os.write_file('${display_name}.app/Info.plist', make_ios_plist(display_name, bundle_id, - bundle_name, 1)) + bundle_name, 1)) or { panic(err) } } b.cc() } diff --git a/vlib/v/builder/cc.v b/vlib/v/builder/cc.v index 7c35f21e3d..12bc21a623 100644 --- a/vlib/v/builder/cc.v +++ b/vlib/v/builder/cc.v @@ -92,7 +92,7 @@ fn (mut v Builder) post_process_c_compiler_output(res os.Result) { if v.pref.is_verbose { eprintln('>> remove tmp file: $tmpfile') } - os.rm(tmpfile) + os.rm(tmpfile) or { panic(err) } } } return @@ -414,7 +414,9 @@ fn (mut v Builder) setup_output_name() { if v.pref.is_verbose { println('Building $v.pref.path to $v.pref.out_name ...') } - v.pref.cache_manager.save('.description.txt', v.pref.path, '${v.pref.path:-30} @ $v.pref.cache_manager.vopts\n') + v.pref.cache_manager.save('.description.txt', v.pref.path, '${v.pref.path:-30} @ $v.pref.cache_manager.vopts\n') or { + panic(err) + } // println('v.table.imports:') // println(v.table.imports) } @@ -734,7 +736,7 @@ fn (mut b Builder) cc_linux_cross() { b.setup_output_name() parent_dir := os.vmodules_dir() if !os.exists(parent_dir) { - os.mkdir(parent_dir) + os.mkdir(parent_dir) or { panic(err) } } sysroot := os.join_path(os.vmodules_dir(), 'linuxroot') if !os.is_dir(sysroot) { @@ -917,7 +919,7 @@ fn (mut v Builder) build_thirdparty_obj_file(path string, moduleflags []cflag.CF // for example thirdparty\tcc\lib\openlibm.o // the best we can do for them is just copy them, // and hope that they work with any compiler... - os.cp(obj_path, opath) + os.cp(obj_path, opath) or { panic(err) } return } println('$obj_path not found, building it in $opath ...') @@ -943,7 +945,9 @@ fn (mut v Builder) build_thirdparty_obj_file(path string, moduleflags []cflag.CF verror(res.output) return } - v.pref.cache_manager.save('.description.txt', obj_path, '${obj_path:-30} @ $cmd\n') + v.pref.cache_manager.save('.description.txt', obj_path, '${obj_path:-30} @ $cmd\n') or { + panic(err) + } println(res.output) } diff --git a/vlib/v/builder/compile.v b/vlib/v/builder/compile.v index 780f99ff4d..18d84e123c 100644 --- a/vlib/v/builder/compile.v +++ b/vlib/v/builder/compile.v @@ -93,12 +93,12 @@ fn (mut b Builder) run_compiled_executable_and_exit() { } if b.pref.os == .ios { device := '"iPhone SE (2nd generation)"' - os.exec('xcrun simctl boot $device') + os.exec('xcrun simctl boot $device') or { panic(err) } bundle_name := b.pref.out_name.split('/').last() display_name := if b.pref.display_name != '' { b.pref.display_name } else { bundle_name } - os.exec('xcrun simctl install $device ${display_name}.app') + os.exec('xcrun simctl install $device ${display_name}.app') or { panic(err) } bundle_id := if b.pref.bundle_id != '' { b.pref.bundle_id } else { 'app.vlang.$bundle_name' } - os.exec('xcrun simctl launch $device $bundle_id') + os.exec('xcrun simctl launch $device $bundle_id') or { panic(err) } } else { exefile := os.real_path(b.pref.out_name) mut cmd := '"$exefile"' @@ -133,7 +133,7 @@ fn (mut v Builder) cleanup_run_executable_after_exit(exefile string) { } if os.is_file(exefile) { v.pref.vrun_elog('remove run executable: $exefile') - os.rm(exefile) + os.rm(exefile) or { panic(err) } } } diff --git a/vlib/v/builder/js.v b/vlib/v/builder/js.v index 654563c20d..04f3ebc205 100644 --- a/vlib/v/builder/js.v +++ b/vlib/v/builder/js.v @@ -29,7 +29,7 @@ pub fn (mut b Builder) build_js(v_files []string, out_file string) { b.info('build_js($out_file)') output := b.gen_js(v_files) mut f := os.create(out_file) or { panic(err) } - f.writeln(output) + f.writeln(output) or { panic(err) } f.close() } diff --git a/vlib/v/builder/msvc.v b/vlib/v/builder/msvc.v index 8a9bd0e5c1..baf3cae284 100644 --- a/vlib/v/builder/msvc.v +++ b/vlib/v/builder/msvc.v @@ -315,7 +315,7 @@ pub fn (mut v Builder) cc_msvc() { // println(res) // println('C OUTPUT:') // Always remove the object file - it is completely unnecessary - os.rm(out_name_obj) + os.rm(out_name_obj) or { panic(err) } } fn (mut v Builder) build_thirdparty_obj_file_with_msvc(path string, moduleflags []cflag.CFlag) { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index e61cf30d33..4c13b40458 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1930,10 +1930,8 @@ pub fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type table.Type) t if expr is ast.CallExpr { if expr.return_type.has_flag(.optional) { if expr.or_block.kind == .absent { - if ret_type != table.void_type { - c.error('${expr.name}() returns an option but is missing an `or {}` block', - expr.pos) - } + c.error('${expr.name}() returns an option, so it should have either an `or {}` block, or `?` at the end', + expr.pos) } else { c.check_or_expr(expr.or_block, ret_type, expr.return_type.clear_flag(.optional)) } diff --git a/vlib/v/checker/tests/optional_method_err.out b/vlib/v/checker/tests/optional_method_err.out index 0029014e49..a67b707bf0 100644 --- a/vlib/v/checker/tests/optional_method_err.out +++ b/vlib/v/checker/tests/optional_method_err.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/optional_method_err.vv:17:10: error: inc_to_limit() returns an option but is missing an `or {}` block +vlib/v/checker/tests/optional_method_err.vv:17:10: error: inc_to_limit() returns an option, so it should have either an `or {}` block, or `?` at the end 15 | mut a := Abc{} 16 | for _ in 0 .. 4 { 17 | _ := a.inc_to_limit(2) diff --git a/vlib/v/checker/tests/optional_void_called_as_normal.out b/vlib/v/checker/tests/optional_void_called_as_normal.out new file mode 100644 index 0000000000..4f5c5b5551 --- /dev/null +++ b/vlib/v/checker/tests/optional_void_called_as_normal.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/optional_void_called_as_normal.vv:7:2: error: foo() returns an option, so it should have either an `or {}` block, or `?` at the end + 5 | fn main() { + 6 | // Calling foo() without ? or an or block, should be an error. + 7 | foo() + | ~~~~~ + 8 | } diff --git a/vlib/v/checker/tests/optional_void_called_as_normal.vv b/vlib/v/checker/tests/optional_void_called_as_normal.vv new file mode 100644 index 0000000000..24017c78c2 --- /dev/null +++ b/vlib/v/checker/tests/optional_void_called_as_normal.vv @@ -0,0 +1,8 @@ +fn foo() ? { + println('foo is called') +} + +fn main() { + // Calling foo() without ? or an or block, should be an error. + foo() +} diff --git a/vlib/v/compiler_errors_test.v b/vlib/v/compiler_errors_test.v index 399062aeb2..a0da40c625 100644 --- a/vlib/v/compiler_errors_test.v +++ b/vlib/v/compiler_errors_test.v @@ -13,7 +13,7 @@ const skip_files = [ const skip_on_ubuntu_musl = [ 'vlib/v/checker/tests/vweb_tmpl_used_var.vv', -] + ] const turn_off_vcolors = os.setenv('VCOLORS', 'never', true) @@ -179,7 +179,7 @@ fn (mut task TaskDescription) execute() { res := os.exec(cli_cmd) or { panic(err) } expected_out_path := program.replace('.vv', '') + task.result_extension if should_autofix && !os.exists(expected_out_path) { - os.write_file(expected_out_path, '') + os.write_file(expected_out_path, '') or { panic(err) } } mut expected := os.read_file(expected_out_path) or { panic(err) } task.expected = clean_line_endings(expected) @@ -192,7 +192,7 @@ fn (mut task TaskDescription) execute() { if task.expected != task.found___ { task.is_error = true if should_autofix { - os.write_file(expected_out_path, res.output) + os.write_file(expected_out_path, res.output) or { panic(err) } } } } diff --git a/vlib/v/fmt/fmt_keep_test.v b/vlib/v/fmt/fmt_keep_test.v index 5634da5a90..c8d1ad3e69 100644 --- a/vlib/v/fmt/fmt_keep_test.v +++ b/vlib/v/fmt/fmt_keep_test.v @@ -67,7 +67,7 @@ fn test_fmt() { continue } vfmt_result_file := os.join_path(tmpfolder, 'vfmt_run_over_$ifilename') - os.write_file(vfmt_result_file, result_ocontent) + os.write_file(vfmt_result_file, result_ocontent) or { panic(err) } eprintln(util.color_compare_files(diff_cmd, opath, vfmt_result_file)) continue } diff --git a/vlib/v/fmt/fmt_test.v b/vlib/v/fmt/fmt_test.v index 8cd48e7bdc..1bd7e66274 100644 --- a/vlib/v/fmt/fmt_test.v +++ b/vlib/v/fmt/fmt_test.v @@ -58,7 +58,7 @@ fn test_fmt() { continue } vfmt_result_file := os.join_path(tmpfolder, 'vfmt_run_over_$ifilename') - os.write_file(vfmt_result_file, result_ocontent) + os.write_file(vfmt_result_file, result_ocontent) or { panic(err) } eprintln(util.color_compare_files(diff_cmd, opath, vfmt_result_file)) continue } diff --git a/vlib/v/fmt/fmt_vlib_test.v b/vlib/v/fmt/fmt_vlib_test.v index 252053511a..257bf6f054 100644 --- a/vlib/v/fmt/fmt_vlib_test.v +++ b/vlib/v/fmt/fmt_vlib_test.v @@ -56,7 +56,7 @@ fn test_vlib_fmt() { continue } vfmt_result_file := os.join_path(tmpfolder, 'vfmt_run_over_$ifilename') - os.write_file(vfmt_result_file, result_ocontent) + os.write_file(vfmt_result_file, result_ocontent) or { panic(err) } eprintln(util.color_compare_files(diff_cmd, opath, vfmt_result_file)) continue } diff --git a/vlib/v/gen/js/jsgen_test.v b/vlib/v/gen/js/jsgen_test.v index 00fdbd3c74..2115b8fb68 100644 --- a/vlib/v/gen/js/jsgen_test.v +++ b/vlib/v/gen/js/jsgen_test.v @@ -7,7 +7,7 @@ const ( ) fn testsuite_end() { - os.rmdir_all(main.output_dir) + os.rmdir_all(output_dir) or { } } const there_is_node_available = is_nodejs_working() @@ -15,22 +15,22 @@ const there_is_node_available = is_nodejs_working() fn test_example_compilation() { vexe := os.getenv('VEXE') os.chdir(os.dir(vexe)) - os.mkdir_all(main.output_dir) + os.mkdir_all(output_dir) or { panic(err) } files := find_test_files() for file in files { - path := os.join_path(main.test_dir, file) + path := os.join_path(test_dir, file) println('Testing $file') - v_code := os.system('$vexe $main.v_options -o $main.output_dir${file}.js $path') + v_code := os.system('$vexe $v_options -o $output_dir${file}.js $path') if v_code != 0 { assert false } // Compilation failed assert v_code == 0 - if !main.there_is_node_available { + if !there_is_node_available { println(' ... skipping running $file, there is no NodeJS present') continue } - js_code := os.system('node $main.output_dir${file}.js') + js_code := os.system('node $output_dir${file}.js') if js_code != 0 { assert false } @@ -40,7 +40,7 @@ fn test_example_compilation() { } fn find_test_files() []string { - files := os.ls(main.test_dir) or { panic(err) } + files := os.ls(test_dir) or { panic(err) } // The life example never exits, so tests would hang with it, skip mut tests := files.filter(it.ends_with('.v')).filter(it != 'life.v') tests.sort() diff --git a/vlib/v/gen/x64/tests/x64_test.v b/vlib/v/gen/x64/tests/x64_test.v index 154ffe5ad1..c1905481f8 100644 --- a/vlib/v/gen/x64/tests/x64_test.v +++ b/vlib/v/gen/x64/tests/x64_test.v @@ -15,12 +15,10 @@ fn test_x64() { vexe := os.getenv('VEXE') vroot := os.dir(vexe) dir := os.join_path(vroot, 'vlib/v/gen/x64/tests') - files := os.ls(dir) or { - panic(err) - } + files := os.ls(dir) or { panic(err) } // wrkdir := os.join_path(os.temp_dir(), 'vtests', 'x64') - os.mkdir_all(wrkdir) + os.mkdir_all(wrkdir) or { panic(err) } os.chdir(wrkdir) tests := files.filter(it.ends_with('.vv')) if tests.len == 0 { @@ -48,9 +46,7 @@ fn test_x64() { eprintln(res.output) continue } - mut expected := os.read_file('$dir/${test}.out') or { - panic(err) - } + mut expected := os.read_file('$dir/${test}.out') or { panic(err) } expected = expected.trim_right('\r\n').replace('\r\n', '\n') mut found := res.output.trim_right('\r\n').replace('\r\n', '\n') found = found.trim_space() diff --git a/vlib/v/live/executable/reloader.v b/vlib/v/live/executable/reloader.v index 1bde974291..45c35fc440 100644 --- a/vlib/v/live/executable/reloader.v +++ b/vlib/v/live/executable/reloader.v @@ -127,7 +127,7 @@ fn protected_load_lib(mut r live.LiveReloadInfo, new_lib_path string) { elog(r, '> load_lib OK, new live_lib: $r.live_lib') // removing the .so file from the filesystem after dlopen-ing // it is safe, since it will still be mapped in memory - os.rm(new_lib_path) + os.rm(new_lib_path) or { } } // NB: r.reloader() is executed in a new, independent thread diff --git a/vlib/v/live/live_test.v b/vlib/v/live/live_test.v index f3f0803a30..b4ae91d4ec 100644 --- a/vlib/v/live/live_test.v +++ b/vlib/v/live/live_test.v @@ -60,8 +60,8 @@ fn atomic_write_source(source string) { // NB: here wrtiting is done in 2 steps, since os.write_file can take some time, // during which the file will be modified, but it will still be not completely written. // The os.mv after that, guarantees that the reloader will see a complete valid V program. - os.write_file(tmp_file, source) - os.mv(tmp_file, source_file) + os.write_file(tmp_file, source) or { panic(err) } + os.mv(tmp_file, source_file) or { panic(err) } } // @@ -75,7 +75,7 @@ fn testsuite_begin() { for f in [tmp_file, source_file, output_file, res_original_file, res_changed_file, res_another_file, res_stop_file, ] { - os.rm(f) + os.rm(f) or { } } atomic_write_source(live_program_source) } @@ -105,7 +105,7 @@ fn testsuite_end() { assert histogram['CHANGED'] + histogram['ANOTHER'] > 0 // assert histogram['END'] > 0 for tfile in cleanup_files { - os.rm(tfile) + os.rm(tfile) or { } } } diff --git a/vlib/v/live/live_test_template.vv b/vlib/v/live/live_test_template.vv index 6dd0eb831d..ab2ed0f709 100644 --- a/vlib/v/live/live_test_template.vv +++ b/vlib/v/live/live_test_template.vv @@ -9,9 +9,12 @@ fn append_to_file(fname string, s string) { println('>>>> could not open file $fname for appending, err: $err ') return } - f.writeln(s) - //info := live.info() - //f.writeln('>>> reloads: ${info.reloads} | ok reloads: ${info.reloads_ok}') + f.writeln(s) or { + println('>>>> could not write to $fname, err: $err ') + return + } + // info := live.info() + // f.writeln('>>> reloads: ${info.reloads} | ok reloads: ${info.reloads_ok}') f.close() } @@ -29,6 +32,7 @@ fn pmessage() string { const ( delay = 20 ) + fn edefault(name string, default string) string { res := os.getenv(name) if res == '' { @@ -36,6 +40,7 @@ fn edefault(name string, default string) string { } return res } + fn main() { mut info := live.info() info.recheck_period_ms = 5 @@ -45,7 +50,7 @@ fn main() { pmessage() max_cycles := edefault('LIVE_CYCLES', '1').int() // NB: 1000 * 20 = maximum of ~20s runtime - for i:=0; i 1 { // a, b = b, a diff --git a/vlib/v/pkgconfig/main.v b/vlib/v/pkgconfig/main.v index 1d192b8186..3f53995aea 100644 --- a/vlib/v/pkgconfig/main.v +++ b/vlib/v/pkgconfig/main.v @@ -94,7 +94,7 @@ pub fn (mut m Main) run() ?string { res += pcdep.description } if pc != 0 { - pc.extend(pcdep) + pc.extend(pcdep) ? } else { pc = pcdep } diff --git a/vlib/v/pkgconfig/pkgconfig.v b/vlib/v/pkgconfig/pkgconfig.v index e7ee6ba166..3e7e004a49 100644 --- a/vlib/v/pkgconfig/pkgconfig.v +++ b/vlib/v/pkgconfig/pkgconfig.v @@ -155,7 +155,7 @@ fn (mut pc PkgConfig) resolve(pkgname string) ?string { } pub fn atleast(v string) bool { - v0 := semver.from(version) or { return false } + v0 := semver.from(pkgconfig.version) or { return false } v1 := semver.from(v) or { return false } return v0.gt(v1) } @@ -207,8 +207,8 @@ fn (mut pc PkgConfig) load_require(dep string) ? { if !pcdep.parse(depfile) { return error('required file "$depfile" could not be parsed') } - pcdep.load_requires() or { return error(err) } - pc.extend(pcdep) + pcdep.load_requires() ? + pc.extend(pcdep) ? } fn (mut pc PkgConfig) add_path(path string) { @@ -223,7 +223,7 @@ fn (mut pc PkgConfig) add_path(path string) { fn (mut pc PkgConfig) load_paths() { if pc.options.use_default_paths { - for path in default_paths { + for path in pkgconfig.default_paths { pc.add_path(path) } } diff --git a/vlib/v/pref/pref.v b/vlib/v/pref/pref.v index 80807d8324..e9b8dfd8db 100644 --- a/vlib/v/pref/pref.v +++ b/vlib/v/pref/pref.v @@ -474,10 +474,10 @@ pub fn parse_args(args []string) (&Preferences, string) { // if output_option.len != 0 { res.vrun_elog('remove tmp exe file: $tmp_exe_file_path') - os.rm(tmp_exe_file_path) + os.rm(tmp_exe_file_path) or { } } res.vrun_elog('remove tmp v file: $tmp_v_file_path') - os.rm(tmp_v_file_path) + os.rm(tmp_v_file_path) or { panic(err) } exit(tmp_result) } must_exist(res.path) diff --git a/vlib/v/tests/inout/compiler_test.v b/vlib/v/tests/inout/compiler_test.v index 23668fcfc6..e5ba13b536 100644 --- a/vlib/v/tests/inout/compiler_test.v +++ b/vlib/v/tests/inout/compiler_test.v @@ -33,13 +33,13 @@ fn test_all() { panic(err) } $if windows { - os.rm('./test.exe') + os.rm('./test.exe') or { } $if msvc { - os.rm('./test.ilk') - os.rm('./test.pdb') + os.rm('./test.ilk') or { } + os.rm('./test.pdb') or { } } } $else { - os.rm('./test') + os.rm('./test') or { } } // println('============') // println(res.output) diff --git a/vlib/v/tests/repl/repl_test.v b/vlib/v/tests/repl/repl_test.v index b600f09513..a285da7396 100644 --- a/vlib/v/tests/repl/repl_test.v +++ b/vlib/v/tests/repl/repl_test.v @@ -64,7 +64,7 @@ fn worker_repl(mut p sync.PoolProcessor, idx int, thread_id int) voidptr { tls_bench.cstep = idx tfolder := os.join_path(cdir, 'vrepl_tests_$idx') if os.is_dir(tfolder) { - os.rmdir_all(tfolder) + os.rmdir_all(tfolder) or { panic(err) } } os.mkdir(tfolder) or { panic(err) } file := p.get_string_item(idx) @@ -73,14 +73,14 @@ fn worker_repl(mut p sync.PoolProcessor, idx int, thread_id int) voidptr { fres := runner.run_repl_file(tfolder, session.options.vexec, file) or { session.bmark.fail() tls_bench.fail() - os.rmdir_all(tfolder) + os.rmdir_all(tfolder) or { panic(err) } eprintln(tls_bench.step_message_fail(err)) assert false return sync.no_result } session.bmark.ok() tls_bench.ok() - os.rmdir_all(tfolder) + os.rmdir_all(tfolder) or { panic(err) } println(tls_bench.step_message_ok(fres)) assert true return sync.no_result diff --git a/vlib/v/tests/repl/runner/runner.v b/vlib/v/tests/repl/runner/runner.v index f8b3113ee3..0e03ab6a99 100644 --- a/vlib/v/tests/repl/runner/runner.v +++ b/vlib/v/tests/repl/runner/runner.v @@ -35,37 +35,34 @@ pub fn full_path_to_v(dirs_in int) string { } fn diff_files(file_result string, file_expected string) string { - diffcmd := util.find_working_diff_command() or { - return err - } + diffcmd := util.find_working_diff_command() or { return err } return util.color_compare_files(diffcmd, file_result, file_expected) } pub fn run_repl_file(wd string, vexec string, file string) ?string { vexec_folder := os.dir(vexec) + os.path_separator - fcontent := os.read_file(file) or { - return error('Could not read file $file') - } + fcontent := os.read_file(file) or { return error('Could not read file $file') } content := fcontent.replace('\r', '') input := content.all_before('===output===\n') output := content.all_after('===output===\n').trim_right('\n\r') fname := os.file_name(file) input_temporary_filename := os.real_path(os.join_path(wd, 'input_temporary_filename.txt')) - os.write_file(input_temporary_filename, input) - os.write_file(os.real_path(os.join_path(wd, 'original.txt')), fcontent) + os.write_file(input_temporary_filename, input) or { panic(err) } + os.write_file(os.real_path(os.join_path(wd, 'original.txt')), fcontent) or { panic(err) } rcmd := '"$vexec" repl -replfolder "$wd" -replprefix "${fname}." < $input_temporary_filename' r := os.exec(rcmd) or { - os.rm(input_temporary_filename) + os.rm(input_temporary_filename) or { panic(err) } return error('Could not execute: $rcmd') } - os.rm(input_temporary_filename) + os.rm(input_temporary_filename) or { panic(err) } result := r.output.replace('\r', '').replace('>>> ', '').replace('>>>', '').replace('... ', - '').replace(wd + os.path_separator, '').replace(vexec_folder, '').replace('\\', '/').trim_right('\n\r') + '').replace(wd + os.path_separator, '').replace(vexec_folder, '').replace('\\', + '/').trim_right('\n\r') if result != output { file_result := '${file}.result.txt' file_expected := '${file}.expected.txt' - os.write_file(file_result, result) - os.write_file(file_expected, output) + os.write_file(file_result, result) or { panic(err) } + os.write_file(file_expected, output) or { panic(err) } diff := diff_files(file_result, file_expected) return error('Difference found in REPL file: $file ====> Got : @@ -87,16 +84,14 @@ pub fn run_prod_file(wd string, vexec string, file string) ?string { } expected_content := f_expected_content.replace('\r', '') cmd := '"$vexec" -prod run "$file"' - r := os.exec(cmd) or { - return error('Could not execute: $cmd') - } + r := os.exec(cmd) or { return error('Could not execute: $cmd') } if r.exit_code != 0 { return error('$cmd return exit code: $r.exit_code') } result := r.output.replace('\r', '') if result != expected_content { file_result := '${file}.result.txt' - os.write_file(file_result, result) + os.write_file(file_result, result) or { panic(err) } diff := diff_files(file_result, file_expected) return error('Difference found in test: $file ====> Got : diff --git a/vlib/v/tests/run_v_code_from_stdin_test.v b/vlib/v/tests/run_v_code_from_stdin_test.v index 3c16ec85dd..fde6f33444 100644 --- a/vlib/v/tests/run_v_code_from_stdin_test.v +++ b/vlib/v/tests/run_v_code_from_stdin_test.v @@ -19,7 +19,7 @@ fn pipe_to_v_run() ? { // eprintln('>> cmd: $cmd | res: $res') assert res.exit_code == 0 assert res.output.replace('\r', '').trim_space().split('\n') == ['4', 'hello'] - os.rm(tmp_v_file) + os.rm(tmp_v_file) or { panic(err) } assert !os.exists(tmp_v_file) } diff --git a/vlib/v/tests/valgrind/valgrind_test.v b/vlib/v/tests/valgrind/valgrind_test.v index 066ca512dd..c3110e93c1 100644 --- a/vlib/v/tests/valgrind/valgrind_test.v +++ b/vlib/v/tests/valgrind/valgrind_test.v @@ -53,13 +53,11 @@ fn test_all() { files := os.ls(dir) or { panic(err) } // wrkdir := os.join_path(os.temp_dir(), 'vtests', 'valgrind') - os.mkdir_all(wrkdir) + os.mkdir_all(wrkdir) or { panic(err) } os.chdir(wrkdir) // - tests := vtest.filter_vtest_only(files.filter(it.ends_with('.v') && !it.ends_with('_test.v')), - - basepath: valgrind_test_path - ) + only_ordinary_v_files := files.filter(it.ends_with('.v') && !it.ends_with('_test.v')) + tests := vtest.filter_vtest_only(only_ordinary_v_files, basepath: valgrind_test_path) bench.set_total_expected_steps(tests.len) for test in tests { bench.step() diff --git a/vlib/v/util/diff.v b/vlib/v/util/diff.v index 55603cba56..e974f3c492 100644 --- a/vlib/v/util/diff.v +++ b/vlib/v/util/diff.v @@ -63,10 +63,10 @@ pub fn color_compare_strings(diff_cmd string, expected string, found string) str ctime := time.sys_mono_now() e_file := os.join_path(cdir, '${ctime}.expected.txt') f_file := os.join_path(cdir, '${ctime}.found.txt') - os.write_file(e_file, expected) - os.write_file(f_file, found) + os.write_file(e_file, expected) or { panic(err) } + os.write_file(f_file, found) or { panic(err) } res := color_compare_files(diff_cmd, e_file, f_file) - os.rm(e_file) - os.rm(f_file) + os.rm(e_file) or { panic(err) } + os.rm(f_file) or { panic(err) } return res } diff --git a/vlib/v/util/util.v b/vlib/v/util/util.v index 99f191c2de..4c3f2fcd19 100644 --- a/vlib/v/util/util.v +++ b/vlib/v/util/util.v @@ -489,7 +489,7 @@ pub fn get_vtmp_folder() string { } vtmp = os.join_path(os.temp_dir(), 'v') if !os.exists(vtmp) || !os.is_dir(vtmp) { - os.mkdir_all(vtmp) + os.mkdir_all(vtmp) or { panic(err) } } os.setenv('VTMP', vtmp, true) return vtmp diff --git a/vlib/v/vcache/vcache.v b/vlib/v/vcache/vcache.v index d1cc7237ee..75038fd192 100644 --- a/vlib/v/vcache/vcache.v +++ b/vlib/v/vcache/vcache.v @@ -30,8 +30,8 @@ pub: basepath string original_vopts string pub mut: - vopts string - k2cpath map[string]string // key -> filesystem cache path for the object + vopts string + k2cpath map[string]string // key -> filesystem cache path for the object } pub fn new_cache_manager(opts []string) CacheManager { @@ -40,13 +40,13 @@ pub fn new_cache_manager(opts []string) CacheManager { vcache_basepath = os.join_path(os.vmodules_dir(), 'cache') } if !os.is_dir(vcache_basepath) { - os.mkdir_all(vcache_basepath) + os.mkdir_all(vcache_basepath) or { panic(err) } readme_content := 'This folder contains cached build artifacts from the V build system. |You can safely delete it, if it is getting too large. |It will be recreated the next time you compile something with V. |You can change its location with the VCACHE environment variable. '.strip_margin() - os.write_file(os.join_path(vcache_basepath, 'README.md'), readme_content) + os.write_file(os.join_path(vcache_basepath, 'README.md'), readme_content) or { panic(err) } } original_vopts := opts.join('|') return CacheManager{ @@ -74,7 +74,7 @@ pub fn (mut cm CacheManager) key2cpath(key string) string { cprefix_folder := os.join_path(cm.basepath, prefix) cpath = os.join_path(cprefix_folder, khash) if !os.is_dir(cprefix_folder) { - os.mkdir_all(cprefix_folder) + os.mkdir_all(cprefix_folder) or { panic(err) } os.chmod(cprefix_folder, 0o777) } cm.k2cpath[key] = cpath diff --git a/vlib/v/vcache/vcache_test.v b/vlib/v/vcache/vcache_test.v index c0a202bfba..3fe8b331ed 100644 --- a/vlib/v/vcache/vcache_test.v +++ b/vlib/v/vcache/vcache_test.v @@ -17,7 +17,7 @@ fn check_cache_entry_fpath_invariants(x string, extension string) { fn testsuite_begin() { os.setenv('VCACHE', vcache_folder, true) // eprintln('testsuite_begin, vcache_folder = $vcache_folder') - os.rmdir_all(vcache_folder) + os.rmdir_all(vcache_folder) or { } vcache.new_cache_manager([]) assert os.is_dir(vcache_folder) } @@ -54,33 +54,25 @@ fn test_different_options_should_produce_different_cache_entries_for_same_key_an fn test_exists() { mut cm := vcache.new_cache_manager([]) - cm.exists('.o', 'abc') or { - assert true - } + cm.exists('.o', 'abc') or { assert true } // x := cm.save('.x', 'abc', '') or { assert false '' } - cm.exists('.o', 'abc') or { - assert true - } + cm.exists('.o', 'abc') or { assert true } // y := cm.save('.o', 'zbc', '') or { assert false '' } - cm.exists('.o', 'abc') or { - assert true - } + cm.exists('.o', 'abc') or { assert true } // z := cm.save('.o', 'abc', '') or { assert false '' } - cm.exists('.o', 'abc') or { - assert false - } + cm.exists('.o', 'abc') or { assert false } // assert os.is_file(x) assert os.is_file(y) @@ -104,6 +96,6 @@ fn test_readme_exists_and_is_readable() { fn testsuite_end() { os.chdir(os.wd_at_startup) - os.rmdir_all(vcache_folder) + os.rmdir_all(vcache_folder) or { } assert !os.is_dir(vcache_folder) } diff --git a/vlib/vweb/assets/assets.v b/vlib/vweb/assets/assets.v index 7dc8ee2f0c..1240e4123c 100644 --- a/vlib/vweb/assets/assets.v +++ b/vlib/vweb/assets/assets.v @@ -99,7 +99,7 @@ fn (am AssetManager) combine(asset_type string, to_file bool) string { os.mkdir(am.cache_dir) or { panic(err) } } mut file := os.create(out_file) or { panic(err) } - file.write(out.bytes()) + file.write(out.bytes()) or { panic(err) } file.close() return out_file } diff --git a/vlib/vweb/assets/assets_test.v b/vlib/vweb/assets/assets_test.v index 6a63d30002..6170f3ce47 100644 --- a/vlib/vweb/assets/assets_test.v +++ b/vlib/vweb/assets/assets_test.v @@ -6,7 +6,7 @@ import os // unique cache dirs are needed per test function. fn clean_cache_dir(dir string) { if os.is_dir(dir) { - os.rmdir_all(dir) + os.rmdir_all(dir) or { panic(err) } } } @@ -21,10 +21,10 @@ fn cache_dir(test_name string) string { fn get_test_file_path(file string) string { path := os.join_path(base_cache_dir(), file) if !os.is_dir(base_cache_dir()) { - os.mkdir_all(base_cache_dir()) + os.mkdir_all(base_cache_dir()) or { panic(err) } } if !os.exists(path) { - os.write_file(path, get_test_file_contents(file)) + os.write_file(path, get_test_file_contents(file)) or { panic(err) } } return path } diff --git a/vlib/vweb/tests/vweb_test.v b/vlib/vweb/tests/vweb_test.v index 4d24f68118..895b8aa784 100644 --- a/vlib/vweb/tests/vweb_test.v +++ b/vlib/vweb/tests/vweb_test.v @@ -20,7 +20,7 @@ const ( fn testsuite_begin() { os.chdir(vroot) if os.exists(serverexe) { - os.rm(serverexe) + os.rm(serverexe) or { } } } @@ -246,7 +246,7 @@ fn simple_tcp_client(config SimpleTcpClientConfig) ?string { client.set_read_timeout(tcp_r_timeout) client.set_write_timeout(tcp_w_timeout) defer { - client.close() + client.close() or { } } message := 'GET $config.path HTTP/1.1 Host: $config.host diff --git a/vlib/vweb/vweb.v b/vlib/vweb/vweb.v index d5d2af083c..f2b7560b2b 100644 --- a/vlib/vweb/vweb.v +++ b/vlib/vweb/vweb.v @@ -355,7 +355,8 @@ fn handle_conn(mut conn net.TcpConn, mut app T) { //} // read body mut read_body := []byte{len: len} - reader.read(mut read_body) // read just the amount of content len if there is no content there is nothing more to read here + // read just the amount of content len if there is no content there is nothing more to read here + reader.read(mut read_body) or { println('reader.read failed with err: $err') } body += read_body.bytestr() break } diff --git a/vlib/x/ttf/common.v b/vlib/x/ttf/common.v index 56e0d91b1e..c05731ea0b 100644 --- a/vlib/x/ttf/common.v +++ b/vlib/x/ttf/common.v @@ -1,4 +1,5 @@ module ttf + /********************************************************************** * * Common data for the module @@ -15,8 +16,7 @@ import os import math // text align -pub -enum Text_align { +pub enum Text_align { left center right @@ -24,8 +24,7 @@ enum Text_align { } // draw style -pub -enum Style { +pub enum Style { outline outline_aliased filled @@ -38,8 +37,9 @@ enum Style { * ******************************************************************************/ const debug_flag = false -fn dprintln(txt string){ - if debug_flag { + +fn dprintln(txt string) { + if ttf.debug_flag { println(txt) } } @@ -50,34 +50,34 @@ fn dprintln(txt string){ * ******************************************************************************/ // transform the bitmap from one layer to color layers -fn (mut bmp BitMap) format_texture(){ +fn (mut bmp BitMap) format_texture() { r := byte(bmp.color >> 24) g := byte((bmp.color >> 16) & 0xFF) - b := byte((bmp.color >> 8 ) & 0xFF) + b := byte((bmp.color >> 8) & 0xFF) a := byte(bmp.color & 0xFF) b_r := byte(bmp.bg_color >> 24) b_g := byte((bmp.bg_color >> 16) & 0xFF) - b_b := byte((bmp.bg_color >> 8 ) & 0xFF) + b_b := byte((bmp.bg_color >> 8) & 0xFF) b_a := byte(bmp.bg_color & 0xFF) - + // trasform buffer in a texture x := byteptr(bmp.buf) - unsafe{ + unsafe { mut i := 0 - for i 0 { - x[i+0] = r - x[i+1] = g - x[i+2] = b + if data > 0 { + x[i + 0] = r + x[i + 1] = g + x[i + 2] = b // alpha - x[i+3] = byte((a * data) >> 8) + x[i + 3] = byte((a * data) >> 8) } else { - x[i+0] = b_r - x[i+1] = b_g - x[i+2] = b_b - x[i+3] = b_a + x[i + 0] = b_r + x[i + 1] = b_g + x[i + 2] = b_b + x[i + 3] = b_a } i += 4 } @@ -85,52 +85,49 @@ fn (mut bmp BitMap) format_texture(){ } // write out a .ppm file -pub -fn (mut bmp BitMap) save_as_ppm(file_name string) { +pub fn (mut bmp BitMap) save_as_ppm(file_name string) { tmp_buf := bmp.buf mut buf := malloc(bmp.buf_size) unsafe { C.memcpy(buf, tmp_buf, bmp.buf_size) } bmp.buf = buf - + bmp.format_texture() npixels := bmp.width * bmp.height mut f_out := os.create(file_name) or { panic(err) } - f_out.writeln('P3') - f_out.writeln('${bmp.width} ${bmp.height}') - f_out.writeln('255') - for i in 0..npixels { + f_out.writeln('P3') or { panic(err) } + f_out.writeln('$bmp.width $bmp.height') or { panic(err) } + f_out.writeln('255') or { panic(err) } + for i in 0 .. npixels { pos := i * bmp.bp unsafe { c_r := bmp.buf[pos] - c_g := bmp.buf[pos +1 ] + c_g := bmp.buf[pos + 1] c_b := bmp.buf[pos + 2] - f_out.write_str('${c_r} ${c_g} ${c_b} ') + f_out.write_str('$c_r $c_g $c_b ') or { panic(err) } } - } f_out.close() - + free(buf) bmp.buf = tmp_buf } -pub -fn (mut bmp BitMap) get_raw_bytes() []byte { - mut f_buf := []byte{len: bmp.buf_size/4} - mut i:=0 +pub fn (mut bmp BitMap) get_raw_bytes() []byte { + mut f_buf := []byte{len: bmp.buf_size / 4} + mut i := 0 for i < bmp.buf_size { - unsafe { f_buf[i>>2] = *(bmp.buf + i) } + unsafe { + f_buf[i >> 2] = *(bmp.buf + i) + } i += 4 } return f_buf } -pub -fn (mut bmp BitMap) save_raw_data(file_name string) { - os.write_file_array(file_name, bmp.get_raw_bytes()) +pub fn (mut bmp BitMap) save_raw_data(file_name string) { + os.write_file_array(file_name, bmp.get_raw_bytes()) or { panic(err) } } - // // Math functions // @@ -181,8 +178,7 @@ fn rfpart(x f32) f32 { ******************************************************************************/ /* [inline] -pub -fn (mut dev BitMap) get_color(x int, y int) (int, int, int, int){ +pub fn (mut dev BitMap) get_color(x int, y int) (int, int, int, int){ if x < 0 || x >= dev.width || y < 0 || y >= dev.height { return 0,0,0,0 } @@ -193,8 +189,7 @@ fn (mut dev BitMap) get_color(x int, y int) (int, int, int, int){ } [inline] -pub -fn (mut dev BitMap) get_color_u32(x int, y int) u32{ +pub fn (mut dev BitMap) get_color_u32(x int, y int) u32{ r, g, b, a := dev.get_color(x, y) unsafe{ return u32(r<<24) | u32(g<<16) | u32(b<<8) | u32(a) @@ -207,18 +202,16 @@ fn (mut dev BitMap) get_color_u32(x int, y int) u32{ * ******************************************************************************/ [inline] -pub -fn color_multiply_alpha(c u32, level f32) u32 { - return u32(f32( c & 0xFF) * level) +pub fn color_multiply_alpha(c u32, level f32) u32 { + return u32(f32(c & 0xFF) * level) } [inline] -pub -fn color_multiply(c u32, level f32) u32 { - mut r := (f32((c >> 24) & 0xFF)/255.0) * level - mut g := (f32((c >> 16) & 0xFF)/255.0) * level - mut b := (f32((c >> 8) & 0xFF)/255.0) * level - mut a := (f32( c & 0xFF)/255.0) * level +pub fn color_multiply(c u32, level f32) u32 { + mut r := (f32((c >> 24) & 0xFF) / 255.0) * level + mut g := (f32((c >> 16) & 0xFF) / 255.0) * level + mut b := (f32((c >> 8) & 0xFF) / 255.0) * level + mut a := (f32(c & 0xFF) / 255.0) * level r = if r > 1.0 { 1.0 } else { r } g = if g > 1.0 { 1.0 } else { g } b = if b > 1.0 { 1.0 } else { b } diff --git a/vlib/x/ttf/render_bmp.v b/vlib/x/ttf/render_bmp.v index 59fb89714e..6802b59d27 100644 --- a/vlib/x/ttf/render_bmp.v +++ b/vlib/x/ttf/render_bmp.v @@ -1,4 +1,5 @@ module ttf + /********************************************************************** * * BMP render module utility functions @@ -15,42 +16,33 @@ module ttf import encoding.utf8 import math -pub -struct BitMap { +pub struct BitMap { pub mut: - tf &TTF_File - - buf byteptr // pointer to the memory buffer + tf &TTF_File + buf byteptr // pointer to the memory buffer buf_size int // allocated buf size in bytes - - width int =1 // width of the buffer - height int =1 // height of the buffer - bp int =4 // byte per pixel of the buffer - - bg_color u32 = 0xFFFFFF_00 // background RGBA format - color u32 = 0x000000_FF // RGBA format - scale f32 = 1.0 // internal usage!! - scale_x f32 = 1.0 // X scale of the single glyph - scale_y f32 = 1.0 // Y scale of the single glyph - angle f32 = 0.0 // angle of rotation of the bitmap - + width int = 1 // width of the buffer + height int = 1 // height of the buffer + bp int = 4 // byte per pixel of the buffer + bg_color u32 = 0xFFFFFF_00 // background RGBA format + color u32 = 0x000000_FF // RGBA format + scale f32 = 1.0 // internal usage!! + scale_x f32 = 1.0 // X scale of the single glyph + scale_y f32 = 1.0 // Y scale of the single glyph + angle f32 = 0.0 // angle of rotation of the bitmap // spaces - space_cw f32 = 1.0 // width of the space glyph internal usage!! - space_mult f32 = f32(0.0) //1.0/16.0 // space between letter, is a multiplier for a standrd space ax - + space_cw f32 = 1.0 // width of the space glyph internal usage!! + space_mult f32 = f32(0.0) // 1.0/16.0 // space between letter, is a multiplier for a standrd space ax // used only by internal text rendering!! - tr_matrix []f32 = [f32(1), 0, 0, 0, 1, 0, 0, 0, 0] // transformation matrix - ch_matrix []f32 = [f32(1), 0, 0, 0, 1, 0, 0, 0, 0] // character matrix - + tr_matrix []f32 = [f32(1), 0, 0, 0, 1, 0, 0, 0, 0] // transformation matrix + ch_matrix []f32 = [f32(1), 0, 0, 0, 1, 0, 0, 0, 0] // character matrix style Style = .filled // default syle - align Text_align = .left // default text align - justify bool // justify text flag, default deactivated - justify_fill_ratio f32 = 0.5 // justify fill ratio, if the ratio of the filled row is >= of this then justify the text - - filler [][]int // filler buffer for the renderer - + align Text_align = .left // default text align + justify bool // justify text flag, default deactivated + justify_fill_ratio f32 = 0.5 // justify fill ratio, if the ratio of the filled row is >= of this then justify the text + filler [][]int // filler buffer for the renderer // flag to force font embedded metrics - use_font_metrics bool + use_font_metrics bool } /****************************************************************************** @@ -59,8 +51,7 @@ pub mut: * ******************************************************************************/ // clear clear the bitmap with 0 bytes -pub -fn (mut bmp BitMap) clear() { +pub fn (mut bmp BitMap) clear() { mut sz := bmp.width * bmp.height * bmp.bp unsafe { C.memset(bmp.buf, 0x00, sz) @@ -69,30 +60,28 @@ fn (mut bmp BitMap) clear() { // transform matrix applied to the text fn (bmp &BitMap) trf_txt(p &Point) (int, int) { - return int(p.x * bmp.tr_matrix[0] + p.y * bmp.tr_matrix[3] + bmp.tr_matrix[6]), - int(p.x * bmp.tr_matrix[1] + p.y * bmp.tr_matrix[4] + bmp.tr_matrix[7]) + return int(p.x * bmp.tr_matrix[0] + p.y * bmp.tr_matrix[3] + bmp.tr_matrix[6]), int( + p.x * bmp.tr_matrix[1] + p.y * bmp.tr_matrix[4] + bmp.tr_matrix[7]) } // transform matrix applied to the char fn (bmp &BitMap) trf_ch(p &Point) (int, int) { - return int(p.x * bmp.ch_matrix[0] + p.y * bmp.ch_matrix[3] + bmp.ch_matrix[6]), - int(p.x * bmp.ch_matrix[1] + p.y * bmp.ch_matrix[4] + bmp.ch_matrix[7]) + return int(p.x * bmp.ch_matrix[0] + p.y * bmp.ch_matrix[3] + bmp.ch_matrix[6]), int( + p.x * bmp.ch_matrix[1] + p.y * bmp.ch_matrix[4] + bmp.ch_matrix[7]) } // set draw postion in the buffer -pub -fn (mut bmp BitMap) set_pos(x f32, y f32) { - bmp.tr_matrix[6] = x - bmp.tr_matrix[7] = y +pub fn (mut bmp BitMap) set_pos(x f32, y f32) { + bmp.tr_matrix[6] = x + bmp.tr_matrix[7] = y } // set the rotation angle in radiants -pub -fn (mut bmp BitMap) set_rotation(a f32) { - bmp.tr_matrix[0] = f32(math.cos(a)) //1 - bmp.tr_matrix[1] = f32(-math.sin(a)) //0 - bmp.tr_matrix[3] = f32(math.sin(a)) //0 - bmp.tr_matrix[4] = f32(math.cos(a)) //1 +pub fn (mut bmp BitMap) set_rotation(a f32) { + bmp.tr_matrix[0] = f32(math.cos(a)) // 1 + bmp.tr_matrix[1] = f32(-math.sin(a)) // 0 + bmp.tr_matrix[3] = f32(math.sin(a)) // 0 + bmp.tr_matrix[4] = f32(math.cos(a)) // 1 } /****************************************************************************** @@ -100,43 +89,40 @@ fn (mut bmp BitMap) set_rotation(a f32) { * Filler functions * ******************************************************************************/ -pub -fn (mut bmp BitMap) init_filler() { - h := bmp.height - bmp.filler.len +pub fn (mut bmp BitMap) init_filler() { + h := bmp.height - bmp.filler.len if h < 1 { return } - for _ in 0..h { - bmp.filler << []int{len:4} + for _ in 0 .. h { + bmp.filler << []int{len: 4} } // dprintln("Init filler: ${bmp.filler.len} rows") } -pub -fn (mut bmp BitMap) clear_filler() { - for i in 0..bmp.height { +pub fn (mut bmp BitMap) clear_filler() { + for i in 0 .. bmp.height { bmp.filler[i].clear() } } -pub -fn (mut bmp BitMap) exec_filler() { - for y in 0..bmp.height { +pub fn (mut bmp BitMap) exec_filler() { + for y in 0 .. bmp.height { if bmp.filler[y].len > 0 { bmp.filler[y].sort() if bmp.filler[y].len & 1 != 0 { - //dprintln("even line!! $y => ${bmp.filler[y]}") + // dprintln("even line!! $y => ${bmp.filler[y]}") continue } mut index := 0 for index < bmp.filler[y].len { startx := bmp.filler[y][index] + 1 - endx := bmp.filler[y][index+1] - if startx >= endx { + endx := bmp.filler[y][index + 1] + if startx >= endx { index += 2 - continue + continue } - for x in startx..endx { + for x in startx .. endx { bmp.plot(x, y, bmp.color) } index += 2 @@ -145,8 +131,7 @@ fn (mut bmp BitMap) exec_filler() { } } -pub -fn (mut bmp BitMap) fline(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { +pub fn (mut bmp BitMap) fline(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { mut x0 := f32(in_x0) mut x1 := f32(in_x1) mut y0 := f32(in_y0) @@ -170,7 +155,7 @@ fn (mut bmp BitMap) fline(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { mut dx := x1 - x0 mut dy := y1 - y0 - + if dy == 0 { if in_y0 >= 0 && in_y0 < bmp.filler.len { if in_x0 <= in_x1 { @@ -184,15 +169,15 @@ fn (mut bmp BitMap) fline(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { return } mut n := dx / dy - for y in 0..int(dy+0.5) { + for y in 0 .. int(dy + 0.5) { yd := int(y + y0) x := n * y + x0 - if x > bmp.width || yd >= bmp.filler.len { - break + if x > bmp.width || yd >= bmp.filler.len { + break } if yd >= 0 && yd < bmp.filler.len { - bmp.filler[yd] << int(x+0.5) - //bmp.plot(int(x+0.5), yd, bmp.color) + bmp.filler[yd] << int(x + 0.5) + // bmp.plot(int(x+0.5), yd, bmp.color) } } } @@ -203,23 +188,22 @@ fn (mut bmp BitMap) fline(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { * ******************************************************************************/ [inline] -pub -fn (mut bmp BitMap) plot(x int, y int, c u32) bool { +pub fn (mut bmp BitMap) plot(x int, y int, c u32) bool { if x < 0 || x >= bmp.width || y < 0 || y >= bmp.height { return false } mut index := (x + y * bmp.width) * bmp.bp unsafe { - //bmp.buf[index]=0xFF + // bmp.buf[index]=0xFF bmp.buf[index] = byte(c & 0xFF) // write only the alpha } -/* + /* for count in 0..(bmp.bp) { unsafe{ bmp.buf[index + count] = byte((c >> (bmp.bp - count - 1) * 8) & 0x0000_00FF) } } -*/ + */ return true } @@ -229,9 +213,8 @@ fn (mut bmp BitMap) plot(x int, y int, c u32) bool { * ******************************************************************************/ // aline draw an aliased line on the bitmap -pub -fn (mut bmp BitMap) aline(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { - //mut c1 := c +pub fn (mut bmp BitMap) aline(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { + // mut c1 := c mut x0 := f32(in_x0) mut x1 := f32(in_x1) mut y0 := f32(in_y0) @@ -263,11 +246,11 @@ fn (mut bmp BitMap) aline(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { mut x := x0 for x <= x1 + 0.5 { y := m * (x - x0) + y0 - e := 1-fabs(y-0.5-int(y)) - bmp.plot(int(x), int(y), color_multiply_alpha(c, e*0.75)) - + e := 1 - fabs(y - 0.5 - int(y)) + bmp.plot(int(x), int(y), color_multiply_alpha(c, e * 0.75)) + ys1 := y + dist - if int(ys1) != int(y){ + if int(ys1) != int(y) { v1 := fabs(ys1 - y) / dist * (1 - e) bmp.plot(int(x), int(ys1), color_multiply_alpha(c, v1)) } @@ -280,7 +263,6 @@ fn (mut bmp BitMap) aline(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { x += 1.0 } - } else { if y1 < y0 { tmp = x0 @@ -302,7 +284,7 @@ fn (mut bmp BitMap) aline(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { for y <= y1 + 0.5 { x := n * (y - y0) + x0 e := f32(1 - fabs(x - 0.5 - int(x))) - bmp.plot(int(x), int(y), color_multiply_alpha(c, f32(e*0.75))) + bmp.plot(int(x), int(y), color_multiply_alpha(c, f32(e * 0.75))) xs1 := x + dist if int(xs1) != int(x) { @@ -325,9 +307,7 @@ fn (mut bmp BitMap) aline(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { * draw functions * ******************************************************************************/ -pub -fn (mut bmp BitMap) line(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { - +pub fn (mut bmp BitMap) line(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { // outline with aliased borders if bmp.style == .outline_aliased { bmp.aline(in_x0, in_y0, in_x1, in_y1, c) @@ -350,7 +330,7 @@ fn (mut bmp BitMap) line(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { x1 := int(in_x1) y0 := int(in_y0) y1 := int(in_y1) - //dprintln("line[$x0,$y0,$x1,$y1]") + // dprintln("line[$x0,$y0,$x1,$y1]") mut x := x0 mut y := y0 @@ -359,28 +339,28 @@ fn (mut bmp BitMap) line(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { sx := if x0 < x1 { 1 } else { -1 } dy := -abs(y1 - y0) sy := if y0 < y1 { 1 } else { -1 } - + // verical line if dx == 0 { if y0 < y1 { - for yt in y0..y1+1 { + for yt in y0 .. y1 + 1 { bmp.plot(x0, yt, c) } return } - for yt in y1..y0+1 { + for yt in y1 .. y0 + 1 { bmp.plot(x0, yt, c) } + // horizontal line return - // horizontal line - } else if dy == 0{ + } else if dy == 0 { if x0 < x1 { - for xt in x0..x1+1 { + for xt in x0 .. x1 + 1 { bmp.plot(xt, y0, c) } return } - for xt in x1..x0+1 { + for xt in x1 .. x0 + 1 { bmp.plot(xt, y0, c) } return @@ -388,10 +368,10 @@ fn (mut bmp BitMap) line(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { mut err := dx + dy // error value e_xy for { - //bmp.plot(x, y, u32(0xFF00)) + // bmp.plot(x, y, u32(0xFF00)) bmp.plot(x, y, c) - - //dprintln("$x $y [$x0,$y0,$x1,$y1]") + + // dprintln("$x $y [$x0,$y0,$x1,$y1]") if x == x1 && y == y1 { break } @@ -405,20 +385,16 @@ fn (mut bmp BitMap) line(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { y += sy } } - } - -pub -fn (mut bmp BitMap) box(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { +pub fn (mut bmp BitMap) box(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { bmp.line(in_x0, in_y0, in_x1, in_y0, c) bmp.line(in_x1, in_y0, in_x1, in_y1, c) bmp.line(in_x0, in_y1, in_x1, in_y1, c) bmp.line(in_x0, in_y0, in_x0, in_y1, c) } -pub -fn (mut bmp BitMap) quadratic(in_x0 int, in_y0 int, in_x1 int, in_y1 int, in_cx int, in_cy int, c u32) { +pub fn (mut bmp BitMap) quadratic(in_x0 int, in_y0 int, in_x1 int, in_y1 int, in_cx int, in_cy int, c u32) { /* x0 := int(in_x0 * bmp.scale) x1 := int(in_x1 * bmp.scale) @@ -437,41 +413,41 @@ fn (mut bmp BitMap) quadratic(in_x0 int, in_y0 int, in_x1 int, in_y1 int, in_cx mut division := f64(1.0) dx := abs(x0 - x1) dy := abs(y0 - y1) - + // if few pixel draw a simple line - //if dx == 0 && dy == 0 { + // if dx == 0 && dy == 0 { if dx <= 2 || dy <= 2 { - //bmp.plot(x0, y0, c) - bmp.line(x0,y0,x1,y1, c) + // bmp.plot(x0, y0, c) + bmp.line(x0, y0, x1, y1, c) return } - division = 1.0/(f64( if dx>dy {dx} else {dy} )) - - //division = 0.1 // 10 division - //division = 0.25 // 4 division - - //dprintln("div: $division") - - /* + division = 1.0 / (f64(if dx > dy { dx } else { dy })) + + // division = 0.1 // 10 division + // division = 0.25 // 4 division + + // dprintln("div: $division") + + /* ----- Bezier quadratic form ----- t = 0.5; // given example value, half length of the curve x = (1 - t) * (1 - t) * p[0].x + 2 * (1 - t) * t * p[1].x + t * t * p[2].x; y = (1 - t) * (1 - t) * p[0].y + 2 * (1 - t) * t * p[1].y + t * t * p[2].y; - --------------------------------- + --------------------------------- */ mut x_old := x0 mut y_old := y0 mut t := 0.0 - - for t <= (1.0 + division/2.0){ + + for t <= (1.0 + division / 2.0) { s := 1.0 - t x := s * s * x0 + 2.0 * s * t * cx + t * t * x1 y := s * s * y0 + 2.0 * s * t * cy + t * t * y1 xi := int(x + 0.5) yi := int(y + 0.5) - //bmp.plot(xi, yi, c) + // bmp.plot(xi, yi, c) bmp.line(x_old, y_old, xi, yi, c) x_old = xi y_old = yi @@ -484,14 +460,13 @@ fn (mut bmp BitMap) quadratic(in_x0 int, in_y0 int, in_x1 int, in_y1 int, in_cx * TTF Query functions * ******************************************************************************/ -pub -fn (mut bmp BitMap) get_chars_bbox(in_string string) []int { +pub fn (mut bmp BitMap) get_chars_bbox(in_string string) []int { mut res := []int{} mut w := 0 mut space_cw, _ := bmp.tf.get_horizontal_metrics(u16(` `)) - div_space_cw := int((f32(space_cw) * bmp.space_mult) * bmp.scale) - space_cw = int(space_cw * bmp.scale) + div_space_cw := int((f32(space_cw) * bmp.space_mult) * bmp.scale) + space_cw = int(space_cw * bmp.scale) bmp.tf.reset_kern() @@ -505,15 +480,14 @@ fn (mut bmp BitMap) get_chars_bbox(in_string string) []int { i++ continue } - // manage unicode chars like latin greek etc - c_len := ((0xe5000000>>((char>>3) & 0x1e)) & 3) + 1 + c_len := ((0xe5000000 >> ((char >> 3) & 0x1e)) & 3) + 1 if c_len > 1 { - tmp_char := utf8.get_uchar(in_string,i) - //dprintln("tmp_char: ${tmp_char.hex()}") + tmp_char := utf8.get_uchar(in_string, i) + // dprintln("tmp_char: ${tmp_char.hex()}") char = u16(tmp_char) } - + c_index := bmp.tf.map_code(int(char)) // Glyph not found if c_index == 0 { @@ -522,18 +496,18 @@ fn (mut bmp BitMap) get_chars_bbox(in_string string) []int { continue } - ax , ay := bmp.tf.next_kern(c_index) - //dprintln("char_index: $c_index ax: $ax ay: $ay") + ax, ay := bmp.tf.next_kern(c_index) + // dprintln("char_index: $c_index ax: $ax ay: $ay") + + // cw, lsb := bmp.tf.get_horizontal_metrics(u16(char)) + // dprintln("metrics: [${u16(char):c}] cw:$cw lsb:$lsb") - //cw, lsb := bmp.tf.get_horizontal_metrics(u16(char)) - //dprintln("metrics: [${u16(char):c}] cw:$cw lsb:$lsb") - //----- Calc Glyph transformations ----- mut x0 := w + int(ax * bmp.scale) mut y0 := 0 + int(ay * bmp.scale) - - p := Point{x0,y0,false} - x1 , y1 := bmp.trf_txt(p) + + p := Point{x0, y0, false} + x1, y1 := bmp.trf_txt(p) // init ch_matrix bmp.ch_matrix[0] = bmp.tr_matrix[0] * bmp.scale * bmp.scale_x bmp.ch_matrix[1] = bmp.tr_matrix[1] * bmp.scale * bmp.scale_x @@ -542,29 +516,28 @@ fn (mut bmp BitMap) get_chars_bbox(in_string string) []int { bmp.ch_matrix[6] = int(x1) bmp.ch_matrix[7] = int(y1) - //x_min, x_max, y_min, y_max := bmp.tf.read_glyph_dim(c_index) + // x_min, x_max, y_min, y_max := bmp.tf.read_glyph_dim(c_index) x_min, x_max, _, _ := bmp.tf.read_glyph_dim(c_index) //----------------- - width := int( (abs(x_max + x_min) + ax) * bmp.scale) - //width := int((cw+ax) * bmp.scale) + width := int((abs(x_max + x_min) + ax) * bmp.scale) + // width := int((cw+ax) * bmp.scale) w += width + div_space_cw h := int(abs(int(bmp.tf.y_max - bmp.tf.y_min)) * bmp.scale) res << w res << h - i+= c_len + i += c_len } return res } -pub -fn (mut bmp BitMap) get_bbox(in_string string) (int, int){ +pub fn (mut bmp BitMap) get_bbox(in_string string) (int, int) { mut w := 0 mut space_cw, _ := bmp.tf.get_horizontal_metrics(u16(` `)) - div_space_cw := int((f32(space_cw) * bmp.space_mult) * bmp.scale) - space_cw = int(space_cw * bmp.scale) + div_space_cw := int((f32(space_cw) * bmp.space_mult) * bmp.scale) + space_cw = int(space_cw * bmp.scale) bmp.tf.reset_kern() @@ -578,15 +551,14 @@ fn (mut bmp BitMap) get_bbox(in_string string) (int, int){ i++ continue } - // manage unicode chars like latin greek etc - c_len := ((0xe5000000>>((char>>3) & 0x1e)) & 3) + 1 + c_len := ((0xe5000000 >> ((char >> 3) & 0x1e)) & 3) + 1 if c_len > 1 { - tmp_char := utf8.get_uchar(in_string,i) - //dprintln("tmp_char: ${tmp_char.hex()}") + tmp_char := utf8.get_uchar(in_string, i) + // dprintln("tmp_char: ${tmp_char.hex()}") char = u16(tmp_char) } - + c_index := bmp.tf.map_code(int(char)) // Glyph not found if c_index == 0 { @@ -594,18 +566,18 @@ fn (mut bmp BitMap) get_bbox(in_string string) (int, int){ i += c_len continue } - ax , ay := bmp.tf.next_kern(c_index) - //dprintln("char_index: $c_index ax: $ax ay: $ay") + ax, ay := bmp.tf.next_kern(c_index) + // dprintln("char_index: $c_index ax: $ax ay: $ay") + + // cw, lsb := bmp.tf.get_horizontal_metrics(u16(char)) + // dprintln("metrics: [${u16(char):c}] cw:$cw lsb:$lsb") - //cw, lsb := bmp.tf.get_horizontal_metrics(u16(char)) - //dprintln("metrics: [${u16(char):c}] cw:$cw lsb:$lsb") - //----- Calc Glyph transformations ----- mut x0 := w + int(ax * bmp.scale) mut y0 := 0 + int(ay * bmp.scale) - - p := Point{x0,y0,false} - x1 , y1 := bmp.trf_txt(p) + + p := Point{x0, y0, false} + x1, y1 := bmp.trf_txt(p) // init ch_matrix bmp.ch_matrix[0] = bmp.tr_matrix[0] * bmp.scale * bmp.scale_x bmp.ch_matrix[1] = bmp.tr_matrix[1] * bmp.scale * bmp.scale_x @@ -615,20 +587,20 @@ fn (mut bmp BitMap) get_bbox(in_string string) (int, int){ bmp.ch_matrix[7] = int(y1) x_min, x_max, _, _ := bmp.tf.read_glyph_dim(c_index) - //x_min := 1 - //x_max := 2 + // x_min := 1 + // x_max := 2 //----------------- - width := int( (abs(x_max + x_min) + ax) * bmp.scale) - //width := int((cw+ax) * bmp.scale) + width := int((abs(x_max + x_min) + ax) * bmp.scale) + // width := int((cw+ax) * bmp.scale) w += width + div_space_cw - i+= c_len + i += c_len } - //dprintln("y_min: $bmp.tf.y_min y_max: $bmp.tf.y_max res: ${int((bmp.tf.y_max - bmp.tf.y_min)*buf.scale)} width: ${int( (cw) * buf.scale)}") - //buf.box(0,y_base - int((bmp.tf.y_min)*buf.scale), int( (x_max) * buf.scale), y_base-int((bmp.tf.y_max)*buf.scale), u32(0xFF00_0000) ) - return w , int(abs(int(bmp.tf.y_max - bmp.tf.y_min)) * bmp.scale) + // dprintln("y_min: $bmp.tf.y_min y_max: $bmp.tf.y_max res: ${int((bmp.tf.y_max - bmp.tf.y_min)*buf.scale)} width: ${int( (cw) * buf.scale)}") + // buf.box(0,y_base - int((bmp.tf.y_min)*buf.scale), int( (x_max) * buf.scale), y_base-int((bmp.tf.y_max)*buf.scale), u32(0xFF00_0000) ) + return w, int(abs(int(bmp.tf.y_max - bmp.tf.y_min)) * bmp.scale) } /****************************************************************************** @@ -638,7 +610,7 @@ fn (mut bmp BitMap) get_bbox(in_string string) (int, int){ ******************************************************************************/ fn (mut bmp BitMap) draw_notdef_glyph(in_x int, in_w int) { mut p := Point{in_x, 0, false} - x1 , y1 := bmp.trf_txt(p) + x1, y1 := bmp.trf_txt(p) // init ch_matrix bmp.ch_matrix[0] = bmp.tr_matrix[0] * bmp.scale * bmp.scale_x bmp.ch_matrix[1] = bmp.tr_matrix[1] * bmp.scale * bmp.scale_x @@ -646,22 +618,21 @@ fn (mut bmp BitMap) draw_notdef_glyph(in_x int, in_w int) { bmp.ch_matrix[4] = bmp.tr_matrix[4] * -bmp.scale * bmp.scale_y bmp.ch_matrix[6] = int(x1) bmp.ch_matrix[7] = int(y1) - x,y := bmp.trf_ch(p) - - y_h := fabs(bmp.tf.y_max-bmp.tf.y_min)* bmp.scale * 0.5 + x, y := bmp.trf_ch(p) + + y_h := fabs(bmp.tf.y_max - bmp.tf.y_min) * bmp.scale * 0.5 bmp.box(int(x), int(y), int(x - in_w), int(y - y_h), bmp.color) - bmp.line(int(x), int(y), int(x - in_w ), int(y - y_h), bmp.color) - bmp.line(int(x - in_w ), int(y), int(x), int(y - y_h), bmp.color) + bmp.line(int(x), int(y), int(x - in_w), int(y - y_h), bmp.color) + bmp.line(int(x - in_w), int(y), int(x), int(y - y_h), bmp.color) } -pub -fn (mut bmp BitMap) draw_text(in_string string) (int, int){ +pub fn (mut bmp BitMap) draw_text(in_string string) (int, int) { mut w := 0 mut space_cw, _ := bmp.tf.get_horizontal_metrics(u16(` `)) - div_space_cw := int((f32(space_cw) * bmp.space_mult) * bmp.scale) - space_cw = int(space_cw * bmp.scale) + div_space_cw := int((f32(space_cw) * bmp.space_mult) * bmp.scale) + space_cw = int(space_cw * bmp.scale) bmp.tf.reset_kern() @@ -675,15 +646,14 @@ fn (mut bmp BitMap) draw_text(in_string string) (int, int){ i++ continue } - // manage unicode chars like latin greek etc - c_len := ((0xe5000000>>((char>>3) & 0x1e)) & 3) + 1 + c_len := ((0xe5000000 >> ((char >> 3) & 0x1e)) & 3) + 1 if c_len > 1 { - tmp_char := utf8.get_uchar(in_string,i) - //dprintln("tmp_char: ${tmp_char.hex()}") + tmp_char := utf8.get_uchar(in_string, i) + // dprintln("tmp_char: ${tmp_char.hex()}") char = u16(tmp_char) } - + c_index := bmp.tf.map_code(int(char)) // Glyph not found if c_index == 0 { @@ -693,19 +663,19 @@ fn (mut bmp BitMap) draw_text(in_string string) (int, int){ continue } - ax , ay := bmp.tf.next_kern(c_index) - //dprintln("char_index: $c_index ax: $ax ay: $ay") + ax, ay := bmp.tf.next_kern(c_index) + // dprintln("char_index: $c_index ax: $ax ay: $ay") cw, _ := bmp.tf.get_horizontal_metrics(u16(char)) - //cw, lsb := bmp.tf.get_horizontal_metrics(u16(char)) - //dprintln("metrics: [${u16(char):c}] cw:$cw lsb:$lsb") + // cw, lsb := bmp.tf.get_horizontal_metrics(u16(char)) + // dprintln("metrics: [${u16(char):c}] cw:$cw lsb:$lsb") //----- Draw_Glyph transformations ----- mut x0 := w + int(ax * bmp.scale) mut y0 := 0 + int(ay * bmp.scale) - p := Point{x0,y0,false} - x1 , y1 := bmp.trf_txt(p) + p := Point{x0, y0, false} + x1, y1 := bmp.trf_txt(p) // init ch_matrix bmp.ch_matrix[0] = bmp.tr_matrix[0] * bmp.scale * bmp.scale_x bmp.ch_matrix[1] = bmp.tr_matrix[1] * bmp.scale * bmp.scale_x @@ -719,23 +689,22 @@ fn (mut bmp BitMap) draw_text(in_string string) (int, int){ // x_max := 2 //----------------- - mut width := int( (abs(x_max + x_min) + ax) * bmp.scale) + mut width := int((abs(x_max + x_min) + ax) * bmp.scale) if bmp.use_font_metrics { - width = int((cw+ax) * bmp.scale) + width = int((cw + ax) * bmp.scale) } w += width + div_space_cw - i+= c_len + i += c_len } - //dprintln("y_min: $bmp.tf.y_min y_max: $bmp.tf.y_max res: ${int((bmp.tf.y_max - bmp.tf.y_min)*buf.scale)} width: ${int( (cw) * buf.scale)}") - //buf.box(0,y_base - int((bmp.tf.y_min)*buf.scale), int( (x_max) * buf.scale), y_base-int((bmp.tf.y_max)*buf.scale), u32(0xFF00_0000) ) - return w , int(abs(int(bmp.tf.y_max - bmp.tf.y_min)) * bmp.scale) + // dprintln("y_min: $bmp.tf.y_min y_max: $bmp.tf.y_max res: ${int((bmp.tf.y_max - bmp.tf.y_min)*buf.scale)} width: ${int( (cw) * buf.scale)}") + // buf.box(0,y_base - int((bmp.tf.y_min)*buf.scale), int( (x_max) * buf.scale), y_base-int((bmp.tf.y_max)*buf.scale), u32(0xFF00_0000) ) + return w, int(abs(int(bmp.tf.y_max - bmp.tf.y_min)) * bmp.scale) } -pub -fn (mut bmp BitMap) draw_glyph(index u16) (int, int){ +pub fn (mut bmp BitMap) draw_glyph(index u16) (int, int) { glyph := bmp.tf.read_glyph(index) - + if !glyph.valid_glyph { return 0, 0 } @@ -744,27 +713,27 @@ fn (mut bmp BitMap) draw_glyph(index u16) (int, int){ bmp.clear_filler() } - mut s := 0 // status - mut c := 0 // contours count + mut s := 0 // status + mut c := 0 // contours count mut contour_start := 0 - mut x0 := 0 - mut y0 := 0 - color := bmp.color //u32(0xFFFF_FF00) // RGBA white - //color1 := u32(0xFF00_0000) // RGBA red - //color2 := u32(0x00FF_0000) // RGBA green + mut x0 := 0 + mut y0 := 0 + color := bmp.color // u32(0xFFFF_FF00) // RGBA white + // color1 := u32(0xFF00_0000) // RGBA red + // color2 := u32(0x00FF_0000) // RGBA green mut sp_x := 0 mut sp_y := 0 mut point := Point{} for count, point_raw in glyph.points { - //dprintln("count: $count, state: $s pl:$glyph.points.len") + // dprintln("count: $count, state: $s pl:$glyph.points.len") point.x = point_raw.x point.y = point_raw.y - - point.x , point.y = bmp.trf_ch(point) + + point.x, point.y = bmp.trf_ch(point) point.on_curve = point_raw.on_curve - + if s == 0 { x0 = point.x y0 = point.y @@ -775,69 +744,67 @@ fn (mut bmp BitMap) draw_glyph(index u16) (int, int){ } else if s == 1 { if point.on_curve { bmp.line(x0, y0, point.x, point.y, color) - //bmp.aline(x0, y0, point.x, point.y, u32(0xFFFF0000)) + // bmp.aline(x0, y0, point.x, point.y, u32(0xFFFF0000)) x0 = point.x y0 = point.y } else { s = 2 } - } else { - //dprintln("s==2") + // dprintln("s==2") mut prev := glyph.points[count - 1] prev.x, prev.y = bmp.trf_ch(prev) if point.on_curve { - //dprintln("HERE1") + // dprintln("HERE1") // ctx.quadraticCurveTo(prev.x + x, prev.y + y,point.x + x, point.y + y); - //bmp.line(x0, y0, point.x + in_x, point.y + in_y, color1) - //bmp.quadratic(x0, y0, point.x + in_x, point.y + in_y, prev.x + in_x, prev.y + in_y, u32(0xa0a00000)) + // bmp.line(x0, y0, point.x + in_x, point.y + in_y, color1) + // bmp.quadratic(x0, y0, point.x + in_x, point.y + in_y, prev.x + in_x, prev.y + in_y, u32(0xa0a00000)) bmp.quadratic(x0, y0, point.x, point.y, prev.x, prev.y, color) x0 = point.x y0 = point.y s = 1 } else { - //dprintln("HERE2") + // dprintln("HERE2") // ctx.quadraticCurveTo(prev.x + x, prev.y + y, // (prev.x + point.x) / 2 + x, // (prev.y + point.y) / 2 + y); - //bmp.line(x0, y0, (prev.x + point.x)/2, (prev.y + point.y)/2, color2) - //bmp.quadratic(x0, y0, (prev.x + point.x)/2, (prev.y + point.y)/2, prev.x, prev.y, color2) - bmp.quadratic(x0, y0, (prev.x + point.x)/2, (prev.y + point.y)/2, prev.x, prev.y, color) - x0 = (prev.x + point.x)/2 - y0 = (prev.y + point.y)/2 + // bmp.line(x0, y0, (prev.x + point.x)/2, (prev.y + point.y)/2, color2) + // bmp.quadratic(x0, y0, (prev.x + point.x)/2, (prev.y + point.y)/2, prev.x, prev.y, color2) + bmp.quadratic(x0, y0, (prev.x + point.x) / 2, (prev.y + point.y) / 2, + prev.x, prev.y, color) + x0 = (prev.x + point.x) / 2 + y0 = (prev.y + point.y) / 2 } } - + if count == glyph.contour_ends[c] { - //dprintln("count == glyph.contour_ends[count]") + // dprintln("count == glyph.contour_ends[count]") if s == 2 { // final point was off-curve. connect to start - + mut start_point := glyph.points[contour_start] start_point.x, start_point.y = bmp.trf_ch(start_point) if point.on_curve { - //ctx.quadraticCurveTo(prev.x + x, prev.y + y, - //point.x + x, point.y + y); - //bmp.line(x0, y0, start_point.x + in_x, start_point.y + in_y, u32(0x00FF0000)) - - bmp.quadratic(x0, y0, start_point.x, start_point.y , + // ctx.quadraticCurveTo(prev.x + x, prev.y + y, + // point.x + x, point.y + y); + // bmp.line(x0, y0, start_point.x + in_x, start_point.y + in_y, u32(0x00FF0000)) + // start_point.x + in_x, start_point.y + in_y, u32(0xFF00FF00)) - start_point.x, start_point.y, color) + bmp.quadratic(x0, y0, start_point.x, start_point.y, start_point.x, + start_point.y, color) } else { - //ctx.quadraticCurveTo(prev.x + x, prev.y + y, + // ctx.quadraticCurveTo(prev.x + x, prev.y + y, // (prev.x + point.x) / 2 + x, // (prev.y + point.y) / 2 + y); - //bmp.line(x0, y0, start_point.x, start_point.y, u32(0x00FF0000) - bmp.quadratic(x0, y0, start_point.x, start_point.y, - (point.x + start_point.x)/2, - (point.y + start_point.y)/2, - //u32(0xFF000000)) - color) + // bmp.line(x0, y0, start_point.x, start_point.y, u32(0x00FF0000) + // u32(0xFF000000)) + bmp.quadratic(x0, y0, start_point.x, start_point.y, (point.x + + start_point.x) / 2, (point.y + start_point.y) / 2, color) } } else { // last point not in a curve - //bmp.line(point.x, point.y, sp_x, sp_y, u32(0x00FF0000)) + // bmp.line(point.x, point.y, sp_x, sp_y, u32(0x00FF0000)) bmp.line(point.x, point.y, sp_x, sp_y, color) } contour_start = count + 1 @@ -852,6 +819,6 @@ fn (mut bmp BitMap) draw_glyph(index u16) (int, int){ x_min := glyph.x_min x_max := glyph.x_max return x_min, x_max - - //return glyph.x_min, glyph.x_max + + // return glyph.x_min, glyph.x_max } diff --git a/vlib/x/ttf/render_sokol_cpu.v b/vlib/x/ttf/render_sokol_cpu.v index d646fa97a6..321385c42d 100644 --- a/vlib/x/ttf/render_sokol_cpu.v +++ b/vlib/x/ttf/render_sokol_cpu.v @@ -1,4 +1,5 @@ module ttf + /********************************************************************** * * BMP render module utility functions @@ -15,15 +16,13 @@ import math import gg import sokol.sgl -pub -struct TTF_render_Sokol { +pub struct TTF_render_Sokol { pub mut: bmp &BitMap // Base bitmap render - // rendering fields - sg_img C.sg_image // sokol image - scale_reduct f32 = 2.0 // scale of the cpu texture for filtering - device_dpi int = 72 // device DPI + sg_img C.sg_image // sokol image + scale_reduct f32 = 2.0 // scale of the cpu texture for filtering + device_dpi int = 72 // device DPI } /****************************************************************************** @@ -31,93 +30,91 @@ pub mut: * Render functions * ******************************************************************************/ -fn (mut tf_skl TTF_render_Sokol) format_texture(){ +fn (mut tf_skl TTF_render_Sokol) format_texture() { tf_skl.bmp.format_texture() } -pub -fn (mut tf_skl TTF_render_Sokol) create_text(in_txt string, in_font_size f32){ +pub fn (mut tf_skl TTF_render_Sokol) create_text(in_txt string, in_font_size f32) { scale_reduct := tf_skl.scale_reduct device_dpi := tf_skl.device_dpi font_size := in_font_size //* scale_reduct - + // Formula: (font_size * device dpi) / (72dpi * em_unit) - //scale := ((1.0 * devide_dpi )/ f32(72 * tf_skl.bmp.tf.units_per_em))* font_size + // scale := ((1.0 * devide_dpi )/ f32(72 * tf_skl.bmp.tf.units_per_em))* font_size scale := f32(font_size * device_dpi) / f32(72 * tf_skl.bmp.tf.units_per_em) - //dprintln("Scale: $scale") - - tf_skl.bmp.scale = scale * scale_reduct + // dprintln("Scale: $scale") + + tf_skl.bmp.scale = scale * scale_reduct w, h := tf_skl.bmp.get_bbox(in_txt) - tf_skl.bmp.width = int(w) - tf_skl.bmp.height = int((h+8)) + tf_skl.bmp.width = int(w) + tf_skl.bmp.height = int((h + 8)) sz := tf_skl.bmp.width * tf_skl.bmp.height * tf_skl.bmp.bp - + // RAM buffer if sz > tf_skl.bmp.buf_size { if sz > 0 { free(tf_skl.bmp.buf) } - dprintln("create_text Alloc: $sz bytes") + dprintln('create_text Alloc: $sz bytes') tf_skl.bmp.buf = malloc(sz) tf_skl.bmp.buf_size = sz } tf_skl.bmp.init_filler() - + // draw the text mut y_base := int((tf_skl.bmp.tf.y_max - tf_skl.bmp.tf.y_min) * tf_skl.bmp.scale) - tf_skl.bmp.set_pos(0,y_base) + tf_skl.bmp.set_pos(0, y_base) tf_skl.bmp.clear() tf_skl.bmp.draw_text(in_txt) tf_skl.format_texture() } -pub -fn (mut tf_skl TTF_render_Sokol) create_text_block(in_txt string, in_w int, in_h int, in_font_size f32){ +pub fn (mut tf_skl TTF_render_Sokol) create_text_block(in_txt string, in_w int, in_h int, in_font_size f32) { scale_reduct := tf_skl.scale_reduct device_dpi := tf_skl.device_dpi font_size := in_font_size //* scale_reduct // Formula: (font_size * device dpi) / (72dpi * em_unit) - //scale := ((1.0 * devide_dpi )/ f32(72 * tf_skl.bmp.tf.units_per_em))* font_size + // scale := ((1.0 * devide_dpi )/ f32(72 * tf_skl.bmp.tf.units_per_em))* font_size scale := f32(font_size * device_dpi) / f32(72 * tf_skl.bmp.tf.units_per_em) - //dprintln("Scale: $scale") - - tf_skl.bmp.scale = scale * scale_reduct + // dprintln("Scale: $scale") + + tf_skl.bmp.scale = scale * scale_reduct w := in_w h := in_h - tf_skl.bmp.width = int(w * scale_reduct + 0.5) - tf_skl.bmp.height = int((h+2) * scale_reduct + 0.5) + tf_skl.bmp.width = int(w * scale_reduct + 0.5) + tf_skl.bmp.height = int((h + 2) * scale_reduct + 0.5) sz := tf_skl.bmp.width * tf_skl.bmp.height * tf_skl.bmp.bp - - //if true { return } - + + // if true { return } + // RAM buffer if sz > tf_skl.bmp.buf_size { if sz > 0 { free(tf_skl.bmp.buf) } - dprintln("Alloc: $sz bytes") + dprintln('Alloc: $sz bytes') tf_skl.bmp.buf = malloc(sz) tf_skl.bmp.buf_size = sz } tf_skl.bmp.init_filler() - + // draw the text mut y_base := int((tf_skl.bmp.tf.y_max - tf_skl.bmp.tf.y_min) * tf_skl.bmp.scale) - tf_skl.bmp.set_pos(0,y_base) + tf_skl.bmp.set_pos(0, y_base) tf_skl.bmp.clear() - - tf_skl.bmp.draw_text_block(in_txt, {x: 0, y:0, w:w, h:h}) + + tf_skl.bmp.draw_text_block(in_txt, x: 0, y: 0, w: w, h: h) tf_skl.format_texture() } + /****************************************************************************** * * Sokol Render functions * ******************************************************************************/ -pub -fn (mut tf_skl TTF_render_Sokol) create_texture(){ +pub fn (mut tf_skl TTF_render_Sokol) create_texture() { w := tf_skl.bmp.width h := tf_skl.bmp.height sz := tf_skl.bmp.width * tf_skl.bmp.height * tf_skl.bmp.bp @@ -125,9 +122,9 @@ fn (mut tf_skl TTF_render_Sokol) create_texture(){ width: w height: h num_mipmaps: 0 - min_filter: .linear - mag_filter: .linear - //usage: .dynamic + min_filter: .linear + mag_filter: .linear + // usage: .dynamic wrap_u: .clamp_to_edge wrap_v: .clamp_to_edge label: &byte(0) @@ -138,38 +135,35 @@ fn (mut tf_skl TTF_render_Sokol) create_texture(){ ptr: tf_skl.bmp.buf size: sz } - + simg := C.sg_make_image(&img_desc) - //free(tf_skl.bmp.buf) // DONT FREE IF Dynamic + // free(tf_skl.bmp.buf) // DONT FREE IF Dynamic tf_skl.sg_img = simg } -pub -fn (tf_skl TTF_render_Sokol) destroy_texture(){ +pub fn (tf_skl TTF_render_Sokol) destroy_texture() { C.sg_destroy_image(tf_skl.sg_img) } // Use only if usage: .dynamic -pub -fn (mut tf_skl TTF_render_Sokol) update_text_texture(){ +pub fn (mut tf_skl TTF_render_Sokol) update_text_texture() { sz := tf_skl.bmp.width * tf_skl.bmp.height * tf_skl.bmp.bp mut tmp_sbc := C.sg_image_content{} - tmp_sbc.subimage[0][0] = C.sg_subimage_content { + tmp_sbc.subimage[0][0] = C.sg_subimage_content{ ptr: tf_skl.bmp.buf size: sz } C.sg_update_image(tf_skl.sg_img, &tmp_sbc) } -pub -fn (tf_skl TTF_render_Sokol) draw_text_bmp(ctx &gg.Context, x f32, y f32) { - //width := tf_skl.bmp.width >> 1 - //height := tf_skl.bmp.height >> 1 +pub fn (tf_skl TTF_render_Sokol) draw_text_bmp(ctx &gg.Context, x f32, y f32) { + // width := tf_skl.bmp.width >> 1 + // height := tf_skl.bmp.height >> 1 sgl.push_matrix() - - width := tf_skl.bmp.width / (tf_skl.scale_reduct) + + width := tf_skl.bmp.width / (tf_skl.scale_reduct) height := tf_skl.bmp.height / (tf_skl.scale_reduct) - + u0 := f32(0.0) v0 := f32(0.0) u1 := f32(1.0) @@ -182,10 +176,22 @@ fn (tf_skl TTF_render_Sokol) draw_text_bmp(ctx &gg.Context, x f32, y f32) { ca := f32(math.cos(tf_skl.bmp.angle)) sa := f32(math.sin(tf_skl.bmp.angle)) m := [ - f32(ca),-sa,0,0, - sa,ca,0,0, - 0,0,1,0, - x,y,0,1 + f32(ca), + -sa, + 0, + 0, + sa, + ca, + 0, + 0, + 0, + 0, + 1, + 0, + x, + y, + 0, + 1, ] sgl.mult_matrix(m) // diff --git a/vlib/x/ttf/text_block.v b/vlib/x/ttf/text_block.v index 909afb8395..dce46ff62d 100644 --- a/vlib/x/ttf/text_block.v +++ b/vlib/x/ttf/text_block.v @@ -1,4 +1,5 @@ module ttf + /********************************************************************** * * BMP render module utility functions @@ -11,40 +12,38 @@ module ttf * * TODO: **********************************************************************/ -pub -struct Text_block { - x int // x postion of the left high corner - y int // y postion of the left high corner - w int // width of the text block - h int // heigth of the text block - cut_lines bool = true // force to cut the line if the length is over the text block width +pub struct Text_block { + x int // x postion of the left high corner + y int // y postion of the left high corner + w int // width of the text block + h int // heigth of the text block + cut_lines bool = true // force to cut the line if the length is over the text block width } fn (mut dev BitMap) get_justify_space_cw(txt string, w int, block_w int, space_cw int) f32 { - num_spaces := txt.count(" ") + num_spaces := txt.count(' ') if num_spaces < 1 { return 0 } delta := block_w - w - //println("num spc: $num_spaces") - //println("delta: ${txt} w:$w bw:$block_w space_cw:$space_cw") - res := f32(delta)/f32(num_spaces)/f32(space_cw) - //println("res: $res") + // println("num spc: $num_spaces") + // println("delta: ${txt} w:$w bw:$block_w space_cw:$space_cw") + res := f32(delta) / f32(num_spaces) / f32(space_cw) + // println("res: $res") return res } // write out a text -pub -fn (mut bmp BitMap) draw_text_block(text string, block Text_block) { +pub fn (mut bmp BitMap) draw_text_block(text string, block Text_block) { mut x := block.x mut y := block.y mut y_base := int((bmp.tf.y_max - bmp.tf.y_min) * bmp.scale) - //bmp.box(x, y, x + block.w, y + block.h, u32(0xFF00_0000)) + // bmp.box(x, y, x + block.w, y + block.h, u32(0xFF00_0000)) // spaces data mut space_cw, _ := bmp.tf.get_horizontal_metrics(u16(` `)) - space_cw = int(space_cw * bmp.scale) + space_cw = int(space_cw * bmp.scale) old_space_cw := bmp.space_cw @@ -57,40 +56,40 @@ fn (mut bmp BitMap) draw_text_block(text string, block Text_block) { for txt in text.split_into_lines() { bmp.space_cw = old_space_cw - mut w,mut h := bmp.get_bbox(txt) + mut w, mut h := bmp.get_bbox(txt) if w <= block.w || block.cut_lines == false { - //println("Solid block!") + // println("Solid block!") left_offset := int((block.w - w) * offset_flag) - if bmp.justify && (f32(w) / f32(block.w)) >= bmp.justify_fill_ratio { + if bmp.justify && (f32(w) / f32(block.w)) >= bmp.justify_fill_ratio { bmp.space_cw = old_space_cw + bmp.get_justify_space_cw(txt, w, block.w, space_cw) } - bmp.set_pos(x + left_offset ,y + y_base) + bmp.set_pos(x + left_offset, y + y_base) bmp.draw_text(txt) //---- DEBUG ---- - //mut txt_w , mut txt_h := bmp.draw_text(txt) - //bmp.box(x + left_offset,y+y_base - int((bmp.tf.y_min)*bmp.scale), x + txt_w + left_offset, y + y_base - int((bmp.tf.y_max) * bmp.scale), u32(0x00ff_0000) ) + // mut txt_w , mut txt_h := bmp.draw_text(txt) + // bmp.box(x + left_offset,y+y_base - int((bmp.tf.y_min)*bmp.scale), x + txt_w + left_offset, y + y_base - int((bmp.tf.y_max) * bmp.scale), u32(0x00ff_0000) ) //--------------- y += y_base } else { - //println("to cut: ${txt}") - mut txt1 := txt.split(" ") - mut c:= txt1.len - //mut done := false + // println("to cut: ${txt}") + mut txt1 := txt.split(' ') + mut c := txt1.len + // mut done := false for c > 0 { tmp_str := txt1[0..c].join(' ') - //println("tmp_str: ${tmp_str}") + // println("tmp_str: ${tmp_str}") if tmp_str.len < 1 { break } - + bmp.space_cw = old_space_cw - w,h = bmp.get_bbox(tmp_str) + w, h = bmp.get_bbox(tmp_str) if w <= block.w { mut left_offset := int((block.w - w) * offset_flag) - if bmp.justify && (f32(w) / f32(block.w)) >= bmp.justify_fill_ratio { - //println("cut phase!") + if bmp.justify && (f32(w) / f32(block.w)) >= bmp.justify_fill_ratio { + // println("cut phase!") bmp.space_cw = 0.0 - w,h = bmp.get_bbox(tmp_str) + w, h = bmp.get_bbox(tmp_str) left_offset = int((block.w - w) * offset_flag) bmp.space_cw = bmp.get_justify_space_cw(tmp_str, w, block.w, space_cw) } else { @@ -99,16 +98,16 @@ fn (mut bmp BitMap) draw_text_block(text string, block Text_block) { bmp.set_pos(x + left_offset, y + y_base) bmp.draw_text(tmp_str) //---- DEBUG ---- - //txt_w , txt_h := bmp.draw_text(tmp_str) - //println("printing [${x},${y}] => '${tmp_str}' space_cw: $bmp.space_cw") - //bmp.box(x + left_offset,y + y_base - int((bmp.tf.y_min)*bmp.scale), x + txt_w + left_offset, y + y_base - int((bmp.tf.y_max) * bmp.scale), u32(0x00ff_0000) ) + // txt_w , txt_h := bmp.draw_text(tmp_str) + // println("printing [${x},${y}] => '${tmp_str}' space_cw: $bmp.space_cw") + // bmp.box(x + left_offset,y + y_base - int((bmp.tf.y_min)*bmp.scale), x + txt_w + left_offset, y + y_base - int((bmp.tf.y_max) * bmp.scale), u32(0x00ff_0000) ) //--------------- y += y_base txt1 = txt1[c..] - c= txt1.len + c = txt1.len //---- DEBUG ---- - //txt2 := txt1.join(' ') - //println("new string: ${txt2} len: ${c}") + // txt2 := txt1.join(' ') + // println("new string: ${txt2} len: ${c}") //--------------- } else { c-- diff --git a/vlib/x/ttf/ttf.v b/vlib/x/ttf/ttf.v index f63b0b750a..5aa0540c93 100644 --- a/vlib/x/ttf/ttf.v +++ b/vlib/x/ttf/ttf.v @@ -1,4 +1,5 @@ module ttf + /********************************************************************** * * TrueTypeFont reader V implementation @@ -16,7 +17,6 @@ module ttf **********************************************************************/ import strings - /****************************************************************************** * * CMAP structs @@ -33,7 +33,7 @@ mut: struct TrueTypeCmap { mut: format int - cache []int = []int{ len: 65536, init: -1 } // for now we allocate 2^16 charcode + cache []int = []int{len: 65536, init: -1} // for now we allocate 2^16 charcode segments []Segment arr []int } @@ -43,86 +43,74 @@ mut: * TTF_File structs * ******************************************************************************/ -pub -struct TTF_File{ +pub struct TTF_File { pub mut: - buf []byte - pos u32 - - length u16 - - scalar_type u32 - search_range u16 - entry_selector u16 - range_shift u16 - - tables map[string]Offset_Table - - version f32 - font_revision f32 - checksum_adjustment u32 - magic_number u32 - flags u16 - units_per_em u16 - created u64 - modified u64 - x_min f32 - y_min f32 - x_max f32 - y_max f32 - mac_style u16 - lowest_rec_ppem u16 - font_direction_hint i16 - index_to_loc_format i16 - glyph_data_format i16 - - font_family string - font_sub_family string - full_name string - postscript_name string - - cmaps []TrueTypeCmap - - ascent i16 - descent i16 - line_gap i16 - advance_width_max u16 - min_left_side_bearing i16 - min_right_side_bearing i16 - x_max_extent i16 - caret_slope_rise i16 - caret_slope_run i16 - caret_offset i16 - metric_data_format i16 - num_of_long_hor_metrics u16 - + buf []byte + pos u32 + length u16 + scalar_type u32 + search_range u16 + entry_selector u16 + range_shift u16 + tables map[string]Offset_Table + version f32 + font_revision f32 + checksum_adjustment u32 + magic_number u32 + flags u16 + units_per_em u16 + created u64 + modified u64 + x_min f32 + y_min f32 + x_max f32 + y_max f32 + mac_style u16 + lowest_rec_ppem u16 + font_direction_hint i16 + index_to_loc_format i16 + glyph_data_format i16 + font_family string + font_sub_family string + full_name string + postscript_name string + cmaps []TrueTypeCmap + ascent i16 + descent i16 + line_gap i16 + advance_width_max u16 + min_left_side_bearing i16 + min_right_side_bearing i16 + x_max_extent i16 + caret_slope_rise i16 + caret_slope_run i16 + caret_offset i16 + metric_data_format i16 + num_of_long_hor_metrics u16 kern []Kern0Table - // cache - glyph_cache map[int]Glyph + glyph_cache map[int]Glyph } -pub -fn (mut tf TTF_File) init() { +pub fn (mut tf TTF_File) init() { tf.read_offset_tables() tf.read_head_table() - //dprintln(tf.get_info_string()) + // dprintln(tf.get_info_string()) tf.read_name_table() tf.read_cmap_table() tf.read_hhea_table() tf.read_kern_table() tf.length = tf.glyph_count() - dprintln("Number of symbols: $tf.length") - dprintln("*****************************") + dprintln('Number of symbols: $tf.length') + dprintln('*****************************') } + /****************************************************************************** * * TTF_File Glyph Structs * ******************************************************************************/ - -pub -struct Point { +pub struct Point { pub mut: x int y int @@ -131,19 +119,18 @@ pub mut: struct Gylph_Component { mut: - points []Point + points []Point } // type of glyph -const( - g_type_simple = u16(1) // simple type - g_type_complex = u16(2) // compound type +const ( + g_type_simple = u16(1) // simple type + g_type_complex = u16(2) // compound type ) -pub -struct Glyph { +pub struct Glyph { pub mut: - g_type u16 = g_type_simple + g_type u16 = ttf.g_type_simple contour_ends []u16 number_of_contours i16 points []Point @@ -155,122 +142,120 @@ pub mut: components []Component } - /****************************************************************************** * * TTF_File metrics and glyph * ******************************************************************************/ -pub -fn (mut tf TTF_File) get_horizontal_metrics(glyph_index u16) (int, int) { - assert"hmtx" in tf.tables +pub fn (mut tf TTF_File) get_horizontal_metrics(glyph_index u16) (int, int) { + assert 'hmtx' in tf.tables old_pos := tf.pos - mut offset := tf.tables["hmtx"].offset + mut offset := tf.tables['hmtx'].offset - mut advance_width := 0 + mut advance_width := 0 mut left_side_bearing := 0 if glyph_index < tf.num_of_long_hor_metrics { offset += glyph_index * 4 tf.pos = offset - advance_width = tf.get_u16() + advance_width = tf.get_u16() left_side_bearing = tf.get_i16() - //dprintln("Found h_metric aw: $advance_width lsb: $left_side_bearing") + // dprintln("Found h_metric aw: $advance_width lsb: $left_side_bearing") } else { // read the last entry of the hMetrics array tf.pos = offset + (tf.num_of_long_hor_metrics - 1) * 4 - advance_width = tf.get_u16() - tf.pos = offset + tf.num_of_long_hor_metrics * 4 + 2 * (glyph_index - tf.num_of_long_hor_metrics) + advance_width = tf.get_u16() + tf.pos = offset + tf.num_of_long_hor_metrics * 4 + + 2 * (glyph_index - tf.num_of_long_hor_metrics) left_side_bearing = tf.get_fword() } tf.pos = old_pos return advance_width, left_side_bearing } -fn (mut tf TTF_File) get_glyph_offset(index u32) u32{ +fn (mut tf TTF_File) get_glyph_offset(index u32) u32 { // check if needed tables exists - assert "loca" in tf.tables - assert "glyf" in tf.tables + assert 'loca' in tf.tables + assert 'glyf' in tf.tables mut old_pos := tf.pos - - table := tf.tables["loca"] - mut offset := u32(0) - mut next := u32(0) + + table := tf.tables['loca'] + mut offset := u32(0) + mut next := u32(0) if tf.index_to_loc_format == 1 { tf.pos = table.offset + (index << 2) - offset = tf.get_u32() - next = tf.get_u32() + offset = tf.get_u32() + next = tf.get_u32() } else { tf.pos = table.offset + (index << 1) - offset = tf.get_u16() << 1 - next = tf.get_u16() << 1 + offset = tf.get_u16() << 1 + next = tf.get_u16() << 1 } - + if offset == next { // indicates glyph has no outline( eg space) return 0 } - - //dprintln("Offset for glyph index $index is $offset") + // dprintln("Offset for glyph index $index is $offset") tf.pos = old_pos return offset + tf.tables['glyf'].offset } -fn (mut tf TTF_File) glyph_count() u16{ - assert "maxp" in tf.tables +fn (mut tf TTF_File) glyph_count() u16 { + assert 'maxp' in tf.tables old_pos := tf.pos - tf.pos = tf.tables["maxp"].offset + 4 + tf.pos = tf.tables['maxp'].offset + 4 count := tf.get_u16() tf.pos = old_pos return count } -pub -fn (mut tf TTF_File) read_glyph_dim(index u16) (int, int, int, int) { +pub fn (mut tf TTF_File) read_glyph_dim(index u16) (int, int, int, int) { offset := tf.get_glyph_offset(index) - //dprintln("offset: $offset") - if offset == 0 || offset >= tf.tables["glyf"].offset + tf.tables["glyf"].length { - dprintln("No glyph found!") + // dprintln("offset: $offset") + if offset == 0 || offset >= tf.tables['glyf'].offset + tf.tables['glyf'].length { + dprintln('No glyph found!') return 0, 0, 0, 0 } - assert offset >= tf.tables["glyf"].offset - assert offset < tf.tables["glyf"].offset + tf.tables["glyf"].length + assert offset >= tf.tables['glyf'].offset + assert offset < tf.tables['glyf'].offset + tf.tables['glyf'].length tf.pos = offset - //dprintln("file seek read_glyph: $tf.pos") - - /*number_of_contours*/ _ := tf.get_i16() + // dprintln("file seek read_glyph: $tf.pos") + + // number_of_contours + _ := tf.get_i16() x_min := tf.get_fword() y_min := tf.get_fword() x_max := tf.get_fword() y_max := tf.get_fword() - + return x_min, x_max, y_min, y_max } -pub -fn (mut tf TTF_File) read_glyph(index u16) Glyph { - index_int := int(index) //index.str() - if index_int in tf.glyph_cache{ - //dprintln("Found glyp: ${index}") +pub fn (mut tf TTF_File) read_glyph(index u16) Glyph { + index_int := int(index) // index.str() + if index_int in tf.glyph_cache { + // dprintln("Found glyp: ${index}") return tf.glyph_cache[index_int] } - //dprintln("Create glyp: ${index}") - + // dprintln("Create glyp: ${index}") + offset := tf.get_glyph_offset(index) - //dprintln("offset: $offset") - if offset == 0 || offset >= tf.tables["glyf"].offset + tf.tables["glyf"].length { - dprintln("No glyph found!") + // dprintln("offset: $offset") + if offset == 0 || offset >= tf.tables['glyf'].offset + tf.tables['glyf'].length { + dprintln('No glyph found!') return Glyph{} } - assert offset >= tf.tables["glyf"].offset - assert offset < tf.tables["glyf"].offset + tf.tables["glyf"].length + assert offset >= tf.tables['glyf'].offset + assert offset < tf.tables['glyf'].offset + tf.tables['glyf'].length tf.pos = offset - //dprintln("file seek read_glyph: $tf.pos") - - /* ---- BUG TO SOLVE ----- + // dprintln("file seek read_glyph: $tf.pos") + + /* + ---- BUG TO SOLVE ----- --- Order of the data if printed in the main is shuffled!! Very Strange mut tmp_glyph := Glyph{ number_of_contours : tf.get_i16() @@ -280,23 +265,23 @@ fn (mut tf TTF_File) read_glyph(index u16) Glyph { y_max : tf.get_fword() } */ - + mut tmp_glyph := Glyph{} tmp_glyph.number_of_contours = tf.get_i16() tmp_glyph.x_min = tf.get_fword() tmp_glyph.y_min = tf.get_fword() tmp_glyph.x_max = tf.get_fword() tmp_glyph.y_max = tf.get_fword() - - //dprintln("file seek after read_glyph: $tf.pos") + + // dprintln("file seek after read_glyph: $tf.pos") assert tmp_glyph.number_of_contours >= -1 if tmp_glyph.number_of_contours == -1 { - //dprintln("read_compound_glyph") + // dprintln("read_compound_glyph") tf.read_compound_glyph(mut tmp_glyph) } else { - //dprintln("read_simple_glyph") + // dprintln("read_simple_glyph") tf.read_simple_glyph(mut tmp_glyph) } @@ -304,7 +289,7 @@ fn (mut tf TTF_File) read_glyph(index u16) Glyph { return tmp_glyph } -const( +const ( tfk_on_curve = 1 tfk_x_is_byte = 2 tfk_y_is_byte = 4 @@ -313,18 +298,18 @@ const( tfk_y_delta = 32 ) -fn (mut tf TTF_File) read_simple_glyph(mut in_glyph Glyph){ +fn (mut tf TTF_File) read_simple_glyph(mut in_glyph Glyph) { if in_glyph.number_of_contours == 0 { return } - for _ in 0..in_glyph.number_of_contours { + for _ in 0 .. in_glyph.number_of_contours { in_glyph.contour_ends << tf.get_u16() } // skip over intructions - tf.pos = tf.get_u16() + tf.pos - + tf.pos = tf.get_u16() + tf.pos + mut num_points := 0 for ce in in_glyph.contour_ends { if ce > num_points { @@ -341,10 +326,9 @@ fn (mut tf TTF_File) read_simple_glyph(mut in_glyph Glyph){ in_glyph.points << Point{ x: 0 y: 0 - on_curve: (flag & tfk_on_curve) > 0 + on_curve: (flag & ttf.tfk_on_curve) > 0 } - - if (flag & tfk_repeat) > 0 { + if (flag & ttf.tfk_repeat) > 0 { mut repeat_count := tf.get_u8() assert repeat_count > 0 i += repeat_count @@ -353,7 +337,7 @@ fn (mut tf TTF_File) read_simple_glyph(mut in_glyph Glyph){ in_glyph.points << Point{ x: 0 y: 0 - on_curve: (flag & tfk_on_curve) > 0 + on_curve: (flag & ttf.tfk_on_curve) > 0 } repeat_count-- } @@ -363,39 +347,39 @@ fn (mut tf TTF_File) read_simple_glyph(mut in_glyph Glyph){ // read coords x mut value := 0 - for i_x in 0..num_points { + for i_x in 0 .. num_points { flag_x := flags[i_x] - if (flag_x & tfk_x_is_byte) > 0 { - if (flag_x & tfk_x_delta) > 0 { + if (flag_x & ttf.tfk_x_is_byte) > 0 { + if (flag_x & ttf.tfk_x_delta) > 0 { value += tf.get_u8() } else { value -= tf.get_u8() } - } else if (~flag_x & tfk_x_delta) > 0 { + } else if (~flag_x & ttf.tfk_x_delta) > 0 { value += tf.get_i16() } else { // value is unchanged } - //dprintln("$i_x x: $value") + // dprintln("$i_x x: $value") in_glyph.points[i_x].x = value } // read coords y value = 0 - for i_y in 0..num_points { + for i_y in 0 .. num_points { flag_y := flags[i_y] - if (flag_y & tfk_y_is_byte) > 0 { - if (flag_y & tfk_y_delta) > 0 { + if (flag_y & ttf.tfk_y_is_byte) > 0 { + if (flag_y & ttf.tfk_y_delta) > 0 { value += tf.get_u8() } else { value -= tf.get_u8() } - } else if (~flag_y & tfk_y_delta) > 0 { + } else if (~flag_y & ttf.tfk_y_delta) > 0 { value += tf.get_i16() } else { // value is unchanged } - //dprintln("$i_y y: $value") + // dprintln("$i_y y: $value") in_glyph.points[i_y].y = value } @@ -403,7 +387,7 @@ fn (mut tf TTF_File) read_simple_glyph(mut in_glyph Glyph){ in_glyph.valid_glyph = true } -const( +const ( tfkc_arg_1_and_2_are_words = 1 tfkc_args_are_xy_values = 2 tfkc_round_xy_to_grid = 4 @@ -425,19 +409,19 @@ mut: matrix []f32 = [f32(1.0), 0, 0, 1.0, 0, 0] } -fn (mut tf TTF_File) read_compound_glyph(mut in_glyph Glyph){ - in_glyph.g_type = g_type_complex +fn (mut tf TTF_File) read_compound_glyph(mut in_glyph Glyph) { + in_glyph.g_type = ttf.g_type_complex mut component := Component{} - mut flags := tfkc_more_components - for (flags & tfkc_more_components) > 0 { + mut flags := ttf.tfkc_more_components + for (flags & ttf.tfkc_more_components) > 0 { mut arg1 := i16(0) mut arg2 := i16(0) - + flags = tf.get_u16() component.glyph_index = tf.get_u16() - - if (flags & tfkc_arg_1_and_2_are_words) > 0 { + + if (flags & ttf.tfkc_arg_1_and_2_are_words) > 0 { arg1 = tf.get_i16() arg2 = tf.get_i16() } else { @@ -445,36 +429,35 @@ fn (mut tf TTF_File) read_compound_glyph(mut in_glyph Glyph){ arg2 = tf.get_u8() } - if (flags & tfkc_args_are_xy_values) > 0 { + if (flags & ttf.tfkc_args_are_xy_values) > 0 { component.matrix[4] = arg1 component.matrix[5] = arg2 } else { component.dest_point_index = arg1 - component.src_point_index = arg2 + component.src_point_index = arg2 } - if (flags & tfkc_we_have_a_scale) > 0 { + if (flags & ttf.tfkc_we_have_a_scale) > 0 { component.matrix[0] = tf.get_2dot14() component.matrix[3] = component.matrix[0] - } else if (flags & tfkc_we_have_an_x_and_y_scale) > 0 { + } else if (flags & ttf.tfkc_we_have_an_x_and_y_scale) > 0 { component.matrix[0] = tf.get_2dot14() component.matrix[3] = tf.get_2dot14() - } else if (flags & tfkc_we_have_a_two_by_two) > 0 { + } else if (flags & ttf.tfkc_we_have_a_two_by_two) > 0 { component.matrix[0] = tf.get_2dot14() component.matrix[1] = tf.get_2dot14() component.matrix[2] = tf.get_2dot14() component.matrix[3] = tf.get_2dot14() } - - //dprintln("Read component glyph index ${component.glyph_index}") - //dprintln("Transform: ${component.matrix}") + // dprintln("Read component glyph index ${component.glyph_index}") + // dprintln("Transform: ${component.matrix}") old_pos := tf.pos simple_glyph := tf.read_glyph(component.glyph_index) if simple_glyph.valid_glyph { point_offset := in_glyph.points.len - for i in 0..simple_glyph.contour_ends.len { + for i in 0 .. simple_glyph.contour_ends.len { in_glyph.contour_ends << u16(simple_glyph.contour_ends[i] + point_offset) } @@ -482,7 +465,7 @@ fn (mut tf TTF_File) read_compound_glyph(mut in_glyph Glyph){ mut x := f32(p.x) mut y := f32(p.y) x = component.matrix[0] * x + component.matrix[1] * y + component.matrix[4] - y = component.matrix[2] * x + component.matrix[3] * y + component.matrix[5] + y = component.matrix[2] * x + component.matrix[3] * y + component.matrix[5] in_glyph.points << Point{ x: int(x) y: int(y) @@ -495,10 +478,9 @@ fn (mut tf TTF_File) read_compound_glyph(mut in_glyph Glyph){ in_glyph.number_of_contours = i16(in_glyph.contour_ends.len) - if (flags & tfkc_we_have_instructions) > 0 { + if (flags & ttf.tfkc_we_have_instructions) > 0 { tf.pos = tf.get_u16() + tf.pos } - // ok we have a valid glyph in_glyph.valid_glyph = true } @@ -537,10 +519,8 @@ fn (mut tf TTF_File) get_fword() i16 { } fn (mut tf TTF_File) get_u32() u32 { - x :=(u32(tf.buf[tf.pos]) << u32(24)) | - (u32(tf.buf[tf.pos + 1]) << u32(16)) | - (u32(tf.buf[tf.pos + 2]) << u32(8)) | - u32(tf.buf[tf.pos + 3]) + x := (u32(tf.buf[tf.pos]) << u32(24)) | (u32(tf.buf[tf.pos + + 1]) << u32(16)) | (u32(tf.buf[tf.pos + 2]) << u32(8)) | u32(tf.buf[tf.pos + 3]) tf.pos += 4 return x } @@ -560,16 +540,16 @@ fn (mut tf TTF_File) get_fixed() f32 { fn (mut tf TTF_File) get_string(length int) string { tmp_pos := u64(tf.pos) tf.pos += u32(length) - return unsafe{ tos(byteptr(u64(tf.buf.data)+tmp_pos), length) } + return unsafe { tos(byteptr(u64(tf.buf.data) + tmp_pos), length) } } fn (mut tf TTF_File) get_unicode_string(length int) string { mut tmp_txt := strings.new_builder(length) mut real_len := 0 - - for _ in 0..(length>>1) { + + for _ in 0 .. (length >> 1) { c := tf.get_u16() - c_len := ((0xe5000000>>((c>>3) & 0x1e)) & 3) + 1 + c_len := ((0xe5000000 >> ((c >> 3) & 0x1e)) & 3) + 1 real_len += c_len if c_len == 1 { tmp_txt.write_b(byte(c & 0xff)) @@ -577,11 +557,11 @@ fn (mut tf TTF_File) get_unicode_string(length int) string { tmp_txt.write_b(byte((c >> 8) & 0xff)) tmp_txt.write_b(byte(c & 0xff)) } - //dprintln("c: ${c:c}|${ byte(c &0xff) :c} c_len: ${c_len} str_len: ${real_len} in_len: ${length}") + // dprintln("c: ${c:c}|${ byte(c &0xff) :c} c_len: ${c_len} str_len: ${real_len} in_len: ${length}") } tf.pos += u32(real_len) res_txt := tmp_txt.str() - //dprintln("get_unicode_string: ${res_txt}") + // dprintln("get_unicode_string: ${res_txt}") return res_txt } @@ -593,11 +573,11 @@ fn (mut tf TTF_File) get_date() u64 { } fn (mut tf TTF_File) calc_checksum(offset u32, length u32) u32 { - old_index := tf.pos - mut sum := u64(0) + old_index := tf.pos + mut sum := u64(0) mut nlongs := int((length + 3) >> 2) tf.pos = offset - //dprintln("offs: $offset nlongs: $nlongs") + // dprintln("offs: $offset nlongs: $nlongs") for nlongs > 0 { sum = sum + u64(tf.get_u32()) nlongs-- @@ -619,37 +599,37 @@ mut: } fn (mut tf TTF_File) read_offset_tables() { - dprintln("*** READ TABLES OFFSET ***") + dprintln('*** READ TABLES OFFSET ***') tf.pos = 0 - tf.scalar_type = tf.get_u32() - num_tables := tf.get_u16() - tf.search_range = tf.get_u16() - tf.entry_selector= tf.get_u16() - tf.range_shift = tf.get_u16() + tf.scalar_type = tf.get_u32() + num_tables := tf.get_u16() + tf.search_range = tf.get_u16() + tf.entry_selector = tf.get_u16() + tf.range_shift = tf.get_u16() - dprintln("scalar_type : [0x$tf.scalar_type.hex()]") - dprintln("num tables : [$num_tables]") - dprintln("search_range : [0x$tf.search_range.hex()]") - dprintln("entry_selector: [0x$tf.entry_selector.hex()]") - dprintln("range_shift : [0x$tf.range_shift.hex()]") + dprintln('scalar_type : [0x$tf.scalar_type.hex()]') + dprintln('num tables : [$num_tables]') + dprintln('search_range : [0x$tf.search_range.hex()]') + dprintln('entry_selector: [0x$tf.entry_selector.hex()]') + dprintln('range_shift : [0x$tf.range_shift.hex()]') - mut i:= 0 + mut i := 0 for i < num_tables { tag := tf.get_string(4) tf.tables[tag] = { checksum: tf.get_u32() - offset: tf.get_u32() - length: tf.get_u32() + offset: tf.get_u32() + length: tf.get_u32() } - dprintln("Table: [$tag]") - //dprintln("${tf.tables[tag]}") + dprintln('Table: [$tag]') + // dprintln("${tf.tables[tag]}") if tag != 'head' { assert tf.calc_checksum(tf.tables[tag].offset, tf.tables[tag].length) == tf.tables[tag].checksum } i++ } - dprintln("*** END READ TABLES OFFSET ***") + dprintln('*** END READ TABLES OFFSET ***') } /****************************************************************************** @@ -658,28 +638,28 @@ fn (mut tf TTF_File) read_offset_tables() { * ******************************************************************************/ fn (mut tf TTF_File) read_head_table() { - dprintln("*** READ HEAD TABLE ***") - tf.pos = tf.tables["head"].offset - dprintln("Offset: $tf.pos") + dprintln('*** READ HEAD TABLE ***') + tf.pos = tf.tables['head'].offset + dprintln('Offset: $tf.pos') - tf.version = tf.get_fixed() - tf.font_revision = tf.get_fixed() + tf.version = tf.get_fixed() + tf.font_revision = tf.get_fixed() tf.checksum_adjustment = tf.get_u32() - tf.magic_number = tf.get_u32() + tf.magic_number = tf.get_u32() assert tf.magic_number == 0x5f0f3cf5 - tf.flags = tf.get_u16() - tf.units_per_em = tf.get_u16() - tf.created = tf.get_date() - tf.modified = tf.get_date() - tf.x_min = tf.get_i16() - tf.y_min = tf.get_i16() - tf.x_max = tf.get_i16() - tf.y_max = tf.get_i16() - tf.mac_style = tf.get_u16() - tf.lowest_rec_ppem = tf.get_u16() + tf.flags = tf.get_u16() + tf.units_per_em = tf.get_u16() + tf.created = tf.get_date() + tf.modified = tf.get_date() + tf.x_min = tf.get_i16() + tf.y_min = tf.get_i16() + tf.x_max = tf.get_i16() + tf.y_max = tf.get_i16() + tf.mac_style = tf.get_u16() + tf.lowest_rec_ppem = tf.get_u16() tf.font_direction_hint = tf.get_i16() tf.index_to_loc_format = tf.get_i16() - tf.glyph_data_format = tf.get_i16() + tf.glyph_data_format = tf.get_i16() } /****************************************************************************** @@ -688,49 +668,43 @@ fn (mut tf TTF_File) read_head_table() { * ******************************************************************************/ fn (mut tf TTF_File) read_name_table() { - dprintln("*** READ NAME TABLE ***") - assert "name" in tf.tables - table_offset := tf.tables["name"].offset - tf.pos = tf.tables["name"].offset - - format := tf.get_u16() // must be 0 + dprintln('*** READ NAME TABLE ***') + assert 'name' in tf.tables + table_offset := tf.tables['name'].offset + tf.pos = tf.tables['name'].offset + + format := tf.get_u16() // must be 0 assert format == 0 - count := tf.get_u16() + count := tf.get_u16() string_offset := tf.get_u16() - for _ in 0..count { - platform_id := tf.get_u16() - /*platform_specific_id :=*/ tf.get_u16() - /*language_id :=*/ tf.get_u16() - name_id := tf.get_u16() - length := tf.get_u16() - offset := tf.get_u16() + for _ in 0 .. count { + platform_id := tf.get_u16() + // platform_specific_id := + tf.get_u16() + // language_id := + tf.get_u16() + name_id := tf.get_u16() + length := tf.get_u16() + offset := tf.get_u16() - old_pos := tf.pos + old_pos := tf.pos tf.pos = table_offset + string_offset + offset - mut name := "" + mut name := '' if platform_id == 0 || platform_id == 3 { name = tf.get_unicode_string(length) } else { name = tf.get_string(length) } - //dprintln("Name [${platform_id} / ${platform_specific_id}] id:[$name_id] language:[$language_id] [$name]") + // dprintln("Name [${platform_id} / ${platform_specific_id}] id:[$name_id] language:[$language_id] [$name]") tf.pos = old_pos match name_id { - 1 { - tf.font_family = name - } - 2 { - tf.font_sub_family = name - } - 4 { - tf.full_name = name - } - 6 { - tf.postscript_name = name - } + 1 { tf.font_family = name } + 2 { tf.font_sub_family = name } + 4 { tf.full_name = name } + 6 { tf.postscript_name = name } else {} } } @@ -742,27 +716,27 @@ fn (mut tf TTF_File) read_name_table() { * ******************************************************************************/ fn (mut tf TTF_File) read_cmap_table() { - dprintln("*** READ CMAP TABLE ***") - assert "cmap" in tf.tables - table_offset := tf.tables["cmap"].offset + dprintln('*** READ CMAP TABLE ***') + assert 'cmap' in tf.tables + table_offset := tf.tables['cmap'].offset tf.pos = table_offset - version := tf.get_u16() // must be 0 + version := tf.get_u16() // must be 0 assert version == 0 number_sub_tables := tf.get_u16() // tables must be sorted by platform id and then platform specific // encoding. - for _ in 0..number_sub_tables { + for _ in 0 .. number_sub_tables { // platforms are: // 0 - Unicode -- use specific id 6 for full coverage. 0/4 common. // 1 - Macintosh (Discouraged) // 2 - reserved // 3 - Microsoft - platform_id := tf.get_u16() + platform_id := tf.get_u16() platform_specific_id := tf.get_u16() - offset := tf.get_u32() - dprintln("CMap platform_id=${platform_id} specific_id=${platform_specific_id} offset=${offset}") + offset := tf.get_u32() + dprintln('CMap platform_id=$platform_id specific_id=$platform_specific_id offset=$offset') if platform_id == 3 && platform_specific_id <= 1 { tf.read_cmap(table_offset + offset) } @@ -771,19 +745,19 @@ fn (mut tf TTF_File) read_cmap_table() { fn (mut tf TTF_File) read_cmap(offset u32) { old_pos := tf.pos - tf.pos = offset - format := tf.get_u16() - length := tf.get_u16() + tf.pos = offset + format := tf.get_u16() + length := tf.get_u16() language := tf.get_u16() - dprintln(" Cmap format: $format length: $length language: $language") + dprintln(' Cmap format: $format length: $length language: $language') if format == 0 { - dprintln(" Cmap 0 Init...") + dprintln(' Cmap 0 Init...') mut cmap := TrueTypeCmap{} cmap.init_0(mut tf) tf.cmaps << cmap } else if format == 4 { - dprintln(" Cmap 4 Init...") + dprintln(' Cmap 4 Init...') mut cmap := TrueTypeCmap{} cmap.init_4(mut tf) tf.cmaps << cmap @@ -797,15 +771,15 @@ fn (mut tf TTF_File) read_cmap(offset u32) { * CMAPS 0/4 * ******************************************************************************/ -fn (mut tf TTF_File) map_code(char_code int) u16{ +fn (mut tf TTF_File) map_code(char_code int) u16 { mut index := 0 - for i in 0..tf.cmaps.len { + for i in 0 .. tf.cmaps.len { mut cmap := tf.cmaps[i] if cmap.format == 0 { - //dprintln("format 0") + // dprintln("format 0") index = cmap.map_0(char_code) } else if cmap.format == 4 { - //dprintln("format 4") + // dprintln("format 4") index = cmap.map_4(char_code, mut tf) } } @@ -814,16 +788,16 @@ fn (mut tf TTF_File) map_code(char_code int) u16{ fn (mut tm TrueTypeCmap) init_0(mut tf TTF_File) { tm.format = 0 - for i in 0..256 { + for i in 0 .. 256 { glyph_index := tf.get_u8() - dprintln(" Glyph[$i] = %glyph_index") + dprintln(' Glyph[$i] = %glyph_index') tm.arr << glyph_index } } fn (mut tm TrueTypeCmap) map_0(char_code int) int { if char_code >= 0 && char_code <= 255 { - //dprintln("charCode $char_code maps to ${tm.arr[char_code]}") + // dprintln("charCode $char_code maps to ${tm.arr[char_code]}") return tm.arr[char_code] } return 0 @@ -833,59 +807,62 @@ fn (mut tm TrueTypeCmap) init_4(mut tf TTF_File) { tm.format = 4 // 2x segcount - seg_count := tf.get_u16() >> 1 - /*search_range :=*/ tf.get_u16() - /*entry_selector :=*/ tf.get_u16() - /*range_shift :=*/ tf.get_u16() - + seg_count := tf.get_u16() >> 1 + // search_range := + tf.get_u16() + // entry_selector := + tf.get_u16() + // range_shift := + tf.get_u16() // Ending character code for each segment, last is 0xffff - for _ in 0..seg_count { - tm.segments << Segment{0, 0, tf.get_u16(), 0} + for _ in 0 .. seg_count { + tm.segments << Segment{0, 0, tf.get_u16(), 0} } // reservePAD tf.get_u16() // starting character code for each segment - for i in 0..seg_count { - tm.segments[i].start_code = tf.get_u16() + for i in 0 .. seg_count { + tm.segments[i].start_code = tf.get_u16() } // Delta for all character codes in segment - for i in 0..seg_count { - tm.segments[i].id_delta = tf.get_u16() + for i in 0 .. seg_count { + tm.segments[i].id_delta = tf.get_u16() } // offset in bytes to glyph indexArray, or 0 - for i in 0..seg_count { + for i in 0 .. seg_count { ro := u32(tf.get_u16()) if ro != 0 { - tm.segments[i].id_range_offset = tf.pos - 2 + ro + tm.segments[i].id_range_offset = tf.pos - 2 + ro } else { - tm.segments[i].id_range_offset = 0 + tm.segments[i].id_range_offset = 0 } } -/* + /* // DEBUG LOG for i in 0..seg_count { seg := tm.segments[i] dprintln(" segments[$i] = $seg.start_code $seg.end_code $seg.id_delta $seg.id_range_offset") } -*/ + */ } fn (mut tm TrueTypeCmap) map_4(char_code int, mut tf TTF_File) int { - //dprintln("HERE map_4 for char [$char_code]") + // dprintln("HERE map_4 for char [$char_code]") old_pos := tf.pos if tm.cache[char_code] == -1 { - //dprintln("Not found, search for it!") + // dprintln("Not found, search for it!") mut found := false for segment in tm.segments { if segment.start_code <= char_code && segment.end_code >= char_code { mut index := (segment.id_delta + char_code) & 0xffff if segment.id_range_offset > 0 { - glyph_index_address := segment.id_range_offset + 2 * u32(char_code - segment.start_code) + glyph_index_address := segment.id_range_offset + + 2 * u32(char_code - segment.start_code) tf.pos = glyph_index_address index = tf.get_u16() } @@ -909,28 +886,29 @@ fn (mut tm TrueTypeCmap) map_4(char_code int, mut tf TTF_File) int { * ******************************************************************************/ fn (mut tf TTF_File) read_hhea_table() { - dprintln("*** READ HHEA TABLE ***") - assert "hhea" in tf.tables - table_offset := tf.tables["hhea"].offset + dprintln('*** READ HHEA TABLE ***') + assert 'hhea' in tf.tables + table_offset := tf.tables['hhea'].offset tf.pos = table_offset - /*version :=*/ tf.get_fixed() // 0x00010000 - - tf.ascent = tf.get_fword() - tf.descent = tf.get_fword() - tf.line_gap = tf.get_fword() - tf.advance_width_max = tf.get_ufword() - tf.min_left_side_bearing = tf.get_fword() - tf.min_right_side_bearing = tf.get_fword() - tf.x_max_extent = tf.get_fword() - tf.caret_slope_rise = tf.get_i16() - tf.caret_slope_run = tf.get_i16() - tf.caret_offset = tf.get_fword() + // version := + tf.get_fixed() // 0x00010000 + + tf.ascent = tf.get_fword() + tf.descent = tf.get_fword() + tf.line_gap = tf.get_fword() + tf.advance_width_max = tf.get_ufword() + tf.min_left_side_bearing = tf.get_fword() + tf.min_right_side_bearing = tf.get_fword() + tf.x_max_extent = tf.get_fword() + tf.caret_slope_rise = tf.get_i16() + tf.caret_slope_run = tf.get_i16() + tf.caret_offset = tf.get_fword() tf.get_i16() // reserved tf.get_i16() // reserved tf.get_i16() // reserved tf.get_i16() // reserved - tf.metric_data_format = tf.get_i16() + tf.metric_data_format = tf.get_i16() tf.num_of_long_hor_metrics = tf.get_u16() } @@ -941,11 +919,11 @@ fn (mut tf TTF_File) read_hhea_table() { ******************************************************************************/ struct Kern0Table { mut: - swap bool - offset u32 - n_pairs int - kmap map[u32]i16 - old_index int = -1 + swap bool + offset u32 + n_pairs int + kmap map[u32]i16 + old_index int = -1 } fn (mut kt Kern0Table) reset() { @@ -957,25 +935,25 @@ fn (mut kt Kern0Table) get(glyph_index int) (int, int) { if kt.old_index >= 0 { ch := ((u32(kt.old_index & 0xFFFF) << 16) | u32(glyph_index & 0xFFFF)) - //dprintln("kern_get: $ch") + // dprintln("kern_get: $ch") if ch in kt.kmap { x = int(kt.kmap[ch]) } } kt.old_index = glyph_index if kt.swap { - return 0 , x + return 0, x } return x, 0 } fn (mut tf TTF_File) create_kern_table0(vertical bool, cross bool) Kern0Table { - offset := tf.pos - n_pairs := tf.get_u16() - search_range := tf.get_u16() + offset := tf.pos + n_pairs := tf.get_u16() + search_range := tf.get_u16() entry_selector := tf.get_u16() - range_shift := tf.get_u16() - dprintln("n_pairs: $n_pairs search_range: $search_range entry_selector: $entry_selector range_shift: $range_shift") + range_shift := tf.get_u16() + dprintln('n_pairs: $n_pairs search_range: $search_range entry_selector: $entry_selector range_shift: $range_shift') mut kt0 := Kern0Table{ swap: (vertical && !cross) || (!vertical && cross) @@ -983,61 +961,61 @@ fn (mut tf TTF_File) create_kern_table0(vertical bool, cross bool) Kern0Table { n_pairs: n_pairs } - for _ in 0..n_pairs { - left := tf.get_u16() + for _ in 0 .. n_pairs { + left := tf.get_u16() right := tf.get_u16() value := tf.get_fword() tmp_index := (u32(left) << 16) | u32(right) kt0.kmap[tmp_index] = value - //dprintln("index: ${tmp_index.hex()} val: ${value.hex()}") + // dprintln("index: ${tmp_index.hex()} val: ${value.hex()}") } kt0.old_index = -1 return kt0 } fn (mut tf TTF_File) read_kern_table() { - dprintln("*** READ KERN TABLE ***") - if !("kern" in tf.tables){ + dprintln('*** READ KERN TABLE ***') + if !('kern' in tf.tables) { return } - table_offset := tf.tables["kern"].offset + table_offset := tf.tables['kern'].offset tf.pos = table_offset - version := tf.get_u16() // must be 0 + version := tf.get_u16() // must be 0 assert version == 0 // must be 0 - n_tables := tf.get_u16() + n_tables := tf.get_u16() - dprintln("Kern Table version: $version Kern nTables: $n_tables") + dprintln('Kern Table version: $version Kern nTables: $n_tables') - for _ in 0..n_tables{ + for _ in 0 .. n_tables { st_version := tf.get_u16() // sub table version - length := tf.get_u16() - coverage := tf.get_u16() - format := coverage >> 8 - cross := coverage & 4 - vertical := (coverage & 0x1) == 0 - dprintln("Kerning subtable version [$st_version] format [$format] length [$length] coverage: [${coverage.hex()}]") + length := tf.get_u16() + coverage := tf.get_u16() + format := coverage >> 8 + cross := coverage & 4 + vertical := (coverage & 0x1) == 0 + dprintln('Kerning subtable version [$st_version] format [$format] length [$length] coverage: [$coverage.hex()]') if format == 0 { - dprintln("kern format: 0") + dprintln('kern format: 0') kern := tf.create_kern_table0(vertical, cross != 0) tf.kern << kern } else { - dprintln("Unknown format -- skip") + dprintln('Unknown format -- skip') tf.pos = tf.pos + length } } } fn (mut tf TTF_File) reset_kern() { - for i in 0..tf.kern.len { + for i in 0 .. tf.kern.len { tf.kern[i].reset() } } -fn (mut tf TTF_File) next_kern(glyph_index int) (int, int){ +fn (mut tf TTF_File) next_kern(glyph_index int) (int, int) { mut x := 0 mut y := 0 - for i in 0..tf.kern.len { + for i in 0 .. tf.kern.len { tmp_x, tmp_y := tf.kern[i].get(glyph_index) x = x + tmp_x y = y + tmp_y @@ -1045,29 +1023,27 @@ fn (mut tf TTF_File) next_kern(glyph_index int) (int, int){ return x, y } - /****************************************************************************** * * TTF_File Utility * ******************************************************************************/ -pub -fn (tf TTF_File) get_info_string() string{ - txt := "----- Font Info ----- +pub fn (tf TTF_File) get_info_string() string { + txt := '----- Font Info ----- font_family : $tf.font_family font_sub_family : $tf.font_sub_family full_name : $tf.full_name postscript_name : $tf.postscript_name version : $tf.version font_revision : $tf.font_revision -magic_number : ${tf.magic_number.hex()} -flags : ${tf.flags.hex()} -created unixTS : ${tf.created} -modified unixTS : ${tf.modified} -box : [x_min:${tf.x_min}, y_min:${tf.y_min}, x_Max:${tf.x_max}, y_Max:${tf.y_max}] -mac_style : ${tf.mac_style} +magic_number : $tf.magic_number.hex() +flags : $tf.flags.hex() +created unixTS : $tf.created +modified unixTS : $tf.modified +box : [x_min:$tf.x_min, y_min:$tf.y_min, x_Max:$tf.x_max, y_Max:$tf.y_max] +mac_style : $tf.mac_style ----------------------- -" +' return txt } @@ -1076,24 +1052,34 @@ mac_style : ${tf.mac_style} * TTF_File test * ******************************************************************************/ -fn tst(){ +fn tst() { mut tf := TTF_File{} tf.buf = [ - byte(0xFF), // 8 bit - 0xF1, 0xF2, // 16 bit - 0x81, 0x23, 0x45, 0x67, // 32 bit - 0x12, 0x34, 0x12, 0x34, // get_2dot14 16 bit - 0x12, 0x34, 0x12, 0x34 // get_fixed 32 bit int + byte(0xFF), /* 8 bit */ + 0xF1, + 0xF2, /* 16 bit */ + 0x81, + 0x23, + 0x45, + 0x67, /* 32 bit */ + 0x12, + 0x34, + 0x12, + 0x34, /* get_2dot14 16 bit */ + 0x12, + 0x34, + 0x12, + 0x34 /* get_fixed 32 bit int */, ] - assert tf.get_u8().hex() == "ff" - assert tf.get_u16().hex() == "f1f2" - assert tf.get_u32().hex() == "81234567" + assert tf.get_u8().hex() == 'ff' + assert tf.get_u16().hex() == 'f1f2' + assert tf.get_u32().hex() == '81234567' - dprintln("buf len: ${tf.buf.len}") - //dprintln( tf.get_u8().hex() ) - //dprintln( tf.get_u16().hex() ) - //dprintln( tf.get_u32().hex() ) - //dprintln( tf.get_2dot14() ) - //dprintln( tf.get_fixed() ) + dprintln('buf len: $tf.buf.len') + // dprintln( tf.get_u8().hex() ) + // dprintln( tf.get_u16().hex() ) + // dprintln( tf.get_u32().hex() ) + // dprintln( tf.get_2dot14() ) + // dprintln( tf.get_fixed() ) } diff --git a/vlib/x/ttf/ttf_test.v b/vlib/x/ttf/ttf_test.v index 5b0453debd..06c2fdf122 100644 --- a/vlib/x/ttf/ttf_test.v +++ b/vlib/x/ttf/ttf_test.v @@ -1,3 +1,7 @@ +import x.ttf +import os +import strings + /********************************************************************** * * BMP render module utility functions @@ -12,100 +16,11 @@ * TODO: * - manage text directions R to L **********************************************************************/ -import ttf -import os -import strings +const font_path = 'Qarmic_sans_Abridged.ttf' -const ( - font_path = 'Qarmic_sans_Abridged.ttf' -) +const font_bytes = $embed_file('ttf_test_data.bin') -fn save_raw_data_as_array(buf_bin []byte, file_name string) { - mut buf := strings.new_builder(buf_bin.len * 5) - for x in buf_bin { - buf.write("0x${x:02x},") - } - os.write_file_array(file_name, buf.buf) -} - -fn test_main() { - mut tf := ttf.TTF_File{} - $if create_data ? { - tf.buf = os.read_bytes(font_path) or { panic(err) } - println("TrueTypeFont file [$font_path] len: ${tf.buf.len}") - save_raw_data_as_array(tf.buf, "test_ttf_Font_arr.bin") - } $else { - tf.buf = font_bytes - } - tf.init() - //println("Unit per EM: $tf.units_per_em") - - w := 64 - h := 32 - bp := 4 - sz := w * h* bp - - font_size := 20 - device_dpi := 72 - scale := f32(font_size * device_dpi) / f32(72 * tf.units_per_em) - - mut bmp := ttf.BitMap{ - tf : &tf - buf : malloc(sz) - buf_size : sz - scale : scale - width : w - height : h - } - - y_base := int((tf.y_max - tf.y_min) * bmp.scale) - bmp.clear() - bmp.set_pos(0,y_base) - bmp.init_filler() - bmp.draw_text("Test Text") - - mut test_buf := get_raw_data(test_data) - $if create_data ? { - bmp.save_as_ppm("test_ttf.ppm") - bmp.save_raw_data("test_ttf.bin") - test_buf = os.read_bytes("test_ttf.bin") or { panic(err) } - } - - ram_buf := bmp.get_raw_bytes() - assert ram_buf.len == test_buf.len - for i in 0..ram_buf.len { - if test_buf[i] != ram_buf[i] { - assert false - } - } -} - -fn get_raw_data(data string) []byte{ - mut buf := []byte{} - mut c := 0 - mut b := 0 - for ch in data { - if ch >= `0` && ch <= `9` { - b = b << 4 - b += int(ch - `0`) - c++ - } else if ch >= `a` && ch <= `f` { - b = b << 4 - b += int(ch - `a` + 10) - c++ - } - - if c == 2 { - buf << byte(b) - b = 0 - c = 0 - } - } - return buf -} - -const( - test_data =" +const test_data = ' 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 @@ -234,9 +149,89 @@ ffbf ffff bf00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -" +' -font_bytes = [ -byte(0x00),0x01,0x00,0x00,0x00,0x0c,0x00,0x80,0x00,0x03,0x00,0x40,0x4f,0x53,0x2f,0x32,0x41,0x98,0xb7,0x90,0x00,0x00,0x01,0x48,0x00,0x00,0x00,0x56,0x63,0x6d,0x61,0x70,0x53,0x38,0xf9,0xae,0x00,0x00,0x03,0x60,0x00,0x00,0x02,0xa4,0x67,0x61,0x73,0x70,0xff,0xff,0x00,0x03,0x00,0x00,0x3e,0xf4,0x00,0x00,0x00,0x08,0x67,0x6c,0x79,0x66,0x95,0xf3,0xc8,0x23,0x00,0x00,0x06,0xe8,0x00,0x00,0x2f,0x6c,0x68,0x65,0x61,0x64,0xf1,0x64,0x88,0x06,0x00,0x00,0x00,0xcc,0x00,0x00,0x00,0x36,0x68,0x68,0x65,0x61,0x11,0x4c,0x06,0xc9,0x00,0x00,0x01,0x04,0x00,0x00,0x00,0x24,0x68,0x6d,0x74,0x78,0x03,0x08,0x1c,0x4d,0x00,0x00,0x01,0xa0,0x00,0x00,0x01,0xc0,0x6b,0x65,0x72,0x6e,0xe3,0x4a,0xe3,0x1a,0x00,0x00,0x36,0x54,0x00,0x00,0x02,0x22,0x6c,0x6f,0x63,0x61,0xa1,0xec,0x96,0x76,0x00,0x00,0x06,0x04,0x00,0x00,0x00,0xe2,0x6d,0x61,0x78,0x70,0x00,0x7b,0x00,0x9a,0x00,0x00,0x01,0x28,0x00,0x00,0x00,0x20,0x6e,0x61,0x6d,0x65,0x86,0x7c,0x31,0x7d,0x00,0x00,0x38,0x78,0x00,0x00,0x05,0x5e,0x70,0x6f,0x73,0x74,0x21,0x0a,0xb6,0x4f,0x00,0x00,0x3d,0xd8,0x00,0x00,0x01,0x1a,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x17,0x61,0x7a,0x59,0x5f,0x0f,0x3c,0xf5,0x00,0x0b,0x08,0x00,0x00,0x00,0x00,0x00,0xc4,0x10,0x0e,0x69,0x00,0x00,0x00,0x00,0xc6,0x1e,0x2e,0xbf,0xfe,0xb5,0xfd,0xbd,0x09,0x63,0x08,0x26,0x00,0x00,0x00,0x06,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x09,0x31,0xfd,0xbd,0x00,0x00,0x09,0x62,0xfe,0xb5,0xff,0x39,0x09,0x63,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x01,0x00,0x00,0x00,0x70,0x00,0x68,0x00,0x05,0x00,0x31,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x01,0x00,0x01,0x04,0x34,0x01,0x90,0x00,0x05,0x00,0x08,0x05,0x9a,0x05,0x33,0x00,0x00,0x01,0x1b,0x05,0x9a,0x05,0x33,0x00,0x00,0x03,0xd1,0x00,0x66,0x02,0x12,0x00,0x00,0x02,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0xa7,0x50,0x00,0x00,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x4c,0x20,0x20,0x00,0x40,0x00,0x20,0x22,0x19,0x07,0x47,0xfd,0xe7,0x00,0xcd,0x09,0x31,0x02,0x43,0x20,0x00,0x01,0x11,0x41,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x01,0xfc,0x00,0x00,0x03,0x7d,0x00,0x00,0x02,0xb1,0x00,0xce,0x02,0xd7,0x00,0x64,0x05,0x0a,0x00,0x41,0x04,0xf9,0x00,0x45,0x06,0xbd,0x00,0x20,0x07,0x03,0x00,0x92,0x01,0x89,0x00,0x64,0x02,0xaa,0x00,0x7d,0x02,0xaa,0x00,0x51,0x03,0x1d,0x00,0x4c,0x04,0xac,0x00,0xc0,0x02,0x39,0x00,0x9e,0x03,0x14,0x00,0x14,0x01,0xff,0x00,0x9e,0x03,0x3c,0xff,0xf7,0x04,0x73,0x00,0x0d,0x04,0x73,0x00,0xa9,0x04,0x73,0x00,0x28,0x04,0x73,0x00,0x20,0x04,0x73,0x00,0x00,0x04,0x73,0x00,0x35,0x04,0x73,0x00,0x0a,0x04,0x73,0x00,0x1a,0x04,0x73,0x00,0x11,0x04,0x73,0x00,0x21,0x01,0xff,0x00,0x9e,0x01,0xff,0x00,0x9e,0x04,0xac,0x00,0xc9,0x04,0xac,0x00,0xc0,0x04,0xac,0x00,0xc9,0x04,0x73,0x00,0xbc,0x06,0x44,0x00,0x40,0x06,0xa5,0x00,0x45,0x06,0x8f,0x00,0x57,0x06,0x12,0x00,0x3c,0x06,0x4a,0x00,0x34,0x05,0xbd,0x00,0x38,0x04,0xb2,0x00,0x35,0x07,0x0d,0x00,0x1e,0x06,0xde,0x00,0x1d,0x02,0xc6,0x00,0x33,0x06,0x92,0x00,0x51,0x06,0x61,0xff,0xf9,0x05,0xa0,0x00,0x43,0x09,0x26,0x00,0x3d,0x07,0x06,0x00,0x3d,0x07,0xa7,0x00,0x1a,0x06,0x50,0x00,0x3d,0x07,0x93,0x00,0x24,0x06,0x5c,0x00,0x27,0x06,0x28,0x00,0x2a,0x05,0x97,0x00,0x01,0x06,0x3f,0x00,0x16,0x06,0x4c,0x00,0x02,0x09,0x62,0x00,0x02,0x05,0x68,0x00,0x12,0x05,0xe9,0x00,0x21,0x05,0xce,0x00,0x31,0x03,0x20,0x00,0xaa,0x03,0x0b,0x00,0x0f,0x03,0x1a,0x00,0x50,0x04,0x2b,0x00,0x00,0x04,0x73,0xff,0xa6,0x02,0xaa,0x00,0x4a,0x05,0x02,0x00,0x3e,0x05,0x15,0x00,0x4b,0x04,0x49,0x00,0x39,0x05,0x35,0x00,0x34,0x04,0xc0,0x00,0x39,0x02,0x70,0xff,0xc6,0x05,0x02,0x00,0x27,0x04,0xc0,0x00,0x42,0x02,0x73,0x00,0x52,0x02,0x12,0xfe,0xb5,0x04,0x52,0x00,0x3e,0x02,0x3d,0x00,0x38,0x07,0x96,0x00,0x46,0x04,0xd4,0x00,0x46,0x05,0x51,0x00,0x2d,0x05,0x0a,0x00,0x45,0x05,0x43,0x00,0x27,0x03,0x28,0x00,0x33,0x04,0x49,0x00,0x45,0x03,0x94,0x00,0x12,0x04,0xa7,0x00,0x35,0x04,0x22,0x00,0x11,0x06,0x6d,0x00,0x08,0x04,0x22,0x00,0x1c,0x04,0x9e,0x00,0x32,0x03,0xca,0x00,0x32,0x03,0xf6,0x00,0x87,0x02,0x3b,0x00,0x9c,0x04,0x2d,0x00,0x33,0x05,0xc5,0x00,0x07,0x04,0x00,0x01,0x00,0x03,0x2f,0x00,0x16,0x03,0xf6,0x00,0x57,0x03,0x14,0x00,0x34,0x02,0xa2,0x00,0x3c,0x04,0x73,0x00,0x28,0x04,0x73,0x00,0x20,0x04,0x00,0x00,0xd3,0x02,0xc4,0x00,0x9e,0x04,0x00,0x01,0x58,0x04,0x73,0x00,0xbd,0x06,0xac,0x00,0x1b,0x06,0x52,0x00,0x1a,0x06,0xac,0x00,0x20,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xa0,0x00,0x03,0x00,0x01,0x00,0x00,0x00,0x1c,0x00,0x04,0x00,0x84,0x00,0x00,0x00,0x1a,0x00,0x10,0x00,0x03,0x00,0x0a,0x00,0x7a,0x00,0x7e,0x00,0xa3,0x00,0xa8,0x00,0xaa,0x00,0xad,0x00,0xb0,0x00,0xb4,0x00,0xb9,0x00,0xbe,0x03,0x7e,0x22,0x19,0xff,0xff,0x00,0x00,0x00,0x20,0x00,0x7e,0x00,0xa0,0x00,0xa8,0x00,0xaa,0x00,0xac,0x00,0xaf,0x00,0xb2,0x00,0xb7,0x00,0xbc,0x03,0x7e,0x22,0x19,0xff,0xff,0xff,0xe3,0xff,0xe0,0x00,0x00,0xff,0xba,0xff,0xb9,0x00,0x00,0xff,0xb6,0xff,0xb5,0xff,0xb3,0xff,0xb1,0xfc,0xa0,0xde,0x51,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x16,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x5f,0x00,0x60,0x00,0x61,0x00,0x64,0x00,0x10,0x00,0x06,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0xfd,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x04,0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,0x09,0x00,0x0a,0x00,0x0b,0x00,0x0c,0x00,0x0d,0x00,0x0e,0x00,0x0f,0x00,0x10,0x00,0x11,0x00,0x12,0x00,0x13,0x00,0x14,0x00,0x15,0x00,0x16,0x00,0x17,0x00,0x18,0x00,0x19,0x00,0x1a,0x00,0x1b,0x00,0x1c,0x00,0x1d,0x00,0x1e,0x00,0x1f,0x00,0x20,0x00,0x21,0x00,0x22,0x00,0x23,0x00,0x24,0x00,0x25,0x00,0x26,0x00,0x27,0x00,0x28,0x00,0x29,0x00,0x2a,0x00,0x2b,0x00,0x2c,0x00,0x2d,0x00,0x2e,0x00,0x2f,0x00,0x30,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,0x35,0x00,0x36,0x00,0x37,0x00,0x38,0x00,0x39,0x00,0x3a,0x00,0x3b,0x00,0x3c,0x00,0x3d,0x00,0x3e,0x00,0x3f,0x00,0x40,0x00,0x41,0x00,0x42,0x00,0x43,0x00,0x44,0x00,0x45,0x00,0x46,0x00,0x47,0x00,0x48,0x00,0x49,0x00,0x4a,0x00,0x4b,0x00,0x4c,0x00,0x4d,0x00,0x4e,0x00,0x4f,0x00,0x50,0x00,0x51,0x00,0x52,0x00,0x53,0x00,0x54,0x00,0x55,0x00,0x56,0x00,0x57,0x00,0x58,0x00,0x59,0x00,0x5a,0x00,0x5b,0x00,0x5c,0x00,0x5d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x00,0x60,0x00,0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x69,0x00,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5f,0x00,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6b,0x00,0x00,0x00,0x56,0x00,0x56,0x00,0x56,0x00,0x56,0x00,0x7c,0x00,0xa4,0x01,0x34,0x01,0xda,0x02,0x4a,0x02,0xa6,0x02,0xbe,0x02,0xea,0x03,0x16,0x03,0x58,0x03,0x80,0x03,0x98,0x03,0xb0,0x03,0xc2,0x03,0xe0,0x04,0x12,0x04,0x38,0x04,0x76,0x04,0xc0,0x04,0xfa,0x05,0x48,0x05,0x8c,0x05,0xbc,0x06,0x0a,0x06,0x48,0x06,0x68,0x06,0x8c,0x06,0xb4,0x06,0xdc,0x07,0x04,0x07,0x40,0x07,0xb2,0x07,0xea,0x08,0x3c,0x08,0x72,0x08,0xae,0x08,0xde,0x09,0x08,0x09,0x52,0x09,0x8e,0x09,0xb0,0x09,0xea,0x0a,0x2c,0x0a,0x52,0x0a,0x8a,0x0a,0xb6,0x0b,0x04,0x0b,0x3c,0x0b,0x98,0x0b,0xda,0x0c,0x1c,0x0c,0x3a,0x0c,0x6e,0x0c,0x96,0x0c,0xe0,0x0d,0x1c,0x0d,0x48,0x0d,0x76,0x0d,0x98,0x0d,0xb6,0x0d,0xd8,0x0d,0xd8,0x0d,0xee,0x0e,0x0c,0x0e,0x54,0x0e,0x8e,0x0e,0xc0,0x0f,0x00,0x0f,0x3c,0x0f,0x70,0x0f,0xbc,0x0f,0xf0,0x10,0x1e,0x10,0x52,0x10,0x88,0x10,0xaa,0x10,0xfa,0x11,0x30,0x11,0x6a,0x11,0xa8,0x11,0xee,0x12,0x1a,0x12,0x56,0x12,0x90,0x12,0xc6,0x12,0xf2,0x13,0x3a,0x13,0x78,0x13,0xba,0x13,0xe4,0x14,0x0e,0x14,0x18,0x14,0x74,0x14,0xd0,0x14,0xee,0x15,0x00,0x15,0x12,0x15,0x30,0x15,0x56,0x15,0x94,0x15,0xde,0x15,0xfa,0x16,0x0e,0x16,0x36,0x16,0x5c,0x16,0xc4,0x17,0x2e,0x17,0xb6,0x00,0x00,0x00,0x04,0x00,0x64,0x00,0x00,0x03,0x9c,0x05,0x9a,0x00,0x03,0x00,0x07,0x00,0x24,0x00,0x38,0x00,0x00,0x33,0x11,0x21,0x11,0x25,0x21,0x11,0x21,0x17,0x36,0x37,0x36,0x33,0x32,0x16,0x15,0x14,0x06,0x07,0x0e,0x01,0x15,0x14,0x17,0x23,0x26,0x35,0x34,0x12,0x35,0x34,0x26,0x23,0x22,0x07,0x06,0x07,0x13,0x37,0x36,0x33,0x32,0x1f,0x01,0x16,0x15,0x14,0x0f,0x01,0x06,0x23,0x22,0x2f,0x01,0x26,0x35,0x34,0x64,0x03,0x38,0xfc,0xfa,0x02,0xd4,0xfd,0x2c,0xaf,0x1f,0x1b,0x35,0x3b,0x5c,0x70,0x2e,0x40,0x3f,0x48,0x18,0x20,0x23,0xa3,0x42,0x3a,0x26,0x1f,0x1a,0x1e,0x40,0x39,0x0b,0x09,0x0a,0x0c,0x38,0x09,0x0a,0x38,0x0e,0x07,0x0b,0x09,0x3d,0x07,0x05,0x9a,0xfa,0x66,0x32,0x05,0x36,0xec,0x1c,0x0f,0x1e,0x5f,0x50,0x31,0x63,0x50,0x50,0x68,0x2f,0x26,0x5f,0x61,0x33,0x4c,0x01,0x1c,0x4b,0x39,0x42,0x11,0x0f,0x19,0xfc,0xff,0x3a,0x0a,0x0b,0x3c,0x0b,0x09,0x0b,0x0b,0x3e,0x0e,0x0a,0x47,0x09,0x09,0x0a,0x00,0x02,0x00,0xce,0xff,0xfe,0x01,0xd2,0x06,0xc1,0x00,0x0b,0x00,0x13,0x00,0x00,0x01,0x26,0x35,0x02,0x27,0x36,0x33,0x16,0x17,0x14,0x03,0x14,0x02,0x37,0x32,0x17,0x14,0x07,0x26,0x27,0x01,0x3e,0x65,0x07,0x01,0x01,0x70,0x70,0x05,0x0a,0xde,0x76,0x83,0x0a,0x7b,0x7f,0x0a,0x02,0x03,0x19,0x5c,0x03,0x82,0x4c,0x7b,0x02,0x7c,0x50,0xfc,0x7e,0x5d,0xfe,0xeb,0x0a,0x7f,0x89,0x03,0x01,0x7a,0x00,0x00,0x02,0x00,0x64,0x05,0x0b,0x02,0x58,0x07,0x41,0x00,0x09,0x00,0x13,0x00,0x00,0x00,0x17,0x03,0x06,0x07,0x26,0x35,0x03,0x36,0x33,0x04,0x17,0x03,0x06,0x07,0x26,0x35,0x03,0x36,0x33,0x01,0x23,0x09,0x0d,0x01,0x57,0x57,0x0c,0x14,0x52,0x01,0x85,0x09,0x0d,0x01,0x57,0x57,0x0c,0x14,0x52,0x07,0x3d,0x51,0xfe,0x8a,0x6a,0x01,0x01,0x6f,0x01,0x75,0x51,0x04,0x51,0xfe,0x8a,0x6a,0x01,0x01,0x6f,0x01,0x75,0x51,0x00,0x00,0x02,0x00,0x41,0xff,0xf8,0x04,0xbb,0x06,0x5c,0x00,0x09,0x00,0x5a,0x00,0x00,0x01,0x06,0x07,0x06,0x07,0x36,0x37,0x13,0x36,0x37,0x05,0x07,0x26,0x27,0x36,0x37,0x32,0x37,0x32,0x37,0x36,0x37,0x36,0x33,0x16,0x17,0x06,0x07,0x36,0x37,0x36,0x37,0x36,0x33,0x16,0x17,0x06,0x07,0x16,0x33,0x16,0x17,0x06,0x07,0x06,0x07,0x26,0x27,0x26,0x27,0x06,0x07,0x06,0x07,0x16,0x33,0x16,0x17,0x06,0x07,0x06,0x07,0x26,0x27,0x26,0x23,0x02,0x07,0x26,0x35,0x36,0x13,0x07,0x02,0x07,0x26,0x35,0x34,0x13,0x07,0x26,0x27,0x36,0x37,0x32,0x37,0x36,0x37,0x13,0x36,0x37,0x02,0x5b,0x16,0x1b,0x17,0x16,0x4b,0x5b,0x5c,0x06,0x06,0xfe,0x5d,0x6a,0x46,0x04,0x0e,0x3d,0x23,0x68,0x1f,0x26,0x25,0x16,0x22,0x36,0x45,0x08,0x02,0x2f,0x50,0x61,0x23,0x16,0x22,0x35,0x45,0x08,0x02,0x2e,0x77,0x1d,0x3d,0x0e,0x02,0x1c,0x0c,0x1d,0x0f,0x10,0x73,0x28,0x16,0x1d,0x16,0x15,0x7a,0x22,0x3d,0x0e,0x02,0x11,0x08,0x27,0x13,0x14,0x76,0x2e,0x75,0x5f,0x52,0x01,0x5f,0x9a,0x74,0x5e,0x51,0x5b,0x83,0x46,0x04,0x0e,0x3d,0x29,0x8d,0x01,0x01,0x5e,0x05,0x05,0x04,0x37,0x68,0x7e,0x75,0x65,0x01,0x02,0x01,0x89,0x1b,0x1b,0x0c,0x08,0x0c,0x51,0x50,0x04,0x02,0x01,0xb2,0x98,0x39,0x04,0x60,0x33,0xe8,0x02,0x02,0xaa,0x93,0x39,0x03,0x61,0x32,0xe2,0x04,0x04,0x50,0x32,0x18,0x12,0x06,0x04,0x03,0x0f,0x01,0x6b,0x85,0x70,0x62,0x03,0x04,0x50,0x26,0x17,0x1f,0x07,0x05,0x03,0x0e,0xfe,0x23,0x01,0x03,0x4c,0x4b,0x01,0x41,0x03,0xfe,0x2e,0x01,0x02,0x4c,0x4b,0x01,0x33,0x09,0x0b,0x52,0x4f,0x04,0x03,0x03,0x04,0x01,0x8d,0x16,0x15,0x00,0x00,0x05,0x00,0x45,0xfe,0xc4,0x04,0xa5,0x07,0x56,0x00,0x44,0x00,0x4b,0x00,0x52,0x00,0x5c,0x00,0x67,0x00,0x00,0x01,0x36,0x37,0x32,0x17,0x11,0x36,0x37,0x16,0x17,0x11,0x16,0x17,0x16,0x15,0x14,0x07,0x06,0x23,0x22,0x27,0x26,0x27,0x11,0x16,0x17,0x16,0x15,0x02,0x05,0x11,0x06,0x07,0x26,0x27,0x11,0x06,0x07,0x23,0x26,0x27,0x11,0x06,0x07,0x26,0x27,0x11,0x26,0x27,0x26,0x35,0x37,0x36,0x33,0x32,0x17,0x16,0x17,0x11,0x24,0x03,0x37,0x12,0x25,0x11,0x36,0x37,0x16,0x17,0x01,0x36,0x37,0x36,0x35,0x34,0x27,0x01,0x06,0x07,0x06,0x15,0x14,0x17,0x05,0x26,0x27,0x26,0x27,0x11,0x16,0x17,0x36,0x37,0x11,0x26,0x2b,0x01,0x06,0x07,0x11,0x16,0x17,0x16,0x17,0x02,0x2a,0x1c,0x1e,0x45,0x31,0x01,0x47,0x47,0x01,0x66,0x3c,0x62,0x08,0x11,0x1d,0x2e,0x4a,0x22,0x34,0x91,0x3c,0x6e,0x0b,0xfe,0xd0,0x01,0x47,0x47,0x01,0x14,0x21,0x49,0x19,0x19,0x01,0x3d,0x51,0x01,0x55,0x5c,0xa4,0x11,0x14,0x15,0x44,0x51,0x39,0x4d,0xfe,0xe5,0x14,0x02,0x18,0x01,0x15,0x01,0x51,0x3d,0x01,0x01,0x40,0x90,0x0e,0x01,0x9f,0xfe,0x30,0x83,0x03,0x05,0x8b,0x01,0x40,0x3d,0x5a,0x0d,0x0c,0x26,0x2a,0x39,0x27,0x2e,0x40,0x03,0x21,0x1e,0x12,0x14,0x50,0x3a,0x06,0x0f,0x02,0x02,0x09,0x01,0x09,0x42,0x01,0x01,0x43,0xfe,0xd9,0x22,0x3f,0x69,0x48,0x14,0x12,0x20,0x54,0x27,0x1c,0xfe,0x69,0x27,0x49,0x86,0xd4,0xfe,0xcc,0x5d,0xfe,0xcd,0x40,0x01,0x01,0x44,0x01,0x13,0x04,0x03,0x01,0x03,0xfe,0xec,0x40,0x01,0x01,0x44,0x01,0x2f,0x29,0x5a,0x9f,0xae,0x17,0x0e,0x96,0x68,0x35,0x02,0x15,0x41,0x01,0x14,0x2b,0x01,0x1e,0x4c,0x01,0x1a,0x42,0x01,0x01,0x43,0xf9,0xe3,0x3f,0x8a,0x09,0x09,0xa3,0x4b,0x02,0x83,0x3c,0x7a,0x14,0x12,0x6c,0x28,0xe9,0x10,0x04,0x01,0x01,0xfd,0xcf,0x07,0x03,0x03,0x09,0x04,0x90,0x0e,0x04,0x06,0xfe,0x5b,0x02,0x01,0x04,0x0a,0x00,0x00,0x05,0x00,0x20,0xff,0xeb,0x06,0x76,0x06,0x25,0x00,0x0d,0x00,0x19,0x00,0x27,0x00,0x33,0x00,0x41,0x00,0x00,0x01,0x17,0x1e,0x01,0x17,0x14,0x06,0x07,0x27,0x2e,0x01,0x27,0x3e,0x01,0x03,0x16,0x1f,0x01,0x36,0x3f,0x01,0x34,0x26,0x27,0x23,0x06,0x01,0x17,0x1e,0x01,0x17,0x14,0x06,0x07,0x27,0x2e,0x01,0x27,0x3e,0x01,0x03,0x16,0x1f,0x01,0x36,0x3f,0x01,0x34,0x26,0x27,0x23,0x06,0x00,0x37,0x32,0x17,0x14,0x07,0x01,0x06,0x07,0x26,0x27,0x36,0x37,0x01,0x01,0x82,0x2e,0x7d,0xe1,0x1a,0xc0,0xb8,0x22,0xa1,0xc8,0x05,0x09,0xae,0x28,0x0c,0xc4,0x2b,0xb3,0x2a,0x05,0x93,0x63,0x1c,0xb4,0x04,0x0a,0x2d,0x7e,0xe1,0x1a,0xc1,0xb8,0x21,0xa1,0xc8,0x05,0x08,0xae,0x28,0x0d,0xc4,0x2a,0xb4,0x2a,0x05,0x93,0x63,0x1c,0xb4,0x01,0x96,0x3d,0x27,0x13,0x32,0xfb,0x52,0x44,0x39,0x32,0x0b,0x07,0x3e,0x04,0xbd,0x06,0x25,0x02,0x08,0xbc,0xbd,0xb6,0xc9,0x0d,0x05,0x11,0xd3,0xc1,0x95,0xc6,0xfe,0x99,0xd3,0x3a,0x06,0x12,0xac,0x1b,0x77,0x99,0x0a,0x18,0xfd,0xa7,0x01,0x08,0xbd,0xbd,0xb6,0xc9,0x0c,0x04,0x11,0xd3,0xc1,0x95,0xc7,0xfe,0x98,0xd3,0x39,0x07,0x12,0xac,0x1c,0x77,0x99,0x09,0x17,0x03,0x94,0x03,0x3d,0x43,0x2a,0xfa,0xd1,0x45,0x09,0x09,0x50,0x3d,0x34,0x05,0x37,0x00,0x03,0x00,0x92,0xff,0xf7,0x06,0xa0,0x07,0x4a,0x00,0x21,0x00,0x29,0x00,0x31,0x00,0x00,0x24,0x17,0x06,0x07,0x26,0x2f,0x01,0x06,0x05,0x23,0x24,0x03,0x35,0x12,0x01,0x26,0x35,0x36,0x25,0x33,0x04,0x13,0x06,0x07,0x16,0x13,0x36,0x13,0x34,0x37,0x16,0x15,0x02,0x07,0x01,0x06,0x07,0x16,0x17,0x36,0x37,0x34,0x03,0x04,0x03,0x12,0x05,0x36,0x37,0x02,0x06,0x46,0x14,0x03,0x70,0x50,0x2b,0x2a,0xc3,0xfe,0xcf,0x5b,0xfd,0xb4,0x15,0x11,0x01,0x89,0xd0,0x1f,0x01,0x51,0x4c,0x01,0x32,0x09,0x0a,0xbc,0xfe,0xec,0x44,0x22,0x63,0x60,0x15,0x9e,0xfc,0xf6,0xaa,0x05,0x2f,0x85,0x69,0x3b,0xae,0xfe,0x9b,0x0f,0x16,0x01,0x95,0xef,0xde,0xb2,0xb5,0x4f,0x6d,0x01,0x15,0x5f,0x61,0xbc,0x1a,0x12,0x01,0xee,0x52,0x01,0x67,0x01,0x23,0x82,0xf1,0xf6,0x0e,0x0c,0xfe,0xd3,0xc5,0x9b,0xaf,0xfe,0x4d,0x6f,0x01,0x18,0x76,0x04,0x04,0x86,0xfe,0xa0,0xfe,0x05,0x1b,0x03,0x83,0x82,0x32,0x28,0x88,0x8a,0xfd,0xaa,0xdc,0xfe,0xca,0xfe,0xb9,0x05,0x01,0xbf,0x01,0x9a,0x00,0x00,0x00,0x01,0x00,0x64,0x05,0x0b,0x01,0x2c,0x07,0x41,0x00,0x09,0x00,0x00,0x00,0x17,0x03,0x06,0x07,0x26,0x35,0x03,0x36,0x33,0x01,0x23,0x09,0x0d,0x01,0x57,0x57,0x0c,0x14,0x52,0x07,0x3d,0x51,0xfe,0x8a,0x6a,0x01,0x01,0x6f,0x01,0x75,0x51,0x00,0x00,0x00,0x01,0x00,0x7d,0xfe,0x74,0x02,0x89,0x08,0x05,0x00,0x15,0x00,0x00,0x00,0x37,0x16,0x17,0x06,0x07,0x02,0x03,0x10,0x13,0x16,0x17,0x06,0x07,0x22,0x27,0x26,0x27,0x02,0x03,0x12,0x13,0x01,0xa6,0x7c,0x53,0x09,0x12,0x5c,0xc0,0x0d,0xc4,0x5b,0x27,0x01,0x4f,0x5a,0x30,0x3e,0x32,0xc1,0x01,0x0c,0xcb,0x08,0x01,0x04,0x15,0x65,0x62,0x8f,0xfe,0xd9,0xfe,0x17,0xfe,0x1d,0xfe,0x6a,0xa6,0x7c,0x73,0x08,0x3e,0x55,0x83,0x02,0x0a,0x01,0xdb,0x02,0x06,0x01,0xa3,0x00,0x01,0x00,0x51,0xfe,0x74,0x02,0x62,0x08,0x0a,0x00,0x15,0x00,0x00,0x12,0x27,0x34,0x37,0x16,0x17,0x12,0x13,0x02,0x03,0x06,0x07,0x06,0x07,0x22,0x27,0x36,0x37,0x12,0x13,0x02,0x03,0x81,0x1a,0x62,0x5b,0x4d,0xf0,0x01,0x01,0xb4,0x46,0x44,0x2e,0x44,0x59,0x07,0x0a,0x66,0xda,0x02,0x0a,0xb5,0x07,0x0e,0x7f,0x73,0x0a,0x0a,0xab,0xfe,0x5f,0xfd,0xa6,0xfe,0x1e,0xfe,0x35,0xaf,0x4d,0x35,0x08,0x6b,0x55,0x8a,0x01,0xbf,0x01,0xf8,0x01,0xce,0x01,0x50,0x00,0x00,0x01,0x00,0x4c,0x03,0xe6,0x02,0xe1,0x06,0xf3,0x00,0x27,0x00,0x00,0x01,0x26,0x35,0x36,0x33,0x32,0x17,0x14,0x07,0x36,0x37,0x16,0x15,0x06,0x07,0x16,0x17,0x06,0x07,0x26,0x27,0x16,0x15,0x06,0x07,0x26,0x27,0x36,0x37,0x06,0x07,0x26,0x27,0x36,0x37,0x26,0x27,0x36,0x37,0x16,0x01,0x64,0x1b,0x1c,0x30,0x30,0x1d,0x18,0x74,0x74,0x2c,0x21,0xab,0xc8,0x07,0x07,0x2c,0x50,0x88,0x12,0x09,0x40,0x49,0x09,0x01,0x12,0x7b,0x43,0x45,0x04,0x05,0xc7,0xbf,0x1a,0x01,0x3a,0x57,0x05,0xd9,0x84,0x4f,0x47,0x48,0x47,0x90,0xae,0x02,0x0d,0x3f,0x6c,0x50,0x53,0x5c,0x33,0x0e,0x08,0x76,0x7e,0x5b,0x48,0x03,0x0f,0x55,0x41,0x83,0x75,0x07,0x06,0x3d,0x43,0x69,0x4a,0x6e,0x3e,0x10,0x01,0x00,0x00,0x00,0x01,0x00,0xc0,0x00,0xc7,0x03,0xf3,0x03,0xed,0x00,0x17,0x00,0x00,0x01,0x33,0x16,0x17,0x06,0x07,0x23,0x15,0x06,0x07,0x26,0x3d,0x01,0x23,0x26,0x27,0x36,0x3b,0x01,0x35,0x36,0x37,0x16,0x17,0x02,0xc7,0x9b,0x84,0x0d,0x07,0x82,0xa2,0x06,0x68,0x5c,0xaf,0x8b,0x04,0x08,0x89,0xac,0x01,0x5d,0x60,0x0c,0x02,0xc9,0x01,0x5d,0x60,0x0c,0xab,0x89,0x04,0x08,0x86,0xa9,0x06,0x68,0x5c,0x97,0x81,0x0d,0x07,0x80,0x00,0x00,0x01,0x00,0x9e,0xfe,0xf1,0x01,0x66,0x00,0xe1,0x00,0x09,0x00,0x00,0x24,0x17,0x03,0x06,0x07,0x26,0x35,0x03,0x36,0x33,0x01,0x5d,0x09,0x0d,0x01,0x57,0x57,0x0c,0x14,0x52,0xdd,0x51,0xfe,0xd0,0x6a,0x01,0x01,0x6f,0x01,0x2f,0x51,0x00,0x00,0x00,0x00,0x01,0x00,0x14,0x02,0x63,0x02,0xe4,0x03,0x2e,0x00,0x09,0x00,0x00,0x00,0x17,0x06,0x07,0x05,0x26,0x27,0x36,0x33,0x25,0x02,0xd8,0x0c,0x06,0x72,0xfe,0x26,0x7a,0x04,0x07,0x78,0x01,0xd2,0x03,0x2d,0x5d,0x60,0x0c,0x01,0x06,0x68,0x5c,0x01,0x00,0x00,0x01,0x00,0x9e,0xff,0xfe,0x01,0xa2,0x01,0x09,0x00,0x07,0x00,0x00,0x36,0x37,0x32,0x17,0x14,0x07,0x26,0x27,0x9f,0x76,0x83,0x0a,0x7b,0x7f,0x0a,0xff,0x0a,0x7f,0x89,0x03,0x01,0x7a,0x00,0x01,0xff,0xf7,0xff,0xe0,0x03,0x38,0x07,0x4f,0x00,0x0d,0x00,0x00,0x01,0x16,0x17,0x06,0x07,0x01,0x06,0x23,0x26,0x27,0x34,0x37,0x01,0x36,0x02,0xf5,0x42,0x01,0x06,0x1c,0xfd,0x80,0x1f,0x3a,0x40,0x06,0x25,0x02,0x80,0x13,0x07,0x4f,0x05,0x61,0x3c,0x36,0xf9,0xbe,0x55,0x04,0x44,0x2c,0x56,0x06,0x43,0x58,0x00,0x02,0x00,0x0d,0xff,0xf1,0x04,0x64,0x05,0xca,0x00,0x0b,0x00,0x15,0x00,0x00,0x01,0x17,0x04,0x13,0x17,0x02,0x05,0x27,0x24,0x03,0x27,0x12,0x13,0x12,0x05,0x20,0x13,0x27,0x02,0x25,0x04,0x03,0x02,0x38,0x44,0x01,0x92,0x50,0x06,0x22,0xfd,0xdb,0x43,0xfe,0x77,0x36,0x0e,0x0f,0xad,0x11,0x01,0x11,0x01,0x9e,0x24,0x05,0x34,0xfe,0xd7,0xfe,0xb4,0x3a,0x05,0xca,0x03,0x37,0xfd,0xf2,0x88,0xfd,0x0e,0x17,0x03,0x64,0x01,0xae,0x85,0x03,0x18,0xfc,0xee,0xfe,0x67,0x4a,0x02,0x33,0x6b,0x01,0xb4,0x12,0x15,0xfd,0xe6,0x00,0x00,0x01,0x00,0xa9,0x00,0x00,0x03,0x13,0x05,0xc1,0x00,0x12,0x00,0x00,0x00,0x17,0x02,0x03,0x06,0x23,0x26,0x27,0x12,0x11,0x06,0x07,0x26,0x27,0x34,0x3f,0x01,0x36,0x33,0x02,0xfe,0x15,0x05,0x15,0x09,0x5e,0x57,0x11,0x23,0xe3,0x66,0x48,0x13,0x2f,0xe4,0x8b,0x59,0x05,0xb7,0x40,0xfe,0x08,0xfc,0xc4,0x43,0x03,0x3e,0x03,0x3d,0x01,0x51,0xf9,0x0c,0x07,0x3d,0x48,0x25,0xba,0x8c,0x00,0x00,0x00,0x00,0x01,0x00,0x28,0xff,0xf6,0x04,0x48,0x05,0xb7,0x00,0x20,0x00,0x00,0x01,0x04,0x13,0x14,0x02,0x05,0x25,0x32,0x16,0x17,0x14,0x23,0x26,0x27,0x04,0x07,0x26,0x35,0x36,0x25,0x24,0x11,0x02,0x25,0x04,0x03,0x06,0x23,0x22,0x27,0x37,0x12,0x25,0x02,0x5c,0x01,0x9b,0x35,0xfa,0xfe,0x7c,0x01,0x0e,0x91,0xf5,0x06,0x6f,0x44,0xd5,0xfe,0x69,0x6f,0x67,0x01,0x01,0x83,0x01,0x92,0x18,0xfe,0xed,0xfe,0xea,0x3a,0x0a,0x5d,0x5e,0x01,0x02,0x44,0x01,0x9a,0x05,0xb7,0x2b,0xfe,0x62,0xe5,0xfe,0xb2,0xe9,0x12,0x30,0x62,0x57,0x19,0x0c,0x11,0x19,0x0a,0x61,0x7e,0xfc,0xe7,0x01,0x1f,0x01,0x09,0x19,0x0a,0xfe,0xf8,0x74,0x6a,0x1f,0x01,0x83,0x2e,0x00,0x00,0x00,0x01,0x00,0x20,0xff,0xf7,0x04,0x57,0x05,0xc5,0x00,0x27,0x00,0x00,0x01,0x04,0x1f,0x01,0x06,0x07,0x04,0x13,0x02,0x05,0x24,0x03,0x36,0x33,0x32,0x12,0x17,0x24,0x37,0x02,0x25,0x06,0x07,0x26,0x35,0x36,0x37,0x36,0x35,0x26,0x27,0x04,0x07,0x14,0x07,0x26,0x27,0x37,0x12,0x25,0x02,0x69,0x01,0x1c,0x3d,0x0a,0x08,0x87,0x01,0x15,0x05,0x33,0xfe,0x16,0xfe,0x00,0x1a,0x0e,0x54,0x42,0x62,0xfb,0x01,0x49,0x23,0x13,0xfe,0xfd,0x5e,0x6c,0x61,0x0b,0xd0,0xcb,0x11,0x86,0xfe,0xbd,0x32,0x5e,0x4c,0x09,0x01,0x49,0x01,0x8f,0x05,0xc5,0x18,0xee,0x3c,0x9e,0x74,0x55,0xfe,0xab,0xfe,0x5d,0x2d,0x04,0x01,0x98,0x47,0xfe,0xfe,0x14,0x0e,0xfb,0x01,0x14,0x0e,0x07,0x07,0x14,0x54,0x5d,0x19,0x18,0xc1,0x72,0x07,0x07,0xc7,0x46,0x0a,0x14,0x55,0x32,0x01,0x20,0x15,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xf6,0x04,0x6a,0x05,0xc8,0x00,0x17,0x00,0x1d,0x00,0x00,0x01,0x32,0x17,0x02,0x03,0x37,0x16,0x17,0x06,0x23,0x27,0x13,0x06,0x23,0x26,0x27,0x37,0x04,0x05,0x26,0x3d,0x01,0x12,0x00,0x17,0x00,0x03,0x36,0x37,0x12,0x02,0xe4,0x80,0x14,0x03,0x23,0xa4,0x60,0x14,0x0b,0x49,0xc4,0x05,0x10,0x56,0x54,0x0a,0x09,0xfe,0xe4,0xfe,0xe3,0x63,0x25,0x02,0x74,0x2b,0xfe,0x18,0x09,0xd4,0xf8,0x22,0x05,0xc8,0x6b,0xfe,0x7b,0xfe,0x1f,0x0b,0x09,0x5e,0x6c,0x08,0xff,0x00,0x41,0x07,0x5d,0xd4,0x02,0x35,0x0f,0x88,0x2a,0x01,0x2d,0x02,0xe3,0xed,0xfe,0x00,0xfe,0xe9,0x2d,0x02,0x01,0xf1,0x00,0x00,0x01,0x00,0x35,0xff,0xf2,0x04,0x46,0x05,0xc1,0x00,0x2c,0x00,0x00,0x01,0x36,0x37,0x32,0x17,0x0e,0x01,0x07,0x25,0x06,0x07,0x17,0x3e,0x01,0x37,0x16,0x12,0x1d,0x01,0x02,0x05,0x07,0x22,0x00,0x35,0x36,0x37,0x32,0x17,0x16,0x17,0x36,0x13,0x37,0x02,0x27,0x0e,0x01,0x07,0x22,0x27,0x12,0x3f,0x01,0x16,0x02,0x52,0x8f,0x7a,0x58,0x08,0x01,0x8b,0xd5,0xfe,0xf9,0x56,0x02,0x0d,0x52,0xc7,0x87,0xe0,0xbe,0x28,0xfe,0x97,0x87,0xd2,0xfe,0xd9,0x07,0x4a,0x49,0x35,0x6b,0xe9,0xff,0x2f,0x04,0x0f,0xe9,0x71,0xe8,0x5c,0x8a,0x14,0x22,0x93,0x21,0x6d,0x05,0xa5,0x08,0x14,0x52,0x51,0x2c,0x06,0x05,0x8d,0x6f,0x0f,0x0c,0x37,0x0a,0x06,0xfe,0xdc,0xba,0x4d,0xfe,0x23,0x2d,0x06,0x01,0x03,0x76,0x41,0x0a,0x59,0xa6,0x01,0x0a,0x01,0x2c,0x69,0x01,0x0c,0x0f,0x0d,0x3f,0x04,0xae,0x01,0x3a,0xaa,0x07,0x10,0x00,0x00,0x00,0x00,0x02,0x00,0x0a,0x00,0x00,0x04,0x66,0x05,0xb8,0x00,0x19,0x00,0x23,0x00,0x00,0x01,0x17,0x16,0x17,0x06,0x07,0x2e,0x01,0x27,0x06,0x02,0x07,0x36,0x37,0x33,0x04,0x13,0x07,0x02,0x05,0x24,0x03,0x35,0x10,0x37,0x36,0x03,0x15,0x12,0x05,0x33,0x24,0x13,0x10,0x25,0x04,0x02,0x40,0x3c,0xf7,0x11,0x0c,0x55,0x5a,0x41,0x41,0x94,0xdc,0x0e,0x8b,0xf2,0x21,0x01,0xd5,0x2a,0x01,0x1f,0xfe,0x1e,0xfd,0xb8,0x12,0x96,0xcb,0x9d,0x22,0x01,0x53,0x26,0x01,0x36,0x0a,0xfe,0xc3,0xfe,0xbb,0x05,0xb8,0x01,0x20,0x74,0x52,0x06,0x0a,0x24,0x10,0x0e,0xfe,0xdf,0x9a,0xa8,0x12,0x1f,0xfe,0x70,0x6b,0xfe,0x76,0x56,0x06,0x02,0x55,0x4a,0x01,0x39,0xdd,0xfc,0xfc,0x6c,0x37,0xfe,0xdd,0x0a,0x4c,0x01,0x0f,0x01,0x05,0x26,0x25,0x00,0x01,0x00,0x1a,0xff,0xfb,0x04,0x4d,0x05,0xc0,0x00,0x19,0x00,0x00,0x01,0x16,0x17,0x14,0x07,0x00,0x03,0x15,0x06,0x23,0x22,0x35,0x37,0x12,0x25,0x06,0x07,0x27,0x26,0x27,0x34,0x37,0x16,0x17,0x36,0x24,0x03,0xc4,0x7f,0x0a,0x3b,0xfe,0x42,0x10,0x12,0x5a,0x69,0x01,0x4e,0x01,0x3a,0x77,0xe7,0x91,0xe7,0x08,0x66,0xcc,0x70,0x5e,0x01,0x39,0x05,0xc0,0x0a,0x53,0x3f,0x28,0xfe,0xc5,0xfd,0xa6,0xf0,0x7c,0x85,0xf0,0x02,0x91,0xfc,0x2b,0x0d,0x0d,0x14,0x63,0x5c,0x0d,0x21,0x04,0x06,0x2d,0x00,0x00,0x00,0x03,0x00,0x11,0xff,0xef,0x04,0x61,0x05,0xd6,0x00,0x15,0x00,0x1d,0x00,0x27,0x00,0x00,0x01,0x33,0x04,0x13,0x17,0x06,0x07,0x04,0x13,0x15,0x02,0x05,0x27,0x24,0x03,0x35,0x12,0x37,0x26,0x27,0x37,0x12,0x13,0x16,0x17,0x36,0x37,0x26,0x27,0x06,0x02,0x07,0x16,0x05,0x37,0x24,0x13,0x26,0x25,0x07,0x02,0x2d,0x2a,0x01,0x23,0x3b,0x01,0x09,0x7b,0x01,0x16,0x19,0x25,0xfe,0x13,0x60,0xfe,0x4d,0x2b,0x10,0xcd,0x67,0x0a,0x04,0x2d,0x92,0x05,0xbd,0xe7,0x11,0x1a,0x8c,0xfb,0x87,0x07,0x01,0x01,0x46,0x34,0x01,0x51,0x06,0x1b,0xfe,0x9d,0x51,0x05,0xd6,0x01,0xfe,0xff,0x2d,0xd0,0x55,0x3e,0xfe,0xeb,0x37,0xfe,0x11,0x1a,0x02,0x16,0x01,0x6d,0x3c,0x01,0x17,0x8a,0x66,0x98,0x29,0x01,0x33,0xfe,0xb8,0xae,0x04,0x29,0xc1,0x8c,0x08,0x0c,0xfd,0x6a,0xf5,0xc9,0x2a,0x01,0x32,0x01,0x34,0xd4,0x11,0x0d,0x00,0x00,0x00,0x00,0x02,0x00,0x21,0xff,0xfe,0x04,0x53,0x05,0xc1,0x00,0x13,0x00,0x1e,0x00,0x00,0x01,0x04,0x13,0x02,0x05,0x27,0x26,0x35,0x34,0x24,0x00,0x13,0x27,0x02,0x05,0x24,0x03,0x10,0x37,0x36,0x03,0x16,0x17,0x20,0x13,0x27,0x2e,0x01,0x23,0x07,0x06,0x02,0x08,0x02,0x26,0x25,0x20,0xfd,0x3b,0x4d,0x42,0x01,0xa3,0x01,0x28,0x04,0x0f,0x57,0xfe,0x6c,0xfe,0x97,0x2a,0xb2,0x7d,0x84,0x10,0xc2,0x01,0x5c,0x34,0x06,0x11,0x9b,0x8c,0x2e,0xf6,0x05,0xc1,0x27,0xfd,0x21,0xfd,0x53,0x10,0x02,0x13,0x35,0x75,0x01,0x01,0x04,0x01,0x13,0x5f,0xfe,0xa1,0x0a,0x17,0x01,0x83,0x01,0x38,0xb2,0x72,0xfd,0xa6,0xd5,0x14,0x01,0x76,0x59,0x48,0x80,0x0b,0x46,0x00,0x00,0x00,0x02,0x00,0x9e,0xff,0xfe,0x01,0xa2,0x04,0x87,0x00,0x07,0x00,0x0f,0x00,0x00,0x36,0x37,0x32,0x17,0x14,0x07,0x26,0x27,0x12,0x37,0x32,0x17,0x14,0x07,0x26,0x27,0x9f,0x76,0x83,0x0a,0x7b,0x7f,0x0a,0x01,0x76,0x83,0x0a,0x7b,0x7f,0x0a,0xff,0x0a,0x7f,0x89,0x03,0x01,0x7a,0x04,0x04,0x0a,0x7f,0x89,0x03,0x01,0x7a,0x00,0x00,0x00,0x00,0x02,0x00,0x9e,0xff,0x08,0x01,0xa2,0x04,0x87,0x00,0x07,0x00,0x11,0x00,0x00,0x12,0x37,0x32,0x17,0x14,0x07,0x26,0x27,0x12,0x17,0x03,0x06,0x07,0x26,0x35,0x03,0x36,0x33,0x9f,0x76,0x83,0x0a,0x7b,0x7f,0x0a,0xdc,0x09,0x0d,0x01,0x57,0x57,0x0c,0x14,0x52,0x04,0x7d,0x0a,0x7f,0x89,0x03,0x01,0x7a,0xfc,0xfd,0x51,0xfe,0xd0,0x6a,0x01,0x01,0x6f,0x01,0x2f,0x51,0x00,0x00,0x00,0x01,0x00,0xc9,0x00,0x91,0x04,0x07,0x04,0x84,0x00,0x13,0x00,0x00,0x09,0x01,0x16,0x17,0x14,0x07,0x22,0x27,0x01,0x26,0x27,0x36,0x37,0x01,0x36,0x33,0x16,0x15,0x06,0x07,0x01,0xf6,0x01,0xc1,0x4e,0x02,0x46,0x3c,0x36,0xfd,0xd8,0x5b,0x03,0x03,0x5b,0x02,0x28,0x36,0x3c,0x46,0x02,0x4e,0x02,0x8b,0xfe,0xd6,0x27,0x4a,0x43,0x1c,0x20,0x01,0x56,0x1f,0x63,0x66,0x1f,0x01,0x56,0x20,0x1c,0x43,0x4a,0x27,0x00,0x00,0x00,0x02,0x00,0xc0,0x01,0x69,0x04,0x12,0x03,0x8b,0x00,0x09,0x00,0x13,0x00,0x00,0x00,0x17,0x06,0x07,0x05,0x26,0x27,0x36,0x33,0x25,0x12,0x17,0x06,0x07,0x21,0x26,0x27,0x36,0x33,0x25,0x04,0x04,0x0e,0x07,0x6c,0xfd,0x9b,0x75,0x05,0x08,0x73,0x02,0x5c,0x6d,0x0e,0x07,0x6c,0xfd,0x9b,0x75,0x05,0x08,0x73,0x02,0x5c,0x02,0x38,0x5e,0x62,0x0e,0x01,0x07,0x6b,0x5d,0x01,0x01,0x51,0x5f,0x62,0x0d,0x05,0x6b,0x5e,0x01,0x00,0x01,0x00,0xc9,0x00,0x91,0x04,0x07,0x04,0x84,0x00,0x13,0x00,0x00,0x01,0x26,0x27,0x34,0x37,0x32,0x17,0x01,0x16,0x17,0x06,0x07,0x01,0x06,0x23,0x26,0x35,0x36,0x37,0x01,0x01,0x19,0x4e,0x02,0x46,0x3c,0x36,0x02,0x28,0x5b,0x03,0x03,0x5b,0xfd,0xd8,0x36,0x3c,0x46,0x02,0x4e,0x01,0xc1,0x03,0xb4,0x27,0x4a,0x43,0x1c,0x20,0xfe,0xaa,0x1f,0x66,0x63,0x1f,0xfe,0xaa,0x20,0x1c,0x43,0x4a,0x27,0x01,0x2a,0x00,0x00,0x00,0x02,0x00,0xbc,0xff,0xff,0x03,0xca,0x07,0x4f,0x00,0x19,0x00,0x21,0x00,0x00,0x01,0x37,0x04,0x13,0x10,0x05,0x06,0x0f,0x01,0x06,0x23,0x26,0x35,0x34,0x37,0x36,0x35,0x34,0x27,0x0e,0x01,0x07,0x26,0x27,0x37,0x36,0x12,0x33,0x16,0x17,0x06,0x07,0x26,0x27,0x01,0xcf,0x79,0x01,0x74,0x0e,0xfe,0xb4,0x59,0x0a,0x01,0x15,0x61,0x63,0xbb,0xf9,0xe4,0x55,0x54,0x45,0x4c,0x1b,0x04,0x22,0x56,0x7b,0x63,0x1b,0x04,0x75,0x90,0x01,0x07,0x43,0x0c,0x14,0xfe,0x9a,0xfe,0xf5,0xe1,0x40,0x81,0xba,0x57,0x11,0xd7,0xf8,0x92,0x9e,0x9d,0xaa,0x09,0x0d,0x50,0x05,0x06,0x5d,0x2a,0x6b,0xfa,0x02,0x11,0x61,0x91,0x0d,0x19,0x8a,0x00,0x00,0x00,0x02,0x00,0x40,0x00,0x1e,0x06,0x10,0x05,0xa4,0x00,0x08,0x00,0x3d,0x00,0x00,0x01,0x14,0x17,0x36,0x13,0x27,0x37,0x06,0x08,0x01,0x05,0x26,0x2f,0x01,0x02,0x05,0x20,0x03,0x35,0x12,0x25,0x32,0x15,0x14,0x07,0x17,0x07,0x12,0x17,0x36,0x13,0x02,0x25,0x23,0x04,0x00,0x0f,0x01,0x12,0x05,0x36,0x37,0x17,0x16,0x17,0x16,0x17,0x06,0x07,0x26,0x27,0x05,0x24,0x03,0x27,0x12,0x00,0x25,0x37,0x04,0x13,0x17,0x01,0xcc,0x7e,0xe6,0xbd,0x04,0x04,0xe1,0xfe,0xd0,0x04,0x16,0xfe,0xfc,0xad,0x17,0x16,0xab,0xfe,0xf8,0xfe,0xe7,0x0b,0x3b,0x02,0x8c,0x91,0x0f,0x0f,0x02,0x09,0x56,0x7e,0x04,0x56,0xfe,0xf9,0x7e,0xfe,0xc9,0xfe,0x89,0x07,0x03,0x3a,0x01,0x3a,0xf1,0x77,0x66,0x95,0x98,0x2d,0x09,0x0e,0x54,0x8c,0x87,0xfe,0x43,0xfe,0x33,0x42,0x05,0x0d,0x01,0xd7,0x01,0x9b,0x4f,0x01,0x93,0x63,0x0c,0x02,0x64,0x94,0x16,0x05,0x01,0x54,0xc2,0x61,0x0b,0xfe,0xfc,0xfd,0xf8,0x08,0x0e,0xa9,0x82,0xfe,0xd4,0x04,0x01,0x20,0x47,0x02,0x1e,0x2b,0x4b,0x1f,0x17,0x81,0xcf,0xfe,0xb8,0x0b,0x38,0x01,0x50,0x01,0xd6,0x0c,0x10,0xfe,0x5c,0xd8,0x60,0xfe,0xb8,0x19,0x0a,0x05,0x04,0x07,0x16,0x0d,0x34,0x51,0x07,0x1e,0x0a,0x08,0x0d,0x01,0xb9,0x61,0x01,0x53,0x01,0xe0,0x0a,0x02,0x1c,0xfe,0x0a,0xa5,0x00,0x00,0x02,0x00,0x45,0xff,0xfc,0x06,0x62,0x07,0x4a,0x00,0x15,0x00,0x1c,0x00,0x00,0x01,0x04,0x00,0x13,0x11,0x14,0x23,0x22,0x35,0x11,0x21,0x11,0x14,0x07,0x26,0x27,0x11,0x36,0x37,0x16,0x15,0x12,0x03,0x21,0x26,0x00,0x21,0x20,0x00,0x03,0x81,0x01,0x77,0x01,0x67,0x03,0x5d,0x6e,0xfb,0x7d,0x67,0x67,0x01,0x04,0x60,0x6a,0xdc,0xbc,0x04,0x58,0x01,0xfe,0xff,0xfe,0xf3,0xfe,0xfb,0xfe,0xbc,0x07,0x4a,0x06,0xfe,0x13,0xfe,0x6a,0xfc,0x9f,0x64,0x62,0x02,0xff,0xfd,0x0d,0x6c,0x01,0x02,0x6b,0x05,0xb8,0x6c,0x01,0x01,0x90,0x01,0x4c,0xfc,0xd5,0xce,0x01,0x91,0xfe,0x64,0x00,0x00,0x00,0x00,0x02,0x00,0x57,0xff,0xf0,0x06,0x2f,0x07,0x65,0x00,0x25,0x00,0x2f,0x00,0x00,0x13,0x32,0x17,0x36,0x25,0x04,0x00,0x13,0x15,0x02,0x05,0x16,0x15,0x14,0x04,0x21,0x26,0x27,0x26,0x35,0x36,0x33,0x16,0x17,0x20,0x24,0x35,0x34,0x24,0x27,0x21,0x11,0x06,0x07,0x22,0x35,0x11,0x34,0x05,0x22,0x07,0x11,0x21,0x2c,0x01,0x37,0x26,0x00,0xb7,0x49,0x11,0x4e,0x01,0x01,0x01,0x81,0x02,0x3d,0x11,0x0b,0xfe,0xc3,0xcd,0xfe,0x5f,0xfe,0x6b,0x70,0x6d,0x55,0x02,0x65,0x65,0x6e,0x01,0x2a,0x01,0x3e,0xfe,0xe3,0xe4,0xfe,0x3b,0x21,0x51,0x5f,0x01,0xbf,0xe0,0x0e,0x01,0x75,0x01,0xa7,0x01,0x18,0x01,0x01,0xfe,0x2a,0x07,0x65,0x4d,0x2b,0x03,0x01,0xfe,0x74,0xfe,0xd0,0x31,0xfe,0xe3,0xb4,0x42,0xd8,0xc1,0xbc,0x07,0x08,0x1f,0x46,0x59,0x0c,0x02,0x63,0x62,0x67,0x48,0x03,0xfe,0x2a,0x50,0x0e,0x65,0x06,0xbc,0x4e,0xe3,0x2c,0xfc,0x9d,0x06,0xf4,0x9d,0xc4,0x01,0x33,0x00,0x01,0x00,0x3c,0xff,0xeb,0x05,0xe5,0x07,0x53,0x00,0x1a,0x00,0x00,0x01,0x32,0x04,0x17,0x06,0x07,0x22,0x26,0x23,0x06,0x00,0x03,0x12,0x00,0x33,0x20,0x36,0x33,0x16,0x17,0x14,0x04,0x05,0x24,0x03,0x12,0x00,0x03,0xb1,0xda,0x01,0x51,0x01,0x09,0x58,0x46,0xb7,0xd0,0xfa,0xfe,0x66,0x01,0x01,0x01,0x72,0xed,0x01,0x01,0xc2,0x52,0x55,0x01,0xfe,0x8d,0xff,0x00,0xfc,0xd0,0x06,0x02,0x02,0x18,0x07,0x53,0xbb,0x60,0x61,0x01,0x9d,0x01,0xfe,0x16,0xfe,0xbc,0xfe,0x9f,0xfe,0xe9,0x33,0x0f,0x5a,0x70,0x33,0x08,0x0d,0x03,0x55,0x01,0xbc,0x02,0x45,0x00,0x00,0x00,0x00,0x01,0x00,0x34,0xff,0xf2,0x06,0x11,0x07,0x65,0x00,0x1f,0x00,0x00,0x25,0x06,0x07,0x22,0x35,0x11,0x34,0x37,0x32,0x17,0x36,0x37,0x04,0x00,0x13,0x10,0x00,0x05,0x27,0x26,0x35,0x36,0x37,0x17,0x24,0x00,0x11,0x02,0x00,0x25,0x22,0x07,0x01,0x00,0x0d,0x5b,0x64,0x65,0x53,0x11,0x4e,0xf7,0x01,0x95,0x02,0x29,0x11,0xfd,0xf7,0xfe,0x62,0xfb,0x55,0x02,0x65,0xe7,0x01,0x43,0x01,0x94,0x01,0xfe,0x5c,0xfe,0x90,0xd6,0x54,0x50,0x50,0x0e,0x65,0x06,0xbc,0x4e,0x04,0x4d,0x2b,0x03,0x01,0xfe,0x74,0xfe,0x62,0xfe,0x81,0xfd,0x5f,0x02,0x06,0x1f,0x50,0x54,0x0a,0x05,0x15,0x01,0xf4,0x01,0x48,0x01,0x28,0x01,0x33,0x01,0x2c,0x00,0x00,0x01,0x00,0x38,0xff,0xfe,0x05,0x91,0x07,0x45,0x00,0x1a,0x00,0x00,0x01,0x16,0x15,0x06,0x07,0x21,0x03,0x21,0x16,0x15,0x06,0x07,0x21,0x11,0x21,0x16,0x15,0x06,0x07,0x21,0x26,0x27,0x11,0x26,0x27,0x34,0x37,0x04,0xef,0x5d,0x02,0x68,0xfc,0x47,0x01,0x03,0x5e,0x67,0x01,0x69,0xfc,0xa9,0x04,0x01,0x64,0x11,0x4e,0xfb,0x82,0x52,0x01,0x28,0x01,0x6a,0x07,0x45,0x09,0x58,0x66,0x03,0xfc,0x76,0x01,0x6b,0x5f,0x07,0xfe,0xa7,0x09,0x5b,0x57,0x0d,0x11,0x7f,0x05,0xf4,0x10,0x56,0x54,0x09,0x00,0x00,0x00,0x01,0x00,0x35,0xff,0xfd,0x04,0xa8,0x07,0x4c,0x00,0x16,0x00,0x00,0x01,0x16,0x15,0x06,0x07,0x21,0x11,0x21,0x16,0x15,0x06,0x07,0x21,0x13,0x06,0x07,0x26,0x27,0x11,0x26,0x27,0x34,0x37,0x04,0x4b,0x5d,0x02,0x68,0xfc,0xf0,0x02,0xa0,0x5d,0x01,0x5f,0xfd,0x65,0x01,0x06,0x69,0x63,0x01,0x28,0x01,0x6a,0x07,0x4c,0x09,0x58,0x68,0x03,0xfd,0x9d,0x0e,0x5f,0x61,0x07,0xfd,0x21,0x6b,0x01,0x01,0x72,0x06,0x19,0x10,0x56,0x54,0x09,0x00,0x00,0x01,0x00,0x1e,0xff,0xeb,0x07,0x19,0x07,0x53,0x00,0x28,0x00,0x00,0x01,0x13,0x21,0x22,0x27,0x36,0x37,0x21,0x16,0x17,0x14,0x07,0x27,0x11,0x06,0x23,0x26,0x2f,0x01,0x04,0x07,0x24,0x03,0x12,0x00,0x25,0x32,0x04,0x17,0x06,0x07,0x22,0x26,0x23,0x06,0x00,0x03,0x12,0x00,0x33,0x32,0x05,0x80,0x01,0xfe,0x9b,0x64,0x03,0x02,0x5f,0x02,0xae,0x53,0x02,0x51,0x7c,0x0f,0x5a,0x48,0x0f,0x03,0xfe,0xb7,0xf6,0xfc,0xda,0x06,0x02,0x02,0x18,0x01,0x5b,0xda,0x01,0x51,0x01,0x09,0x58,0x46,0xb7,0xd0,0xfa,0xfe,0x5c,0x01,0x01,0x01,0x68,0xf7,0xf7,0x01,0x81,0x01,0x0d,0x5d,0x66,0x03,0x0e,0x61,0x54,0x05,0x01,0xfd,0xb6,0x4b,0x04,0x44,0x4e,0x9b,0x08,0x0d,0x03,0x55,0x01,0xbc,0x02,0x45,0x05,0xbb,0x60,0x61,0x01,0x9d,0x01,0xfe,0x16,0xfe,0xbc,0xfe,0x9f,0xfe,0xe9,0x00,0x00,0x00,0x01,0x00,0x1d,0xff,0xf5,0x06,0xb7,0x07,0x47,0x00,0x22,0x00,0x00,0x01,0x13,0x36,0x37,0x32,0x17,0x11,0x16,0x15,0x06,0x07,0x11,0x06,0x23,0x26,0x27,0x03,0x21,0x11,0x06,0x23,0x26,0x27,0x11,0x26,0x35,0x36,0x37,0x11,0x36,0x37,0x32,0x17,0x11,0x21,0x05,0x8b,0x01,0x01,0x6d,0x6b,0x01,0x51,0x01,0x50,0x01,0x6b,0x6d,0x01,0x01,0xfb,0xc7,0x01,0x6b,0x6d,0x01,0x5b,0x02,0x59,0x01,0x6d,0x6b,0x01,0x04,0x39,0x03,0x6f,0x03,0x4d,0x8a,0x01,0x8a,0xfc,0x35,0x10,0x58,0x59,0x07,0xfe,0x50,0x85,0x01,0x85,0x01,0xab,0xfe,0x5a,0x81,0x01,0x81,0x01,0xaa,0x08,0x55,0x56,0x13,0x03,0xc8,0x8d,0x01,0x8c,0xfc,0x3b,0x00,0x00,0x00,0x00,0x01,0x00,0x33,0xff,0xfc,0x02,0x8f,0x07,0x44,0x00,0x17,0x00,0x00,0x13,0x23,0x22,0x35,0x34,0x33,0x21,0x32,0x15,0x14,0x2b,0x01,0x11,0x33,0x32,0x15,0x14,0x23,0x21,0x22,0x35,0x34,0x3b,0x01,0xf2,0x53,0x6c,0x71,0x01,0x7a,0x71,0x6c,0x5c,0x5c,0x6c,0x71,0xfe,0x86,0x71,0x6c,0x53,0x06,0x71,0x76,0x5d,0x5d,0x76,0xfa,0x5e,0x76,0x5d,0x5d,0x76,0x00,0x00,0x01,0x00,0x51,0xff,0xf6,0x06,0x9f,0x07,0x5b,0x00,0x21,0x00,0x00,0x01,0x05,0x26,0x35,0x36,0x33,0x21,0x34,0x37,0x32,0x17,0x33,0x32,0x15,0x06,0x2b,0x01,0x16,0x11,0x02,0x00,0x05,0x22,0x24,0x27,0x36,0x37,0x32,0x16,0x33,0x24,0x00,0x13,0x10,0x04,0xbb,0xfc,0x34,0x7f,0x06,0x78,0x03,0xa8,0x66,0x6e,0x01,0xb1,0x83,0x0a,0x6f,0x97,0x27,0x02,0xfe,0x42,0xfe,0x87,0xda,0xfe,0xaf,0x01,0x09,0x58,0x46,0xc2,0xd0,0x01,0x18,0x01,0x3f,0x01,0x06,0x10,0x01,0x01,0x69,0x6c,0x71,0x05,0x76,0x64,0x70,0xe4,0xfe,0xcf,0xfd,0xea,0xfe,0x15,0x05,0xbb,0x60,0x61,0x01,0xaa,0x01,0x01,0x89,0x01,0xb2,0x01,0x2c,0x00,0x01,0xff,0xf9,0xff,0xf8,0x06,0x46,0x07,0x53,0x00,0x24,0x00,0x00,0x01,0x00,0x01,0x36,0x37,0x16,0x15,0x14,0x07,0x00,0x01,0x04,0x01,0x16,0x15,0x06,0x07,0x26,0x27,0x00,0x25,0x11,0x14,0x23,0x22,0x27,0x33,0x03,0x26,0x27,0x34,0x37,0x03,0x34,0x33,0x32,0x15,0x01,0x1a,0x02,0xfe,0x01,0x64,0x1c,0x58,0x56,0x38,0xfe,0x7e,0xfc,0x98,0x02,0xf2,0x01,0xd6,0x4d,0x04,0x5f,0x3a,0x2f,0xfe,0x4c,0xfd,0x61,0x65,0x71,0x01,0x03,0x01,0x49,0x03,0x4c,0x01,0x71,0x65,0x03,0x5e,0x01,0x54,0x02,0x44,0x53,0x01,0x06,0x49,0x3f,0x61,0xfd,0x7d,0xfe,0xae,0x70,0xfe,0xc9,0x3f,0x52,0x4e,0x04,0x07,0x1d,0x01,0x27,0x6d,0xfe,0xa1,0x5d,0x5d,0x01,0xae,0x15,0x56,0x4f,0x25,0x04,0x07,0x6a,0x71,0x00,0x00,0x01,0x00,0x43,0xff,0xfa,0x05,0xa8,0x07,0x50,0x00,0x12,0x00,0x00,0x13,0x16,0x15,0x11,0x20,0x25,0x36,0x37,0x16,0x17,0x14,0x07,0x04,0x0d,0x01,0x26,0x27,0x03,0x36,0xaf,0x6d,0x02,0x7e,0x01,0x0f,0x4d,0x54,0x5a,0x04,0x7c,0xfe,0xe0,0xfe,0x9a,0xfe,0x67,0xc4,0x05,0x01,0x03,0x07,0x50,0x01,0x70,0xf9,0xf2,0x53,0x1f,0x0c,0x04,0x63,0x63,0x26,0x4c,0x16,0x03,0x09,0xbc,0x06,0x1d,0x73,0x00,0x00,0x01,0x00,0x3d,0x00,0x05,0x08,0xf0,0x07,0x43,0x00,0x1b,0x00,0x00,0x00,0x27,0x00,0x25,0x11,0x06,0x07,0x22,0x27,0x11,0x36,0x37,0x04,0x01,0x00,0x25,0x16,0x17,0x11,0x06,0x23,0x26,0x35,0x11,0x04,0x01,0x06,0x07,0x04,0x42,0x09,0xfe,0x99,0xfe,0x47,0x01,0x6d,0x61,0x0d,0x06,0x5d,0x02,0xb8,0x01,0x3f,0x01,0x3e,0x02,0xb8,0x5b,0x08,0x0d,0x61,0x70,0xfe,0x49,0xfe,0x99,0x09,0x56,0x01,0x2c,0x49,0x04,0x97,0x3d,0xfa,0x3f,0x82,0x01,0x86,0x06,0x45,0x6b,0x08,0x2f,0xfb,0xef,0x04,0x11,0x2f,0x08,0x6b,0xf9,0xbb,0x86,0x01,0x82,0x05,0xc1,0x3d,0xfb,0x69,0x49,0x05,0x00,0x00,0x00,0x00,0x01,0x00,0x3d,0xff,0xf7,0x06,0xc8,0x07,0x43,0x00,0x16,0x00,0x00,0x13,0x04,0x01,0x11,0x36,0x37,0x16,0x15,0x11,0x06,0x23,0x26,0x2f,0x01,0x00,0x25,0x11,0x14,0x07,0x22,0x27,0x11,0x36,0xa0,0x03,0xa3,0x01,0xaa,0x02,0x5b,0x7e,0x08,0x63,0x62,0x09,0x01,0xfe,0x35,0xfc,0xf0,0x6b,0x61,0x0d,0x06,0x07,0x43,0x57,0xfc,0x47,0x03,0x91,0x60,0x18,0x01,0x79,0xf9,0x9e,0x69,0x0a,0x57,0xcd,0x04,0xbf,0x6f,0xfa,0x35,0x82,0x01,0x86,0x06,0x45,0x6b,0x00,0x00,0x00,0x02,0x00,0x1a,0xff,0xe4,0x07,0x7f,0x07,0x5a,0x00,0x13,0x00,0x25,0x00,0x00,0x01,0x16,0x17,0x06,0x23,0x22,0x26,0x27,0x22,0x00,0x03,0x12,0x00,0x05,0x20,0x00,0x13,0x10,0x00,0x2d,0x01,0x26,0x35,0x34,0x37,0x36,0x37,0x04,0x00,0x13,0x02,0x00,0x21,0x24,0x00,0x11,0x12,0x00,0x03,0x3d,0xc1,0x01,0x0a,0x51,0x31,0x6e,0x6c,0x77,0xfe,0xd9,0x02,0x0a,0x01,0xa7,0x01,0x0f,0x01,0x0c,0x01,0xc0,0x15,0xfe,0x35,0xfe,0xe7,0xfe,0x56,0x27,0x3c,0xaa,0xed,0x01,0x84,0x02,0x42,0x01,0x23,0xfd,0xfa,0xfe,0x62,0xfe,0x70,0xfd,0xf2,0x02,0x01,0x6d,0x06,0x92,0x22,0x7d,0x3f,0x50,0x01,0xfe,0x7b,0xfe,0xf5,0xfe,0x81,0xfe,0xc0,0x05,0x01,0x2c,0x01,0x94,0x01,0xb3,0x01,0x71,0x09,0x08,0x0b,0x43,0x25,0x24,0x15,0x08,0x09,0xfe,0x33,0xfd,0xe8,0xfe,0x2c,0xfe,0x4c,0x01,0x01,0xe8,0x01,0xaa,0x01,0x40,0x01,0xef,0x00,0x00,0x00,0x02,0x00,0x3d,0xff,0xf2,0x06,0x25,0x07,0x65,0x00,0x13,0x00,0x1d,0x00,0x00,0x00,0x29,0x01,0x11,0x06,0x07,0x22,0x35,0x11,0x34,0x37,0x32,0x17,0x36,0x25,0x04,0x00,0x13,0x15,0x06,0x01,0x22,0x07,0x11,0x21,0x24,0x36,0x37,0x26,0x00,0x04,0x7a,0xfe,0x69,0xfe,0x27,0x0d,0x5c,0x64,0x65,0x54,0x11,0x4e,0x01,0x01,0x01,0x95,0x02,0x29,0x11,0x0b,0xfc,0x24,0xe0,0x54,0x01,0xbb,0x01,0x9d,0xf0,0x01,0x01,0xfe,0x5c,0x02,0x22,0xfe,0x2e,0x50,0x0e,0x65,0x06,0xbc,0x4e,0x04,0x4d,0x2b,0x03,0x01,0xfe,0x74,0xfe,0xd0,0x31,0xff,0x03,0x1b,0x2c,0xfc,0xa7,0x06,0xea,0x9d,0xc4,0x01,0x33,0x00,0x02,0x00,0x24,0xfe,0x33,0x07,0xa6,0x07,0x5a,0x00,0x16,0x00,0x2e,0x00,0x00,0x25,0x26,0x27,0x36,0x33,0x16,0x17,0x16,0x33,0x32,0x00,0x13,0x02,0x00,0x25,0x20,0x00,0x03,0x10,0x00,0x05,0x37,0x26,0x04,0x05,0x16,0x17,0x06,0x07,0x26,0x27,0x26,0x27,0x06,0x07,0x24,0x00,0x03,0x12,0x00,0x21,0x04,0x00,0x11,0x02,0x00,0x07,0x03,0xc4,0x33,0x03,0x04,0x68,0x51,0x34,0x61,0x20,0x77,0x01,0x27,0x02,0x0a,0xfe,0x59,0xfe,0xf1,0xfe,0xf4,0xfe,0x40,0x15,0x01,0xcb,0x01,0x19,0x56,0x3e,0x02,0x53,0x01,0x07,0x4d,0x04,0x11,0x4c,0x5b,0x57,0xe9,0x9a,0x88,0xab,0xfe,0x68,0xfd,0xdc,0x01,0x23,0x01,0xfc,0x01,0x9e,0x01,0x90,0x02,0x04,0x02,0xfe,0xa7,0x83,0xeb,0x21,0x44,0x58,0x02,0x37,0x36,0x01,0x86,0x01,0x0a,0x01,0x7f,0x01,0x40,0x05,0xfe,0xd4,0xfe,0x6c,0xfe,0x4d,0xfe,0x8f,0x08,0x08,0x1d,0xdc,0xde,0x3b,0x42,0x4f,0x0d,0x02,0x67,0xd3,0x87,0x16,0x06,0x09,0x01,0xe2,0x02,0x0d,0x01,0xd4,0x01,0xb4,0x01,0xfe,0x18,0xfe,0x56,0xfe,0xb6,0xfe,0x1b,0x14,0x00,0x00,0x02,0x00,0x27,0xff,0xf2,0x06,0x3b,0x07,0x65,0x00,0x19,0x00,0x22,0x00,0x00,0x13,0x32,0x17,0x36,0x25,0x04,0x00,0x13,0x02,0x05,0x01,0x16,0x15,0x14,0x23,0x26,0x27,0x01,0x21,0x11,0x06,0x07,0x22,0x35,0x11,0x34,0x05,0x22,0x07,0x11,0x21,0x20,0x13,0x26,0x00,0x96,0x4c,0x11,0x4e,0x01,0x01,0x01,0x95,0x02,0x29,0x11,0x01,0xfe,0x9c,0x01,0x71,0x1e,0x70,0x57,0x42,0xfe,0x8b,0xfd,0x39,0x0d,0x54,0x6e,0x02,0x03,0xe0,0x54,0x02,0x01,0x02,0x3d,0x01,0x01,0xfe,0x66,0x07,0x65,0x4d,0x2b,0x03,0x01,0xfe,0x74,0xfe,0xd0,0xfe,0x6c,0x90,0xfe,0x3f,0x26,0x2c,0x5c,0x01,0x70,0x01,0xbf,0xfe,0x2a,0x50,0x0e,0x65,0x06,0xbc,0x4e,0xf4,0x25,0xfc,0xa7,0x01,0x8d,0xc4,0x01,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x2a,0xff,0xe3,0x06,0x0b,0x07,0x5c,0x00,0x21,0x00,0x00,0x01,0x04,0x17,0x16,0x17,0x06,0x07,0x22,0x26,0x25,0x04,0x03,0x16,0x00,0x13,0x02,0x05,0x24,0x27,0x26,0x27,0x36,0x37,0x32,0x17,0x16,0x05,0x24,0x37,0x34,0x24,0x03,0x12,0x25,0x03,0x63,0x01,0x70,0xe5,0x52,0x01,0x10,0x46,0x3f,0xcc,0xfe,0xb5,0xfd,0xa8,0x07,0x01,0x04,0xd9,0x01,0x16,0xfd,0x89,0xfe,0x6e,0xd8,0x52,0x01,0x06,0x50,0x2b,0x4e,0xcc,0x01,0x26,0x01,0xa3,0x0b,0xfb,0x2b,0x01,0x1a,0x03,0x1e,0x07,0x5c,0x02,0x91,0x34,0x53,0x57,0x01,0xa0,0x0b,0x1f,0xfe,0x73,0xf4,0xfe,0xf9,0xfe,0x8c,0xfe,0x7d,0x14,0x11,0x85,0x3e,0x44,0x66,0x01,0x3f,0x6a,0x07,0x1d,0xaf,0xe5,0xf4,0x01,0x97,0x02,0x54,0x1a,0x00,0x00,0x01,0x00,0x01,0xff,0xfc,0x05,0x91,0x07,0x44,0x00,0x10,0x00,0x00,0x01,0x21,0x22,0x35,0x34,0x33,0x21,0x32,0x15,0x14,0x23,0x21,0x03,0x14,0x23,0x22,0x27,0x02,0x61,0xfe,0x0c,0x6c,0x71,0x04,0xae,0x71,0x6c,0xfe,0x17,0x02,0x67,0x71,0x01,0x06,0x71,0x76,0x5d,0x5d,0x76,0xf9,0xe8,0x5d,0x5d,0x00,0x00,0x00,0x00,0x01,0x00,0x16,0xff,0xfc,0x06,0x02,0x07,0x5b,0x00,0x1b,0x00,0x00,0x13,0x36,0x33,0x16,0x17,0x02,0x11,0x12,0x00,0x05,0x32,0x37,0x11,0x36,0x33,0x32,0x15,0x11,0x14,0x07,0x22,0x27,0x06,0x07,0x24,0x00,0x03,0x10,0x63,0x0c,0x64,0x68,0x01,0x4a,0x01,0x01,0x9a,0x01,0x70,0xcc,0x5e,0x0d,0x64,0x6a,0x65,0x62,0x11,0x58,0xed,0xfe,0x6b,0xfd,0xd7,0x11,0x06,0xdf,0x74,0x02,0x79,0xfd,0x7d,0xfe,0xd6,0xfe,0xd8,0xfe,0xcd,0x01,0x54,0x05,0xcb,0x6d,0x6f,0xf9,0x62,0x4e,0x04,0x4d,0x49,0x03,0x01,0x01,0x8c,0x01,0x9e,0x01,0x48,0x00,0x00,0x00,0x00,0x01,0x00,0x02,0xff,0xfe,0x06,0x43,0x07,0x48,0x00,0x14,0x00,0x00,0x09,0x01,0x36,0x33,0x16,0x15,0x06,0x07,0x01,0x06,0x07,0x23,0x26,0x27,0x01,0x26,0x27,0x34,0x37,0x32,0x17,0x03,0x23,0x02,0x3b,0x2a,0x5a,0x61,0x08,0x18,0xfd,0x85,0x26,0x5f,0x01,0x5f,0x26,0xfd,0x85,0x18,0x08,0x57,0x64,0x2a,0x01,0x64,0x05,0x60,0x84,0x10,0x69,0x37,0x35,0xfa,0x14,0x76,0x03,0x03,0x76,0x05,0xec,0x35,0x37,0x69,0x10,0x84,0x00,0x01,0x00,0x02,0xff,0xfe,0x09,0x63,0x07,0x48,0x00,0x29,0x00,0x00,0x09,0x01,0x06,0x07,0x23,0x26,0x27,0x01,0x26,0x27,0x34,0x37,0x32,0x17,0x09,0x01,0x36,0x37,0x36,0x37,0x32,0x17,0x36,0x33,0x16,0x17,0x16,0x17,0x09,0x01,0x36,0x33,0x16,0x15,0x06,0x07,0x01,0x06,0x07,0x23,0x26,0x27,0x04,0xb3,0xfe,0xf5,0x26,0x5f,0x01,0x5f,0x26,0xfd,0x85,0x18,0x08,0x57,0x67,0x2a,0x02,0x39,0x01,0x19,0x0a,0x0d,0x10,0x42,0x07,0x06,0x07,0x07,0x42,0x10,0x0d,0x0a,0x01,0x1a,0x02,0x37,0x2a,0x64,0x5b,0x08,0x18,0xfd,0x85,0x26,0x5f,0x01,0x5f,0x26,0x02,0xd0,0xfd,0xa7,0x76,0x03,0x03,0x76,0x05,0xec,0x35,0x37,0x69,0x10,0x84,0xfa,0xa0,0x02,0x68,0x20,0x18,0x40,0x0c,0x01,0x01,0x0c,0x40,0x18,0x20,0xfd,0x98,0x05,0x60,0x84,0x10,0x69,0x37,0x35,0xfa,0x14,0x76,0x03,0x03,0x76,0x00,0x01,0x00,0x12,0xff,0xf4,0x05,0x53,0x07,0x4f,0x00,0x1f,0x00,0x00,0x09,0x01,0x26,0x27,0x34,0x37,0x32,0x17,0x09,0x01,0x36,0x33,0x16,0x15,0x06,0x07,0x09,0x01,0x16,0x17,0x14,0x07,0x22,0x27,0x09,0x01,0x06,0x23,0x26,0x35,0x36,0x37,0x01,0xf9,0xfe,0x40,0x1d,0x0a,0x53,0x63,0x37,0x01,0xaf,0x01,0xb8,0x37,0x63,0x53,0x0a,0x1d,0xfe,0x37,0x01,0xc9,0x1d,0x0a,0x53,0x63,0x37,0xfe,0x48,0xfe,0x51,0x37,0x63,0x53,0x0a,0x1d,0x03,0xa2,0x02,0xc8,0x35,0x37,0x69,0x10,0x84,0xfd,0x5f,0x02,0x97,0x84,0x10,0x69,0x37,0x35,0xfd,0x42,0xfd,0x41,0x35,0x37,0x69,0x10,0x84,0x02,0x97,0xfd,0x5f,0x84,0x10,0x69,0x37,0x35,0x00,0x00,0x00,0x01,0x00,0x21,0xff,0xff,0x05,0xc0,0x07,0x4f,0x00,0x15,0x00,0x00,0x09,0x01,0x26,0x27,0x34,0x37,0x32,0x17,0x09,0x01,0x36,0x33,0x16,0x15,0x06,0x07,0x01,0x11,0x14,0x07,0x26,0x27,0x02,0x7d,0xfd,0xcd,0x1f,0x0a,0x64,0x5f,0x36,0x01,0xd2,0x01,0xdb,0x36,0x5f,0x64,0x0a,0x1f,0xfd,0xc2,0x6d,0x6e,0x01,0x02,0x23,0x04,0x47,0x35,0x37,0x69,0x10,0x84,0xfc,0x76,0x03,0x80,0x84,0x10,0x69,0x37,0x35,0xfb,0xc3,0xfe,0x4d,0x6a,0x07,0x07,0x6a,0x00,0x00,0x00,0x00,0x01,0x00,0x31,0xff,0xfe,0x05,0xb9,0x07,0x3f,0x00,0x17,0x00,0x00,0x08,0x01,0x35,0x21,0x22,0x27,0x36,0x37,0x25,0x16,0x15,0x02,0x00,0x06,0x15,0x05,0x32,0x17,0x06,0x07,0x21,0x26,0x35,0x10,0x01,0x43,0x03,0x83,0xfb,0xf9,0x7f,0x0f,0x06,0x88,0x04,0x7a,0x80,0x0a,0xfc,0x5a,0xdb,0x03,0xdf,0x7f,0x0f,0x06,0x88,0xfb,0xa4,0x80,0x02,0xb8,0x02,0xb5,0xfc,0x67,0x69,0x05,0x01,0x0b,0x87,0xfe,0x7a,0xfd,0x17,0xe7,0x7a,0x01,0x71,0x68,0x05,0x09,0x87,0x01,0x02,0x00,0x00,0x00,0x00,0x01,0x00,0xaa,0xff,0x21,0x02,0xd0,0x08,0x26,0x00,0x11,0x00,0x00,0x13,0x34,0x33,0x25,0x16,0x15,0x06,0x07,0x21,0x11,0x25,0x16,0x17,0x14,0x07,0x25,0x22,0x35,0xaa,0x6c,0x01,0x50,0x6a,0x02,0x5c,0xfe,0xec,0x01,0x14,0x5c,0x02,0x6a,0xfe,0xb0,0x6c,0x07,0xa1,0x83,0x02,0x0b,0x4e,0x67,0x02,0xf8,0x7f,0x01,0x02,0x68,0x4e,0x0b,0x02,0x83,0x00,0x00,0x00,0x01,0x00,0x0f,0xff,0x8e,0x03,0x07,0x07,0xf9,0x00,0x0d,0x00,0x00,0x12,0x37,0x16,0x17,0x01,0x16,0x15,0x06,0x07,0x26,0x27,0x01,0x26,0x35,0x0f,0x6c,0x4f,0x0c,0x02,0x1a,0x17,0x0b,0x46,0x48,0x1a,0xfd,0xe1,0x26,0x07,0xf7,0x02,0x11,0x5e,0xf8,0xcb,0x2a,0x44,0x58,0x01,0x05,0x42,0x07,0x32,0x41,0x54,0x00,0x00,0x01,0x00,0x50,0xff,0x21,0x02,0x76,0x08,0x26,0x00,0x11,0x00,0x00,0x05,0x14,0x23,0x05,0x26,0x35,0x36,0x37,0x05,0x11,0x21,0x26,0x27,0x34,0x37,0x05,0x32,0x15,0x02,0x76,0x6c,0xfe,0xb0,0x6a,0x02,0x5c,0x01,0x14,0xfe,0xec,0x5c,0x02,0x6a,0x01,0x50,0x6c,0x5a,0x83,0x02,0x0b,0x4e,0x68,0x02,0x01,0x07,0x81,0x02,0x67,0x4e,0x0b,0x02,0x83,0x00,0x00,0x00,0x01,0xff,0xa6,0xfe,0xdd,0x04,0xd8,0xff,0x90,0x00,0x09,0x00,0x00,0x01,0x21,0x26,0x27,0x36,0x33,0x21,0x32,0x15,0x06,0x04,0x76,0xfb,0x90,0x5e,0x02,0x02,0x5d,0x04,0x72,0x61,0x02,0xfe,0xdd,0x01,0x5d,0x55,0x5c,0x56,0x00,0x00,0x01,0x00,0x4a,0x05,0x23,0x02,0x6b,0x06,0x13,0x00,0x0e,0x00,0x00,0x00,0x15,0x06,0x07,0x26,0x25,0x26,0x27,0x36,0x33,0x32,0x17,0x1e,0x01,0x17,0x02,0x6b,0x01,0x34,0x87,0xfe,0xd5,0x37,0x03,0x07,0x3e,0x34,0x4b,0xa9,0x62,0x21,0x05,0x82,0x2a,0x2d,0x08,0x07,0x6c,0x16,0x2a,0x3d,0x2a,0x3b,0x0f,0x0b,0x00,0x00,0x02,0x00,0x3e,0xff,0xf9,0x04,0xca,0x04,0x93,0x00,0x09,0x00,0x26,0x00,0x00,0x25,0x36,0x24,0x37,0x34,0x25,0x06,0x04,0x07,0x16,0x01,0x13,0x06,0x07,0x26,0x2f,0x01,0x06,0x21,0x24,0x03,0x36,0x00,0x25,0x32,0x17,0x2e,0x01,0x27,0x22,0x06,0x23,0x26,0x35,0x36,0x24,0x37,0x04,0x12,0x01,0xb0,0xc0,0x01,0x6c,0x07,0xfe,0xf3,0xaa,0xfe,0xd8,0x01,0x06,0x03,0xad,0x14,0x07,0x5f,0x55,0x0a,0x06,0xef,0xfe,0x8b,0xfe,0xa6,0x03,0x01,0x01,0x8c,0x01,0x00,0xd2,0x4e,0x01,0x83,0xb7,0xcd,0x8e,0x4d,0x49,0x06,0x01,0x15,0xdb,0x01,0x27,0xd9,0xb9,0x0c,0x98,0x80,0x7d,0x0a,0x06,0xaa,0x6e,0x8d,0x02,0x0c,0xfd,0xb5,0x70,0x0a,0x09,0x40,0x63,0xb3,0x12,0x01,0x39,0xb6,0x01,0x10,0x14,0x2d,0x5d,0x77,0x0c,0x69,0x08,0x60,0x4e,0x70,0x05,0x07,0xfe,0xf5,0x00,0x00,0x02,0x00,0x4b,0xff,0xef,0x04,0xce,0x07,0x56,0x00,0x09,0x00,0x1c,0x00,0x00,0x01,0x06,0x00,0x07,0x14,0x33,0x36,0x00,0x37,0x26,0x01,0x36,0x37,0x16,0x17,0x11,0x12,0x21,0x04,0x13,0x02,0x00,0x05,0x22,0x27,0x06,0x23,0x22,0x27,0x03,0x5c,0xc0,0xfe,0x94,0x07,0xd8,0xad,0x01,0x3f,0x17,0x06,0xfc,0x4d,0x03,0x67,0x61,0x01,0xe5,0x01,0x6b,0x01,0x5a,0x0d,0x01,0xfe,0x74,0xfe,0xc4,0x96,0x58,0x1e,0x56,0x57,0x01,0x03,0x9e,0x02,0xfe,0x82,0x9e,0xcd,0x01,0x01,0x31,0xf0,0xc9,0x03,0x44,0x73,0x01,0x02,0x80,0xfc,0x37,0x01,0x5d,0x12,0xfe,0x81,0xfe,0xf8,0xfe,0x34,0x14,0x26,0x26,0x71,0x00,0x00,0x00,0x00,0x01,0x00,0x39,0xff,0xec,0x04,0x10,0x04,0x88,0x00,0x19,0x00,0x00,0x01,0x04,0x17,0x06,0x07,0x2e,0x01,0x23,0x0e,0x01,0x07,0x12,0x17,0x3e,0x02,0x37,0x16,0x17,0x06,0x04,0x07,0x24,0x03,0x12,0x00,0x02,0x6c,0x01,0x64,0x05,0x02,0x58,0x35,0x7d,0x58,0x83,0xee,0x02,0x14,0xf4,0x8d,0xb8,0x2b,0x47,0x4d,0x06,0x09,0xfe,0xeb,0xdd,0xfe,0x2f,0x0b,0x01,0x01,0x1e,0x04,0x88,0x0b,0x99,0x53,0x05,0x01,0x37,0x01,0xff,0xbf,0xfe,0xb5,0x06,0x01,0xa5,0x63,0x01,0x04,0x64,0x74,0xf1,0x05,0x05,0x01,0xfc,0x01,0x1f,0x01,0x67,0x00,0x02,0x00,0x34,0xff,0xf9,0x04,0xe8,0x07,0x47,0x00,0x0a,0x00,0x20,0x00,0x00,0x25,0x36,0x00,0x37,0x27,0x34,0x23,0x06,0x00,0x07,0x16,0x01,0x03,0x36,0x37,0x16,0x17,0x1a,0x01,0x17,0x06,0x07,0x26,0x35,0x27,0x02,0x21,0x24,0x03,0x12,0x00,0x25,0x32,0x01,0xa6,0xc0,0x01,0x6c,0x0a,0x03,0xd8,0xad,0xfe,0xc1,0x1c,0x06,0x02,0xe5,0x06,0x03,0x6f,0x5a,0x05,0x05,0x33,0x01,0x07,0x5f,0x69,0x1a,0xf9,0xfe,0x8b,0xfe,0xa6,0x03,0x01,0x01,0x8c,0x01,0x3c,0x90,0xb9,0x0c,0x01,0x7e,0x98,0x56,0x7d,0x01,0xfe,0xcf,0xf0,0xd3,0x03,0x96,0x02,0x80,0x76,0x02,0x0e,0x6b,0xfc,0x91,0xfd,0x76,0x5b,0x70,0x0a,0x09,0x72,0xf9,0xfe,0x85,0x12,0x01,0x7f,0x01,0x08,0x01,0xcc,0x14,0x00,0x02,0x00,0x39,0xff,0xec,0x04,0x82,0x04,0x93,0x00,0x07,0x00,0x1d,0x00,0x00,0x01,0x34,0x23,0x04,0x07,0x16,0x17,0x20,0x16,0x05,0x26,0x27,0x12,0x05,0x36,0x37,0x36,0x33,0x16,0x17,0x06,0x04,0x05,0x24,0x03,0x12,0x00,0x25,0x04,0x13,0x03,0xb3,0xd7,0xfe,0xba,0x57,0x93,0x66,0x01,0x78,0xcb,0xfd,0xc7,0xbf,0x6c,0x09,0x01,0x64,0xa0,0x88,0x41,0x41,0x53,0x01,0x02,0xfe,0xdd,0xfe,0xdc,0xfe,0x27,0x27,0x01,0x01,0x7e,0x01,0x23,0x01,0x9d,0x04,0x03,0x4c,0x88,0x1c,0xd4,0x08,0x02,0xbc,0x0c,0x0a,0x01,0xfe,0xaa,0x13,0x02,0x78,0x3d,0x01,0x60,0x4e,0xce,0x02,0x38,0x01,0xe0,0x01,0x27,0x01,0x5b,0x0d,0x0f,0xfe,0xcc,0x00,0x00,0x01,0xff,0xc6,0x00,0x00,0x02,0x9d,0x07,0x49,0x00,0x1e,0x00,0x00,0x01,0x1e,0x01,0x17,0x06,0x07,0x2e,0x01,0x27,0x06,0x07,0x33,0x16,0x17,0x06,0x07,0x23,0x13,0x14,0x07,0x22,0x27,0x03,0x23,0x22,0x35,0x34,0x3f,0x01,0x3e,0x01,0x01,0x8c,0x87,0x89,0x01,0x08,0x46,0x1e,0x60,0x4a,0x64,0x04,0xeb,0x4d,0x04,0x08,0x4d,0xea,0x0b,0x64,0x60,0x0e,0x0d,0x2d,0x55,0x5a,0x31,0x05,0x94,0x07,0x49,0x01,0x48,0x47,0x4a,0x02,0x01,0x1b,0x02,0x0c,0xce,0x0b,0x42,0x5a,0x08,0xfb,0x79,0x70,0x0b,0x7c,0x04,0x85,0x5b,0x4f,0x05,0x04,0xac,0xe8,0x00,0x00,0x02,0x00,0x27,0xfd,0xe4,0x04,0xbf,0x04,0x68,0x00,0x0a,0x00,0x28,0x00,0x00,0x25,0x36,0x00,0x37,0x27,0x34,0x23,0x06,0x00,0x07,0x16,0x08,0x01,0x07,0x2e,0x01,0x35,0x36,0x37,0x32,0x16,0x33,0x3e,0x01,0x37,0x13,0x02,0x21,0x24,0x03,0x12,0x00,0x25,0x32,0x17,0x36,0x33,0x16,0x17,0x13,0x03,0x01,0x99,0xc0,0x01,0x6c,0x0a,0x03,0xd8,0xad,0xfe,0xc1,0x1c,0x06,0x03,0xc4,0xfe,0xd7,0xe7,0xc0,0xa9,0x03,0x56,0x4f,0x6d,0x59,0x67,0xde,0x02,0x03,0xfc,0xfe,0x8b,0xfe,0xa6,0x03,0x01,0x01,0x8c,0x01,0x3c,0x96,0x58,0x1e,0x55,0x61,0x01,0x0c,0x09,0xaf,0x0c,0x01,0x7e,0x98,0x56,0x7d,0x01,0xfe,0xcf,0xf0,0xd3,0xfe,0x82,0xfe,0xb8,0x05,0x01,0x4d,0x50,0x45,0x14,0x30,0x01,0xc3,0xe9,0x01,0x12,0xfe,0x85,0x12,0x01,0x7f,0x01,0x08,0x01,0xcc,0x14,0x26,0x26,0x01,0x70,0xfd,0xeb,0xfe,0x58,0x00,0x00,0x01,0x00,0x42,0x00,0x03,0x04,0x66,0x07,0x3d,0x00,0x1b,0x00,0x00,0x37,0x26,0x35,0x02,0x35,0x36,0x37,0x16,0x17,0x13,0x12,0x25,0x04,0x13,0x14,0x03,0x06,0x23,0x26,0x35,0x12,0x35,0x26,0x27,0x22,0x00,0x03,0x06,0xc5,0x67,0x1c,0x0d,0x58,0x60,0x07,0x09,0x9e,0x01,0x4f,0x01,0x5d,0x05,0x14,0x0a,0x68,0x55,0x10,0x0a,0x93,0x92,0xfe,0xf4,0x32,0x05,0x07,0x0c,0x68,0x06,0x17,0x4c,0x5e,0x01,0x09,0x7a,0xfc,0x5a,0x01,0x6d,0x07,0x0a,0xfe,0x44,0xf2,0xfe,0x98,0x65,0x08,0x63,0x01,0x66,0xdf,0xfd,0x11,0xfe,0x83,0xfe,0x2a,0x5e,0x00,0x00,0x00,0x02,0x00,0x52,0xff,0xf9,0x02,0x3e,0x06,0x99,0x00,0x07,0x00,0x18,0x00,0x00,0x01,0x16,0x15,0x06,0x07,0x26,0x27,0x36,0x12,0x17,0x03,0x16,0x33,0x32,0x36,0x33,0x32,0x17,0x06,0x07,0x24,0x03,0x13,0x36,0x33,0x01,0x05,0x69,0x13,0x65,0x72,0x02,0x16,0x8d,0x01,0x09,0x14,0x5d,0x1c,0x33,0x22,0x35,0x0a,0x02,0xbc,0xfe,0xd7,0x05,0x0b,0x05,0x62,0x06,0x99,0x1a,0x6c,0x68,0x0c,0x05,0x8f,0x66,0xfd,0xe5,0x6d,0xfd,0x8f,0xda,0x12,0x4f,0x8f,0x01,0x17,0x01,0x9a,0x02,0x69,0x6b,0x00,0x02,0xfe,0xb5,0xfe,0x5c,0x01,0x9c,0x07,0x12,0x00,0x08,0x00,0x1b,0x00,0x00,0x01,0x16,0x17,0x07,0x06,0x23,0x22,0x27,0x34,0x13,0x16,0x17,0x13,0x0a,0x01,0x07,0x24,0x27,0x36,0x37,0x32,0x16,0x33,0x32,0x36,0x13,0x03,0x36,0x01,0x06,0x80,0x0a,0x0a,0x27,0x58,0x5b,0x13,0x8a,0x4f,0x13,0x17,0x01,0xe3,0xf2,0xff,0x00,0x11,0x03,0x3d,0x2e,0x56,0x51,0x82,0x84,0x01,0x15,0x05,0x07,0x12,0x01,0x6c,0x3d,0x5d,0x70,0x7d,0xfd,0x9d,0x03,0x69,0xfc,0xed,0xfe,0x78,0xfe,0xd4,0x06,0x10,0x85,0x54,0x0c,0x26,0xca,0x01,0x41,0x02,0xfa,0x57,0x00,0x00,0x01,0x00,0x3e,0xff,0xf9,0x04,0x2e,0x07,0x2b,0x00,0x1b,0x00,0x00,0x12,0x37,0x32,0x15,0x03,0x01,0x36,0x37,0x32,0x17,0x06,0x07,0x05,0x01,0x16,0x17,0x06,0x07,0x26,0x27,0x01,0x07,0x13,0x06,0x23,0x26,0x27,0x13,0x4b,0x6f,0x66,0x09,0x01,0xda,0x50,0x3b,0x68,0x07,0x08,0x7c,0xfe,0xcf,0x01,0xd9,0x1e,0x01,0x03,0x52,0x57,0x15,0xfe,0x0e,0x5b,0x02,0x01,0x6b,0x75,0x03,0x0b,0x07,0x23,0x08,0x6f,0xfc,0x3f,0x01,0x31,0x43,0x01,0x73,0x45,0x3d,0xc5,0xfd,0xfb,0x24,0x3f,0x4a,0x0b,0x0b,0x2a,0x02,0x21,0x3d,0xfe,0x6f,0x81,0x01,0x78,0x06,0x32,0x00,0x00,0x00,0x00,0x01,0x00,0x38,0xff,0xf9,0x02,0x24,0x07,0x4a,0x00,0x10,0x00,0x00,0x00,0x17,0x03,0x16,0x33,0x32,0x36,0x33,0x32,0x17,0x06,0x07,0x24,0x03,0x13,0x36,0x33,0x01,0x10,0x01,0x0e,0x14,0x5d,0x1c,0x33,0x22,0x35,0x0a,0x02,0xbc,0xfe,0xd7,0x05,0x10,0x05,0x62,0x07,0x4a,0x6d,0xfa,0xc3,0xda,0x12,0x4f,0x8f,0x01,0x17,0x01,0x9a,0x05,0x35,0x6b,0x00,0x00,0x00,0x01,0x00,0x46,0xff,0xfa,0x07,0x41,0x04,0x88,0x00,0x2e,0x00,0x00,0x01,0x06,0x03,0x06,0x23,0x26,0x35,0x12,0x35,0x26,0x27,0x22,0x00,0x03,0x06,0x07,0x26,0x35,0x0a,0x01,0x35,0x36,0x37,0x16,0x17,0x13,0x12,0x25,0x16,0x17,0x36,0x37,0x04,0x13,0x14,0x03,0x06,0x23,0x26,0x35,0x12,0x35,0x26,0x27,0x22,0x07,0x06,0x04,0x85,0x03,0x11,0x0a,0x68,0x55,0x10,0x0a,0x93,0x92,0xfe,0xf4,0x32,0x05,0x66,0x67,0x07,0x2e,0x0d,0x58,0x6a,0x07,0x10,0xa8,0x01,0x4f,0xe5,0x51,0x99,0xed,0x01,0x5d,0x05,0x14,0x0a,0x68,0x55,0x10,0x0a,0x93,0x92,0x86,0x21,0x02,0x92,0xe6,0xfe,0xb9,0x65,0x08,0x63,0x01,0x66,0xdf,0xfd,0x11,0xfe,0x83,0xfe,0x20,0x5e,0x09,0x0c,0x68,0x01,0xcd,0x01,0xa2,0x4c,0x5e,0x01,0x09,0x7a,0xfe,0xf8,0x01,0x81,0x07,0x07,0xc0,0xc2,0x05,0x0a,0xfe,0x44,0xf2,0xfe,0x98,0x65,0x08,0x63,0x01,0x66,0xdf,0xfd,0x11,0xbe,0x2f,0x00,0x01,0x00,0x46,0xff,0xfa,0x04,0x7b,0x04,0x82,0x00,0x1c,0x00,0x00,0x17,0x26,0x35,0x0a,0x01,0x35,0x36,0x37,0x16,0x1f,0x01,0x12,0x25,0x04,0x13,0x14,0x03,0x06,0x23,0x26,0x35,0x12,0x35,0x26,0x27,0x22,0x00,0x03,0x06,0xd8,0x67,0x07,0x24,0x0d,0x58,0x6a,0x07,0x06,0xa8,0x01,0x4f,0x01,0x5d,0x05,0x14,0x0a,0x68,0x55,0x10,0x0a,0x93,0x92,0xfe,0xf4,0x32,0x05,0x02,0x0c,0x68,0x01,0xc3,0x01,0xa2,0x4c,0x5e,0x01,0x09,0x7a,0xf4,0x01,0x6d,0x07,0x0a,0xfe,0x44,0xf2,0xfe,0x98,0x65,0x08,0x63,0x01,0x66,0xdf,0xfd,0x11,0xfe,0x83,0xfe,0x2a,0x5e,0x00,0x00,0x00,0x00,0x02,0x00,0x2d,0xff,0xe9,0x05,0x16,0x04,0x94,0x00,0x0d,0x00,0x19,0x00,0x00,0x01,0x17,0x16,0x00,0x13,0x10,0x00,0x05,0x27,0x24,0x00,0x03,0x36,0x00,0x03,0x12,0x05,0x17,0x24,0x13,0x37,0x34,0x24,0x2f,0x01,0x04,0x02,0x6a,0x4a,0xca,0x01,0x6d,0x2b,0xfe,0xc7,0xfe,0xd7,0x35,0xfe,0xfb,0xfe,0xbc,0x09,0x0e,0x01,0x19,0x5c,0x17,0x01,0x5b,0x51,0x01,0x3b,0x4f,0x0a,0xff,0x00,0xbb,0x33,0xfe,0xc4,0x04,0x94,0x02,0x0d,0xfe,0xe0,0xfe,0xe0,0xfe,0xea,0xfe,0xcd,0x13,0x07,0x1a,0x01,0x41,0x01,0x27,0xe5,0x01,0x2e,0xfd,0xde,0xfe,0xb2,0x61,0x0a,0x1e,0x01,0x0b,0x2f,0xc7,0xee,0x0f,0x01,0x29,0x00,0x00,0x00,0x02,0x00,0x45,0xfd,0xe7,0x04,0xdb,0x04,0x7c,0x00,0x0a,0x00,0x1e,0x00,0x00,0x01,0x06,0x00,0x07,0x17,0x14,0x17,0x36,0x00,0x37,0x26,0x01,0x13,0x06,0x07,0x22,0x27,0x03,0x36,0x37,0x16,0x15,0x17,0x12,0x21,0x04,0x13,0x02,0x00,0x05,0x22,0x03,0x69,0xc0,0xfe,0x94,0x0a,0x03,0xd8,0xad,0x01,0x3f,0x1c,0x06,0xfd,0x2b,0x08,0x0a,0x54,0x67,0x0a,0x2f,0x07,0x5f,0x69,0x06,0xef,0x01,0x75,0x01,0x5a,0x03,0x01,0xfe,0x74,0xfe,0xc4,0x83,0x03,0xbc,0x0c,0xfe,0x8c,0x98,0x56,0x7d,0x0a,0x01,0x01,0x31,0xf0,0xd3,0xfc,0x64,0xfe,0x3b,0x70,0x04,0x77,0x05,0x9d,0x70,0x0a,0x09,0x72,0xef,0x01,0x71,0x12,0xfe,0x81,0xfe,0xf8,0xfe,0x34,0x14,0x00,0x00,0x00,0x02,0x00,0x27,0xfd,0xdd,0x06,0x0a,0x04,0x68,0x00,0x0a,0x00,0x24,0x00,0x00,0x25,0x36,0x00,0x37,0x27,0x34,0x23,0x06,0x00,0x07,0x16,0x00,0x17,0x32,0x36,0x33,0x16,0x17,0x06,0x07,0x24,0x0b,0x01,0x02,0x21,0x24,0x03,0x12,0x00,0x25,0x32,0x17,0x36,0x33,0x32,0x17,0x13,0x01,0x99,0xc0,0x01,0x6c,0x0a,0x03,0xd8,0xad,0xfe,0xc1,0x1c,0x06,0x03,0xd0,0x93,0x22,0x2e,0x19,0x45,0x07,0x01,0xcf,0xfe,0xc4,0x10,0x0b,0xea,0xfe,0x8b,0xfe,0xa6,0x03,0x01,0x01,0x8c,0x01,0x3c,0x96,0x58,0x1e,0x41,0x45,0x13,0x1d,0xaf,0x0c,0x01,0x7e,0x98,0x56,0x7d,0x01,0xfe,0xcf,0xf0,0xd3,0xfd,0xfe,0x01,0x0d,0x0a,0x5a,0x75,0x03,0x28,0x01,0x8a,0x01,0xb3,0xfe,0xad,0x12,0x01,0x7f,0x01,0x08,0x01,0xcc,0x14,0x26,0x26,0x53,0xfb,0x8f,0x00,0x00,0x00,0x01,0x00,0x33,0x00,0x00,0x02,0xfd,0x04,0x89,0x00,0x16,0x00,0x00,0x13,0x16,0x17,0x36,0x37,0x04,0x17,0x06,0x07,0x2e,0x01,0x27,0x06,0x07,0x13,0x06,0x23,0x26,0x27,0x02,0x26,0x35,0x36,0x92,0x63,0x0b,0x41,0x94,0x01,0x12,0x16,0x02,0x47,0x53,0x42,0x43,0xab,0x12,0x1a,0x0e,0x63,0x5a,0x07,0x0c,0x28,0x0e,0x04,0x89,0x06,0x5d,0x53,0x0b,0x12,0xc9,0x59,0x0a,0x01,0x74,0x0a,0x17,0xa0,0xfd,0x6b,0x79,0x01,0x72,0x02,0x99,0xc1,0x5d,0x59,0x00,0x00,0x00,0x00,0x01,0x00,0x45,0xff,0xe9,0x04,0x04,0x04,0x99,0x00,0x20,0x00,0x00,0x01,0x17,0x04,0x17,0x06,0x07,0x2e,0x01,0x23,0x22,0x06,0x07,0x14,0x04,0x13,0x07,0x02,0x05,0x23,0x24,0x27,0x34,0x37,0x32,0x16,0x17,0x24,0x37,0x34,0x24,0x27,0x37,0x12,0x02,0x32,0x45,0x01,0x32,0x0e,0x04,0x46,0x40,0x6d,0x64,0x91,0x9d,0x08,0x02,0xb0,0x2e,0x05,0x38,0xfe,0x5b,0x3a,0xfe,0x70,0x13,0x3c,0x3c,0xa3,0xb8,0x01,0x0b,0x0a,0xfd,0x3e,0x1b,0x02,0x3f,0x04,0x99,0x02,0x15,0xac,0x45,0x0d,0x03,0x4a,0x45,0x54,0x76,0x04,0xfe,0xbe,0x58,0xfe,0xea,0x25,0x1e,0xf5,0x47,0x10,0x8e,0x04,0x07,0x9e,0xad,0x05,0xfc,0x3b,0x01,0x29,0x00,0x00,0x00,0x00,0x01,0x00,0x12,0xff,0xff,0x03,0x78,0x06,0x3e,0x00,0x21,0x00,0x00,0x01,0x16,0x17,0x06,0x2b,0x01,0x27,0x03,0x12,0x17,0x36,0x37,0x36,0x33,0x32,0x15,0x02,0x05,0x24,0x0b,0x01,0x23,0x22,0x27,0x36,0x37,0x33,0x35,0x37,0x36,0x33,0x16,0x17,0x07,0x02,0xd9,0x5a,0x05,0x08,0x5c,0x92,0xbb,0x04,0x02,0xb4,0x69,0x12,0x1d,0x52,0x55,0x2c,0xfe,0xed,0xfe,0x81,0x03,0x01,0x40,0x5c,0x08,0x05,0x5a,0x5d,0x04,0x0c,0x62,0x55,0x0a,0x01,0x05,0x00,0x07,0x5a,0x5b,0x01,0xfd,0x93,0xfe,0xfc,0x09,0x05,0x72,0x5a,0x71,0xfe,0xe3,0x0f,0x0c,0x01,0xd0,0x02,0x69,0x5b,0x5a,0x07,0x01,0xe4,0x59,0x07,0x62,0xd5,0x00,0x00,0x01,0x00,0x35,0x00,0x00,0x04,0x74,0x04,0x8b,0x00,0x1c,0x00,0x00,0x01,0x16,0x15,0x1a,0x01,0x15,0x06,0x07,0x26,0x27,0x03,0x02,0x05,0x24,0x03,0x34,0x13,0x36,0x33,0x16,0x15,0x02,0x15,0x16,0x17,0x32,0x00,0x13,0x36,0x03,0xd8,0x67,0x07,0x2e,0x0d,0x58,0x6a,0x07,0x10,0xa7,0xfe,0xb1,0xfe,0xa3,0x06,0x14,0x0a,0x68,0x55,0x10,0x0a,0x93,0x92,0x01,0x0c,0x32,0x05,0x04,0x87,0x0c,0x68,0xfe,0x3d,0xfe,0x5e,0x4c,0x5e,0x01,0x09,0x7b,0x01,0x07,0xfe,0x79,0x07,0x0a,0x01,0xc2,0xf2,0x01,0x69,0x64,0x08,0x63,0xfe,0x9a,0xdf,0xfd,0x11,0x01,0x7d,0x01,0xd6,0x5e,0x00,0x01,0x00,0x11,0x00,0x04,0x04,0x06,0x04,0x8b,0x00,0x16,0x00,0x00,0x25,0x26,0x27,0x0a,0x01,0x35,0x36,0x37,0x32,0x16,0x13,0x12,0x17,0x36,0x12,0x36,0x33,0x16,0x17,0x14,0x02,0x03,0x06,0x02,0x0f,0x64,0x3f,0xba,0xa1,0x0b,0x54,0x44,0x42,0x70,0x6d,0x3a,0x34,0xe0,0x42,0x4e,0x4a,0x0b,0xa1,0xb9,0x40,0x04,0x01,0xa4,0x01,0xe9,0x01,0x65,0x3a,0x50,0x0a,0x6e,0xfe,0xe4,0xfe,0xea,0x97,0x90,0x02,0x39,0x6e,0x0a,0x50,0x3a,0xfe,0x9b,0xfe,0x17,0xa4,0x00,0x00,0x01,0x00,0x08,0x00,0x04,0x06,0x43,0x04,0x8b,0x00,0x27,0x00,0x00,0x00,0x37,0x16,0x17,0x16,0x12,0x17,0x36,0x12,0x36,0x33,0x16,0x17,0x14,0x02,0x03,0x06,0x07,0x26,0x27,0x02,0x27,0x06,0x03,0x06,0x07,0x26,0x27,0x0a,0x01,0x35,0x36,0x37,0x32,0x16,0x12,0x17,0x36,0x12,0x37,0x02,0xea,0x41,0x36,0x1e,0x21,0xab,0x3a,0x35,0xae,0x42,0x44,0x4a,0x0b,0x89,0x91,0x44,0x5e,0x64,0x3f,0x74,0x4a,0x4b,0x73,0x40,0x5d,0x65,0x43,0x92,0x89,0x0b,0x4a,0x44,0x42,0xab,0x3b,0x34,0xae,0x21,0x04,0x84,0x07,0x07,0x30,0x37,0xfd,0xce,0x97,0x90,0x02,0x39,0x6e,0x0a,0x50,0x3a,0xfe,0x9b,0xfe,0x17,0xa4,0x01,0x01,0xa4,0x01,0xa9,0xbf,0xbf,0xfe,0x57,0xa4,0x01,0x01,0xa4,0x01,0xe9,0x01,0x65,0x3a,0x50,0x0a,0x6e,0xfd,0xce,0x97,0x90,0x02,0x39,0x37,0x00,0x00,0x00,0x01,0x00,0x1c,0x00,0x00,0x04,0x00,0x04,0x80,0x00,0x1f,0x00,0x00,0x09,0x01,0x26,0x27,0x36,0x37,0x16,0x17,0x09,0x01,0x36,0x37,0x16,0x17,0x14,0x07,0x09,0x01,0x16,0x15,0x06,0x07,0x26,0x27,0x09,0x01,0x06,0x07,0x26,0x27,0x36,0x37,0x01,0x8d,0xfe,0xdb,0x4b,0x01,0x06,0x58,0x49,0x32,0x01,0x11,0x01,0x12,0x31,0x4a,0x57,0x06,0x4c,0xfe,0xe3,0x01,0x2d,0x4c,0x06,0x58,0x49,0x31,0xfe,0xe1,0xfe,0xec,0x32,0x49,0x58,0x06,0x01,0x4b,0x02,0x45,0x01,0x4d,0x3b,0x44,0x65,0x0a,0x02,0x56,0xfe,0xd7,0x01,0x29,0x56,0x02,0x0a,0x65,0x44,0x3b,0xfe,0xbc,0xfe,0xa1,0x3a,0x45,0x65,0x0a,0x02,0x57,0x01,0x48,0xfe,0xb7,0x57,0x02,0x0a,0x65,0x45,0x3a,0x00,0x01,0x00,0x32,0xfd,0xe3,0x04,0x55,0x04,0x8b,0x00,0x25,0x00,0x00,0x00,0x05,0x22,0x27,0x26,0x35,0x36,0x37,0x32,0x16,0x33,0x32,0x12,0x11,0x02,0x05,0x24,0x03,0x34,0x13,0x36,0x33,0x16,0x15,0x02,0x15,0x16,0x17,0x32,0x00,0x13,0x36,0x37,0x16,0x15,0x12,0x13,0x10,0x03,0x41,0xfe,0xe3,0x98,0x52,0x3d,0x05,0x3e,0x41,0x51,0x50,0xab,0xbe,0xa8,0xfe,0xb1,0xfe,0xa3,0x05,0x1e,0x0a,0x68,0x55,0x1a,0x0a,0x93,0x92,0x01,0x0c,0x39,0x05,0x66,0x67,0x11,0x01,0xfd,0xe5,0x02,0x29,0x1b,0x4b,0x41,0x1b,0x21,0x01,0x2c,0x01,0xb5,0xfe,0x7f,0x07,0x0a,0x01,0xbc,0xf2,0x01,0x69,0x64,0x08,0x63,0xfe,0x9a,0xdf,0xfd,0x11,0x01,0x7d,0x01,0xd6,0x5e,0x09,0x0c,0x68,0xfe,0x79,0xfe,0xcb,0xfe,0x38,0x00,0x01,0x00,0x32,0x00,0x04,0x03,0x96,0x04,0x7c,0x00,0x15,0x00,0x00,0x01,0x05,0x26,0x27,0x36,0x37,0x21,0x16,0x15,0x14,0x07,0x01,0x21,0x16,0x17,0x06,0x07,0x21,0x26,0x35,0x34,0x37,0x02,0x93,0xfd,0xf5,0x53,0x03,0x0a,0x5f,0x02,0x92,0x69,0x1d,0xfd,0xbc,0x02,0x0b,0x53,0x03,0x0a,0x5f,0xfd,0x6e,0x69,0x1e,0x03,0xb9,0x01,0x11,0x52,0x5b,0x06,0x0f,0x55,0x3a,0x3c,0xfd,0x2a,0x11,0x57,0x57,0x09,0x12,0x55,0x3a,0x3c,0x00,0x00,0x00,0x00,0x01,0x00,0x87,0x02,0xb0,0x03,0x72,0x04,0x0b,0x00,0x17,0x00,0x00,0x00,0x15,0x06,0x07,0x26,0x27,0x26,0x23,0x22,0x07,0x06,0x07,0x26,0x27,0x36,0x37,0x16,0x17,0x16,0x3b,0x01,0x32,0x36,0x37,0x03,0x72,0x2d,0xa6,0x75,0x45,0x48,0x34,0x2b,0x3b,0x15,0x3a,0x2c,0x01,0x2b,0xc3,0x5b,0x49,0x46,0x35,0x04,0x27,0x44,0x3b,0x04,0x02,0x3a,0xca,0x11,0x07,0x19,0x1a,0x4a,0x2c,0x01,0x11,0x3e,0xaa,0x05,0x06,0x19,0x19,0x8e,0x07,0x00,0x00,0xff,0xff,0x00,0x9c,0xfd,0xbd,0x01,0xa0,0x04,0x80,0x00,0x0b,0x00,0x04,0x02,0x6e,0x04,0x7e,0xc0,0x00,0x00,0x02,0x00,0x33,0xff,0xe6,0x04,0x0a,0x07,0x4b,0x00,0x2c,0x00,0x33,0x00,0x00,0x13,0x26,0x03,0x12,0x00,0x25,0x16,0x17,0x13,0x36,0x33,0x16,0x17,0x06,0x07,0x03,0x16,0x17,0x06,0x07,0x26,0x27,0x26,0x27,0x01,0x16,0x17,0x3e,0x02,0x37,0x16,0x17,0x06,0x04,0x07,0x26,0x27,0x07,0x06,0x23,0x26,0x27,0x34,0x37,0x01,0x06,0x07,0x06,0x07,0x16,0x17,0xe2,0xa8,0x07,0x01,0x01,0x1e,0x01,0x14,0x13,0x11,0x9b,0x13,0x3c,0x42,0x01,0x06,0x12,0x78,0xa5,0x03,0x02,0x58,0x35,0x3e,0x12,0x14,0xfe,0xd1,0x26,0x2d,0x8d,0xb8,0x2b,0x47,0x4d,0x06,0x09,0xfe,0xeb,0xdd,0x60,0x4d,0x43,0x1f,0x3a,0x2f,0x06,0x25,0x01,0x87,0x6a,0x62,0x77,0x02,0x09,0x36,0x01,0x20,0x7c,0x01,0x2f,0x01,0x1f,0x01,0x67,0x15,0x01,0x01,0x01,0x8f,0x58,0x05,0x61,0x3c,0x2c,0xfe,0xd3,0x26,0x68,0x53,0x05,0x01,0x1c,0x07,0x06,0xfd,0x0b,0x0c,0x01,0x01,0xa5,0x63,0x01,0x04,0x64,0x74,0xf1,0x05,0x01,0x17,0xa7,0x55,0x04,0x44,0x2c,0x56,0x03,0xee,0x14,0x68,0x80,0xbf,0x94,0x53,0x00,0x00,0x00,0x00,0x01,0x00,0x07,0xff,0xf4,0x05,0xa9,0x07,0x4f,0x00,0x34,0x00,0x00,0x01,0x03,0x05,0x3e,0x01,0x33,0x16,0x17,0x06,0x04,0x07,0x25,0x26,0x27,0x13,0x26,0x27,0x36,0x3f,0x01,0x26,0x27,0x36,0x37,0x12,0x37,0x36,0x25,0x20,0x17,0x16,0x15,0x06,0x23,0x2e,0x01,0x27,0x06,0x07,0x06,0x03,0x21,0x16,0x17,0x06,0x07,0x05,0x07,0x25,0x16,0x17,0x06,0x07,0x01,0x2c,0x28,0x02,0xb3,0xcc,0x89,0x48,0x54,0x01,0x01,0xfe,0xef,0xec,0xfc,0xde,0x53,0x0d,0x2c,0x4c,0x02,0x07,0x56,0x08,0x62,0x03,0x08,0x6d,0x26,0xa8,0xb1,0x01,0x3c,0x01,0x65,0xa1,0x23,0x07,0x57,0x44,0xc9,0xb4,0xc7,0x84,0x77,0x28,0x01,0x50,0x84,0x0c,0x06,0x82,0xfe,0x95,0x07,0x01,0x6a,0x84,0x0c,0x06,0x82,0x02,0xba,0xfe,0x12,0x0c,0x01,0xe9,0x05,0x6a,0x70,0xd6,0x01,0x0b,0x07,0x84,0x02,0x39,0x16,0x49,0x46,0x0e,0x65,0x12,0x53,0x4c,0x09,0x01,0x48,0xb1,0xba,0x07,0x86,0x27,0x3b,0x59,0x07,0x64,0x02,0x01,0x7a,0x61,0xfe,0xf8,0x01,0x58,0x5c,0x0a,0x01,0x5e,0x02,0x02,0x58,0x5b,0x0b,0x00,0x00,0x00,0x02,0x01,0x00,0x05,0x12,0x02,0xde,0x05,0xdc,0x00,0x07,0x00,0x0f,0x00,0x00,0x00,0x15,0x06,0x23,0x22,0x35,0x36,0x37,0x04,0x15,0x06,0x23,0x22,0x35,0x36,0x37,0x01,0xd3,0x14,0x53,0x6c,0x0b,0x52,0x01,0x81,0x13,0x54,0x6c,0x0b,0x52,0x05,0xda,0x6c,0x5c,0x77,0x3f,0x14,0x02,0x6c,0x5c,0x77,0x3f,0x14,0x00,0xff,0xff,0x00,0x16,0x03,0x1e,0x03,0x16,0x07,0x47,0x00,0x63,0x00,0x44,0xff,0xed,0x04,0x88,0x2a,0x3d,0x26,0x66,0x00,0x43,0x00,0x42,0x00,0x5d,0x04,0x41,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x01,0x00,0x57,0x01,0x13,0x03,0x9f,0x02,0xff,0x00,0x06,0x00,0x00,0x13,0x21,0x11,0x07,0x23,0x11,0x21,0x57,0x03,0x48,0x01,0x62,0xfd,0x1b,0x02,0xff,0xfe,0x15,0x01,0x01,0x88,0x00,0x00,0x01,0x00,0x34,0x05,0x59,0x02,0x9d,0x06,0x0e,0x00,0x0e,0x00,0x00,0x00,0x17,0x06,0x07,0x06,0x0f,0x01,0x26,0x27,0x36,0x33,0x16,0x17,0x36,0x37,0x02,0x93,0x0a,0x05,0x44,0x6d,0x6e,0xd9,0x69,0x03,0x06,0x5d,0x67,0x67,0x65,0x7a,0x06,0x0e,0x4c,0x4d,0x0c,0x0d,0x02,0x01,0x06,0x57,0x4f,0x07,0x01,0x03,0x0e,0x00,0x02,0x00,0x3c,0x03,0x76,0x02,0x68,0x05,0xa2,0x00,0x0b,0x00,0x17,0x00,0x00,0x01,0x22,0x06,0x15,0x14,0x16,0x33,0x32,0x36,0x35,0x34,0x26,0x27,0x32,0x16,0x15,0x14,0x06,0x23,0x22,0x26,0x35,0x34,0x36,0x01,0x53,0x56,0x7b,0x7a,0x57,0x57,0x78,0x79,0x56,0x73,0xa2,0xa4,0x73,0x75,0xa0,0xa3,0x05,0x5c,0x7a,0x57,0x57,0x78,0x78,0x57,0x57,0x7a,0x46,0xa3,0x73,0x72,0xa4,0xa2,0x74,0x74,0xa2,0x00,0x01,0x00,0x28,0xff,0xf6,0x04,0x48,0x05,0xb7,0x00,0x20,0x00,0x00,0x01,0x04,0x13,0x14,0x02,0x05,0x25,0x32,0x16,0x17,0x14,0x23,0x26,0x27,0x04,0x07,0x26,0x35,0x36,0x25,0x24,0x11,0x02,0x25,0x04,0x03,0x06,0x23,0x22,0x27,0x37,0x12,0x25,0x02,0x5c,0x01,0x9b,0x35,0xfa,0xfe,0x7c,0x01,0x0e,0x91,0xf5,0x06,0x6f,0x44,0xd5,0xfe,0x69,0x6f,0x67,0x01,0x01,0x83,0x01,0x9c,0x18,0xfe,0xd9,0xfe,0xf4,0x4c,0x0a,0x5d,0x4c,0x01,0x02,0x44,0x01,0x9a,0x05,0xb7,0x2b,0xfe,0x62,0xe5,0xfe,0xb2,0xe9,0x12,0x30,0x62,0x57,0x19,0x0c,0x11,0x19,0x0a,0x6b,0x6a,0xfc,0xf1,0x01,0x1f,0x01,0x13,0x19,0x0a,0xfe,0xee,0x74,0x6a,0x1f,0x01,0x83,0x2e,0x00,0x00,0x00,0x01,0x00,0x20,0xff,0xf7,0x04,0x57,0x05,0xc5,0x00,0x27,0x00,0x00,0x01,0x04,0x1f,0x01,0x06,0x07,0x04,0x13,0x02,0x05,0x24,0x03,0x36,0x33,0x32,0x12,0x17,0x24,0x37,0x02,0x25,0x06,0x07,0x26,0x35,0x36,0x37,0x36,0x35,0x26,0x27,0x04,0x07,0x14,0x07,0x26,0x27,0x37,0x12,0x25,0x02,0x69,0x01,0x1c,0x3d,0x0a,0x08,0x87,0x01,0x15,0x05,0x33,0xfe,0x16,0xfe,0x00,0x1a,0x0e,0x54,0x42,0x62,0xfb,0x01,0x49,0x23,0x13,0xfe,0xfd,0x5e,0x6c,0x61,0x0b,0xd0,0xcb,0x11,0x86,0xfe,0xbd,0x32,0x5e,0x4c,0x09,0x01,0x49,0x01,0x8f,0x05,0xc5,0x18,0xee,0x3c,0x9e,0x74,0x55,0xfe,0xab,0xfe,0x5d,0x2d,0x04,0x01,0x98,0x47,0xfe,0xfe,0x14,0x0e,0xfb,0x01,0x14,0x0e,0x07,0x07,0x14,0x54,0x5d,0x19,0x18,0xc1,0x72,0x07,0x07,0xc7,0x46,0x0a,0x14,0x55,0x32,0x01,0x20,0x15,0x00,0x00,0x00,0x00,0x01,0x00,0xd3,0x04,0xf2,0x02,0xef,0x06,0x00,0x00,0x0c,0x00,0x00,0x00,0x17,0x14,0x07,0x04,0x23,0x26,0x27,0x34,0x37,0x3e,0x01,0x37,0x02,0xed,0x02,0x54,0xfe,0xab,0x36,0x3c,0x01,0x54,0x9d,0xd9,0x21,0x05,0xf6,0x2c,0x2e,0x1b,0x8f,0x01,0x32,0x31,0x16,0x3b,0x58,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x9e,0x02,0xa0,0x01,0x7b,0x03,0x83,0x00,0x07,0x00,0x00,0x12,0x37,0x32,0x17,0x14,0x07,0x26,0x27,0x9f,0x64,0x6f,0x09,0x69,0x6c,0x08,0x03,0x7b,0x08,0x6c,0x74,0x03,0x01,0x68,0x00,0x00,0x00,0x00,0x01,0x01,0x58,0xfe,0x3c,0x02,0xe9,0x00,0x08,0x00,0x15,0x00,0x00,0x25,0x33,0x14,0x17,0x16,0x17,0x06,0x07,0x26,0x27,0x36,0x33,0x32,0x16,0x17,0x36,0x37,0x26,0x27,0x26,0x27,0x26,0x01,0xb3,0x6f,0x43,0x82,0x02,0x14,0xac,0xc7,0x0a,0x04,0x31,0x1e,0x29,0x4b,0x50,0x0e,0x07,0x51,0x32,0x27,0x19,0x08,0x67,0x04,0x33,0x80,0x9d,0x11,0x01,0x99,0x2f,0x59,0x08,0x05,0x43,0x4c,0x05,0x0b,0x30,0x21,0x00,0x00,0x00,0x00,0x01,0x00,0xbd,0x00,0x00,0x03,0x27,0x05,0xc1,0x00,0x12,0x00,0x00,0x00,0x17,0x02,0x03,0x06,0x23,0x26,0x27,0x12,0x11,0x06,0x07,0x26,0x27,0x34,0x3f,0x01,0x36,0x33,0x03,0x12,0x15,0x05,0x29,0x09,0x5e,0x57,0x11,0x37,0xe3,0x66,0x48,0x13,0x2f,0xe4,0x8b,0x59,0x05,0xb7,0x40,0xfe,0x08,0xfc,0xc4,0x43,0x03,0x3e,0x03,0x3d,0x01,0x51,0xf9,0x0c,0x07,0x3d,0x48,0x25,0xba,0x8c,0x00,0x00,0x00,0x00,0x04,0x00,0x1b,0xff,0xee,0x06,0x8a,0x05,0xee,0x00,0x12,0x00,0x1d,0x00,0x35,0x00,0x3b,0x00,0x00,0x00,0x17,0x02,0x03,0x06,0x23,0x26,0x27,0x12,0x35,0x06,0x07,0x26,0x27,0x34,0x3f,0x01,0x36,0x33,0x25,0x16,0x17,0x06,0x01,0x26,0x3d,0x01,0x36,0x01,0x36,0x01,0x32,0x17,0x02,0x03,0x37,0x16,0x17,0x06,0x23,0x27,0x17,0x06,0x23,0x26,0x27,0x37,0x06,0x07,0x26,0x3d,0x01,0x36,0x00,0x17,0x00,0x07,0x36,0x37,0x12,0x01,0xa4,0x0e,0x03,0x1b,0x06,0x3e,0x39,0x0c,0x25,0x96,0x43,0x2f,0x0d,0x1f,0x96,0x5c,0x3a,0x02,0x9b,0x36,0x06,0x03,0xfd,0xcc,0x53,0x02,0x02,0x12,0x06,0x01,0xaf,0x44,0x22,0x02,0x18,0x72,0x42,0x0e,0x15,0x25,0x88,0x03,0x0b,0x3b,0x3a,0x07,0x06,0xc5,0xc5,0x45,0x1a,0x01,0xb3,0x1e,0xfe,0xad,0x06,0x93,0xac,0x18,0x05,0xb0,0x2a,0xfe,0xb1,0xfd,0xda,0x2c,0x02,0x29,0x02,0x27,0xdf,0xa5,0x08,0x05,0x28,0x30,0x19,0x7b,0x5d,0x37,0x04,0x65,0x5a,0xfa,0xc3,0x03,0x50,0x21,0x40,0x05,0x06,0x3d,0xfd,0xfc,0x47,0xfe,0xff,0xfe,0xc2,0x07,0x06,0x3e,0x47,0x05,0xa9,0x2b,0x05,0x3d,0x8c,0x01,0x23,0x0a,0x5a,0x1b,0xc7,0x01,0xe9,0x9d,0xfe,0xae,0xb9,0x1e,0x01,0x01,0x49,0x00,0x03,0x00,0x1a,0xff,0xee,0x06,0x40,0x05,0xee,0x00,0x12,0x00,0x1d,0x00,0x3e,0x00,0x00,0x00,0x17,0x02,0x03,0x06,0x23,0x26,0x27,0x12,0x35,0x06,0x07,0x26,0x27,0x34,0x3f,0x01,0x36,0x33,0x25,0x16,0x17,0x06,0x01,0x26,0x3d,0x01,0x36,0x01,0x36,0x01,0x16,0x13,0x14,0x06,0x07,0x37,0x32,0x16,0x17,0x14,0x07,0x26,0x27,0x04,0x07,0x27,0x22,0x27,0x36,0x37,0x24,0x35,0x26,0x27,0x06,0x07,0x14,0x23,0x22,0x27,0x36,0x25,0x01,0xa3,0x0e,0x03,0x1b,0x06,0x3e,0x39,0x0c,0x25,0x96,0x43,0x2f,0x0d,0x1f,0x96,0x5c,0x3a,0x02,0x4c,0x36,0x06,0x03,0xfd,0xcc,0x53,0x02,0x02,0x12,0x06,0x01,0x82,0xff,0x30,0xa3,0xfd,0xb0,0x5e,0xa0,0x04,0x48,0x2d,0x84,0xfe,0xf0,0x3b,0x2b,0x18,0x0d,0x01,0xfc,0x01,0x13,0x1b,0xc0,0xaf,0x47,0x43,0x2a,0x08,0x2e,0x01,0x25,0x05,0xab,0x2a,0xfe,0xb1,0xfd,0xda,0x2c,0x02,0x29,0x02,0x27,0xdf,0xa5,0x08,0x05,0x28,0x30,0x19,0x7b,0x5d,0x3c,0x04,0x65,0x5a,0xfa,0xc3,0x03,0x50,0x21,0x40,0x05,0x06,0x3d,0xfd,0xd7,0x1c,0xfe,0xf3,0x88,0xe6,0x98,0x05,0x18,0x40,0x2c,0x0d,0x11,0x07,0x04,0x17,0x07,0x4c,0x31,0xaa,0x9d,0xbb,0xb3,0x10,0x07,0xab,0x4c,0x52,0xf0,0x31,0x00,0x00,0x00,0x00,0x04,0x00,0x20,0xff,0xd5,0x06,0x8a,0x05,0xd5,0x00,0x27,0x00,0x3f,0x00,0x45,0x00,0x50,0x00,0x00,0x01,0x16,0x1f,0x01,0x06,0x07,0x16,0x17,0x02,0x05,0x24,0x03,0x36,0x33,0x32,0x16,0x17,0x36,0x37,0x26,0x27,0x06,0x07,0x26,0x35,0x36,0x37,0x36,0x35,0x26,0x27,0x06,0x07,0x14,0x07,0x26,0x27,0x35,0x36,0x25,0x01,0x32,0x17,0x02,0x03,0x37,0x16,0x17,0x06,0x23,0x27,0x17,0x06,0x23,0x26,0x27,0x37,0x06,0x07,0x26,0x3d,0x01,0x36,0x00,0x17,0x00,0x07,0x36,0x37,0x12,0x03,0x16,0x17,0x06,0x01,0x26,0x3d,0x01,0x36,0x01,0x36,0x01,0xb4,0xc5,0x2a,0x07,0x06,0x5d,0xc0,0x03,0x23,0xfe,0xad,0xfe,0x9e,0x12,0x18,0x33,0x26,0x44,0xae,0xe3,0x18,0x0d,0xb3,0x41,0x4b,0x43,0x08,0x90,0x8c,0x0c,0x5c,0xe0,0x22,0x41,0x35,0x05,0x32,0x01,0x14,0x04,0x08,0x44,0x22,0x02,0x18,0x72,0x42,0x0e,0x15,0x25,0x88,0x03,0x0b,0x3b,0x3a,0x07,0x06,0xc5,0xc5,0x45,0x1a,0x01,0xb3,0x1e,0xfe,0xad,0x06,0x93,0xac,0x18,0xe4,0x36,0x06,0x03,0xfd,0xcc,0x53,0x02,0x02,0x12,0x06,0x05,0xc5,0x10,0x9c,0x28,0x68,0x4c,0x38,0xe0,0xfe,0xed,0x1e,0x03,0x01,0x0c,0x2f,0xaa,0x0d,0x09,0xa5,0xb5,0x0a,0x05,0x05,0x0e,0x37,0x3d,0x10,0x10,0x7f,0x4b,0x05,0x05,0x83,0x27,0x0d,0x0d,0x31,0x28,0xbd,0x0e,0xfe,0x1d,0x47,0xfe,0xff,0xfe,0xc2,0x07,0x06,0x3e,0x47,0x05,0xa9,0x2b,0x05,0x3d,0x8c,0x01,0x23,0x0a,0x5a,0x1b,0xc7,0x01,0xe9,0x9d,0xfe,0xae,0xb9,0x1e,0x01,0x01,0x49,0x03,0x34,0x04,0x65,0x5a,0xfa,0xc3,0x03,0x50,0x21,0x40,0x05,0x06,0x3d,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x02,0x1e,0x00,0x01,0x00,0x58,0x01,0x80,0x00,0x06,0x00,0x90,0x00,0x24,0x00,0x37,0xff,0x92,0x00,0x24,0x00,0x3a,0x00,0x6c,0x00,0x24,0x00,0x3c,0xff,0x92,0x00,0x24,0x00,0x59,0x00,0xa0,0x00,0x24,0x00,0x5a,0x00,0xa8,0x00,0x24,0x00,0x5c,0x00,0x5d,0x00,0x29,0x00,0x0f,0xfc,0x7f,0x00,0x29,0x00,0x11,0xfc,0x46,0x00,0x29,0x00,0x24,0x00,0x7e,0x00,0x2f,0x00,0x37,0xfe,0x7e,0x00,0x2f,0x00,0x39,0xfe,0x6a,0x00,0x2f,0x00,0x3a,0xfe,0x66,0x00,0x2f,0x00,0x3c,0xfe,0x47,0x00,0x2f,0x00,0x5c,0x00,0xa3,0x00,0x33,0x00,0x0f,0xfb,0x61,0x00,0x33,0x00,0x11,0xfb,0x28,0x00,0x33,0x00,0x24,0x00,0x62,0x00,0x35,0x00,0x37,0xff,0x3f,0x00,0x35,0x00,0x39,0xff,0xbc,0x00,0x35,0x00,0x3a,0xff,0xbc,0x00,0x35,0x00,0x3c,0xff,0x7d,0x00,0x37,0x00,0x0f,0xfd,0xa3,0x00,0x37,0x00,0x10,0xfe,0x51,0x00,0x37,0x00,0x11,0xfd,0x6a,0x00,0x37,0x00,0x1d,0xfd,0x6a,0x00,0x37,0x00,0x1e,0xfd,0x6a,0x00,0x37,0x00,0x24,0x00,0x36,0x00,0x37,0x00,0x32,0xff,0x28,0x00,0x37,0x00,0x44,0xfd,0xf4,0x00,0x37,0x00,0x46,0xfd,0xdc,0x00,0x37,0x00,0x48,0xfd,0xd5,0x00,0x37,0x00,0x4c,0x00,0x47,0x00,0x37,0x00,0x52,0xfd,0xda,0x00,0x37,0x00,0x55,0xfd,0xd4,0x00,0x37,0x00,0x56,0xfd,0xff,0x00,0x37,0x00,0x58,0xfd,0xe9,0x00,0x37,0x00,0x5a,0xfd,0xdf,0x00,0x37,0x00,0x5c,0xfd,0xdc,0x00,0x39,0x00,0x0f,0xfd,0xd6,0x00,0x39,0x00,0x10,0xff,0x37,0x00,0x39,0x00,0x11,0xfd,0x9d,0x00,0x39,0x00,0x1d,0xff,0x0b,0x00,0x39,0x00,0x1e,0xff,0x0b,0x00,0x39,0x00,0x24,0x00,0x7a,0x00,0x39,0x00,0x44,0xff,0x23,0x00,0x39,0x00,0x48,0xff,0x10,0x00,0x39,0x00,0x4c,0x00,0x34,0x00,0x39,0x00,0x52,0xfe,0xfe,0x00,0x39,0x00,0x55,0xff,0x80,0x00,0x39,0x00,0x58,0xff,0x7d,0x00,0x39,0x00,0x5c,0xff,0x8b,0x00,0x3a,0x00,0x0f,0xfd,0xae,0x00,0x3a,0x00,0x10,0xff,0x34,0x00,0x3a,0x00,0x11,0xfd,0xae,0x00,0x3a,0x00,0x1d,0xff,0x09,0x00,0x3a,0x00,0x1e,0xff,0x09,0x00,0x3a,0x00,0x24,0x00,0x5e,0x00,0x3a,0x00,0x44,0xff,0x13,0x00,0x3a,0x00,0x48,0xff,0x0e,0x00,0x3a,0x00,0x4c,0x00,0x32,0x00,0x3a,0x00,0x52,0xff,0x2f,0x00,0x3a,0x00,0x55,0xff,0x7e,0x00,0x3a,0x00,0x58,0xff,0x7b,0x00,0x3a,0x00,0x5c,0xff,0x89,0x00,0x3c,0x00,0x0f,0xfd,0x95,0x00,0x3c,0x00,0x10,0xfe,0x7e,0x00,0x3c,0x00,0x11,0xfd,0x95,0x00,0x3c,0x00,0x1d,0xfe,0xb1,0x00,0x3c,0x00,0x1e,0xfe,0xb1,0x00,0x3c,0x00,0x24,0x00,0x76,0x00,0x3c,0x00,0x44,0xfe,0x9b,0x00,0x3c,0x00,0x48,0xfe,0x77,0x00,0x3c,0x00,0x4c,0x00,0x56,0x00,0x3c,0x00,0x52,0xfe,0x98,0x00,0x3c,0x00,0x53,0xff,0x1e,0x00,0x3c,0x00,0x54,0xfe,0x40,0x00,0x3c,0x00,0x58,0xff,0x22,0x00,0x3c,0x00,0x59,0xff,0x47,0x00,0x49,0x00,0x48,0xff,0x55,0x00,0x49,0x00,0x49,0x00,0xee,0x00,0x55,0x00,0x0f,0xfe,0x80,0x00,0x55,0x00,0x11,0xfe,0x47,0x00,0x59,0x00,0x0f,0xfe,0x9d,0x00,0x59,0x00,0x11,0xfe,0x64,0x00,0x5a,0x00,0x0f,0xff,0x15,0x00,0x5a,0x00,0x11,0xff,0x21,0x00,0x5c,0x00,0x0f,0xff,0xce,0x00,0x5c,0x00,0x11,0xff,0xce,0x00,0x00,0x00,0x00,0x00,0x2a,0x01,0xfe,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x09,0x00,0x3b,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x07,0x00,0x34,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x16,0x00,0x3b,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x09,0x00,0x3b,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x2c,0x00,0x51,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x08,0x00,0x7d,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x0d,0x00,0x85,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x3f,0x00,0x92,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x19,0x00,0xd1,0x00,0x03,0x00,0x01,0x04,0x03,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x04,0x05,0x00,0x02,0x00,0x10,0x00,0xea,0x00,0x03,0x00,0x01,0x04,0x06,0x00,0x02,0x00,0x0c,0x00,0xfa,0x00,0x03,0x00,0x01,0x04,0x07,0x00,0x02,0x00,0x10,0x01,0x06,0x00,0x03,0x00,0x01,0x04,0x08,0x00,0x02,0x00,0x10,0x01,0x16,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x00,0x00,0x96,0x01,0x26,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x01,0x00,0x16,0x01,0x26,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x02,0x00,0x0e,0x01,0xbc,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x03,0x00,0x30,0x01,0xca,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x04,0x00,0x16,0x01,0x26,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x05,0x00,0x6e,0x01,0xfa,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x09,0x00,0x1a,0x01,0x44,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x0a,0x00,0x7e,0x02,0x68,0x00,0x03,0x00,0x01,0x04,0x0a,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x04,0x0b,0x00,0x02,0x00,0x10,0x02,0xe6,0x00,0x03,0x00,0x01,0x04,0x0c,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x04,0x0e,0x00,0x02,0x00,0x0c,0x03,0x34,0x00,0x03,0x00,0x01,0x04,0x10,0x00,0x02,0x00,0x0e,0x02,0xf6,0x00,0x03,0x00,0x01,0x04,0x13,0x00,0x02,0x00,0x12,0x03,0x04,0x00,0x03,0x00,0x01,0x04,0x14,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x04,0x15,0x00,0x02,0x00,0x10,0x03,0x16,0x00,0x03,0x00,0x01,0x04,0x16,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x04,0x19,0x00,0x02,0x00,0x0e,0x03,0x26,0x00,0x03,0x00,0x01,0x04,0x1b,0x00,0x02,0x00,0x10,0x03,0x34,0x00,0x03,0x00,0x01,0x04,0x1d,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x04,0x1f,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x04,0x24,0x00,0x02,0x00,0x0e,0x03,0x44,0x00,0x03,0x00,0x01,0x04,0x2d,0x00,0x02,0x00,0x0e,0x03,0x52,0x00,0x03,0x00,0x01,0x08,0x0a,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x08,0x16,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x0c,0x0a,0x00,0x02,0x00,0x0c,0x03,0x16,0x00,0x03,0x00,0x01,0x0c,0x0c,0x00,0x02,0x00,0x0c,0x03,0x16,0x54,0x79,0x70,0x65,0x66,0x61,0x63,0x65,0x20,0xa9,0x20,0x28,0x79,0x6f,0x75,0x72,0x20,0x63,0x6f,0x6d,0x70,0x61,0x6e,0x79,0x29,0x2e,0x20,0x32,0x30,0x30,0x38,0x2e,0x20,0x41,0x6c,0x6c,0x20,0x52,0x69,0x67,0x68,0x74,0x73,0x20,0x52,0x65,0x73,0x65,0x72,0x76,0x65,0x64,0x52,0x65,0x67,0x75,0x6c,0x61,0x72,0x51,0x69,0x6b,0x6b,0x69,0x20,0x52,0x65,0x67,0x3a,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x2e,0x30,0x30,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x2e,0x30,0x30,0x20,0x4d,0x61,0x72,0x63,0x68,0x20,0x32,0x36,0x2c,0x20,0x32,0x30,0x30,0x38,0x2c,0x20,0x69,0x6e,0x69,0x74,0x69,0x61,0x6c,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x51,0x69,0x6b,0x6b,0x69,0x52,0x65,0x67,0x4a,0x6f,0x61,0x6e,0x6e,0x65,0x20,0x54,0x61,0x79,0x6c,0x6f,0x72,0x54,0x68,0x69,0x73,0x20,0x66,0x6f,0x6e,0x74,0x20,0x77,0x61,0x73,0x20,0x63,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x75,0x73,0x69,0x6e,0x67,0x20,0x46,0x6f,0x6e,0x74,0x43,0x72,0x65,0x61,0x74,0x6f,0x72,0x20,0x35,0x2e,0x36,0x20,0x66,0x72,0x6f,0x6d,0x20,0x48,0x69,0x67,0x68,0x2d,0x4c,0x6f,0x67,0x69,0x63,0x2e,0x63,0x6f,0x6d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x61,0x72,0x74,0x2d,0x6f,0x66,0x2d,0x71,0x2e,0x63,0x6f,0x2e,0x7a,0x61,0x00,0x6f,0x00,0x62,0x00,0x79,0x01,0x0d,0x00,0x65,0x00,0x6a,0x00,0x6e,0x00,0xe9,0x00,0x6e,0x00,0x6f,0x00,0x72,0x00,0x6d,0x00,0x61,0x00,0x6c,0x00,0x53,0x00,0x74,0x00,0x61,0x00,0x6e,0x00,0x64,0x00,0x61,0x00,0x72,0x00,0x64,0x03,0x9a,0x03,0xb1,0x03,0xbd,0x03,0xbf,0x03,0xbd,0x03,0xb9,0x03,0xba,0x03,0xac,0x00,0x51,0x00,0x61,0x00,0x72,0x00,0x6d,0x00,0x69,0x00,0x63,0x00,0x20,0x00,0x73,0x00,0x61,0x00,0x6e,0x00,0x73,0x00,0x20,0x00,0xa9,0x00,0x20,0x00,0x28,0x00,0x4a,0x00,0x6f,0x00,0x61,0x00,0x6e,0x00,0x6e,0x00,0x65,0x00,0x20,0x00,0x54,0x00,0x61,0x00,0x79,0x00,0x6c,0x00,0x6f,0x00,0x72,0x00,0x20,0x00,0x2d,0x00,0x20,0x00,0x71,0x00,0x61,0x00,0x62,0x00,0x62,0x00,0x6f,0x00,0x6a,0x00,0x6f,0x00,0x40,0x00,0x79,0x00,0x61,0x00,0x68,0x00,0x6f,0x00,0x6f,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00,0x29,0x00,0x20,0x00,0x32,0x00,0x30,0x00,0x30,0x00,0x39,0x00,0x2e,0x00,0x20,0x00,0x41,0x00,0x6c,0x00,0x6c,0x00,0x20,0x00,0x52,0x00,0x69,0x00,0x67,0x00,0x68,0x00,0x74,0x00,0x73,0x00,0x20,0x00,0x52,0x00,0x65,0x00,0x73,0x00,0x65,0x00,0x72,0x00,0x76,0x00,0x65,0x00,0x64,0x00,0x52,0x00,0x65,0x00,0x67,0x00,0x75,0x00,0x6c,0x00,0x61,0x00,0x72,0x00,0x51,0x00,0x61,0x00,0x72,0x00,0x6d,0x00,0x69,0x00,0x63,0x00,0x20,0x00,0x73,0x00,0x61,0x00,0x6e,0x00,0x73,0x00,0x3a,0x00,0x56,0x00,0x65,0x00,0x72,0x00,0x73,0x00,0x69,0x00,0x6f,0x00,0x6e,0x00,0x20,0x00,0x31,0x00,0x2e,0x00,0x30,0x00,0x30,0x00,0x51,0x00,0x61,0x00,0x72,0x00,0x6d,0x00,0x69,0x00,0x63,0x00,0x20,0x00,0x73,0x00,0x61,0x00,0x6e,0x00,0x73,0x00,0x20,0x00,0x56,0x00,0x65,0x00,0x72,0x00,0x73,0x00,0x69,0x00,0x6f,0x00,0x6e,0x00,0x20,0x00,0x31,0x00,0x2e,0x00,0x30,0x00,0x30,0x00,0x3b,0x00,0x20,0x00,0x46,0x00,0x65,0x00,0x62,0x00,0x72,0x00,0x75,0x00,0x61,0x00,0x72,0x00,0x79,0x00,0x20,0x00,0x32,0x00,0x30,0x00,0x30,0x00,0x39,0x00,0x20,0x00,0x69,0x00,0x6e,0x00,0x69,0x00,0x74,0x00,0x69,0x00,0x61,0x00,0x6c,0x00,0x20,0x00,0x72,0x00,0x65,0x00,0x6c,0x00,0x65,0x00,0x61,0x00,0x73,0x00,0x65,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x20,0x00,0x77,0x00,0x61,0x00,0x73,0x00,0x20,0x00,0x63,0x00,0x72,0x00,0x65,0x00,0x61,0x00,0x74,0x00,0x65,0x00,0x64,0x00,0x20,0x00,0x75,0x00,0x73,0x00,0x69,0x00,0x6e,0x00,0x67,0x00,0x20,0x00,0x46,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x43,0x00,0x72,0x00,0x65,0x00,0x61,0x00,0x74,0x00,0x6f,0x00,0x72,0x00,0x20,0x00,0x35,0x00,0x2e,0x00,0x36,0x00,0x20,0x00,0x66,0x00,0x72,0x00,0x6f,0x00,0x6d,0x00,0x20,0x00,0x48,0x00,0x69,0x00,0x67,0x00,0x68,0x00,0x2d,0x00,0x4c,0x00,0x6f,0x00,0x67,0x00,0x69,0x00,0x63,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00,0x4e,0x00,0x6f,0x00,0x72,0x00,0x6d,0x00,0x61,0x00,0x61,0x00,0x6c,0x00,0x69,0x00,0x4e,0x00,0x6f,0x00,0x72,0x00,0x6d,0x00,0x61,0x00,0x6c,0x00,0x65,0x00,0x53,0x00,0x74,0x00,0x61,0x00,0x6e,0x00,0x64,0x00,0x61,0x00,0x61,0x00,0x72,0x00,0x64,0x00,0x4e,0x00,0x6f,0x00,0x72,0x00,0x6d,0x00,0x61,0x00,0x6c,0x00,0x6e,0x00,0x79,0x04,0x1e,0x04,0x31,0x04,0x4b,0x04,0x47,0x04,0x3d,0x04,0x4b,0x04,0x39,0x00,0x4e,0x00,0x6f,0x00,0x72,0x00,0x6d,0x00,0xe1,0x00,0x6c,0x00,0x6e,0x00,0x65,0x00,0x4e,0x00,0x61,0x00,0x76,0x00,0x61,0x00,0x64,0x00,0x6e,0x00,0x6f,0x00,0x41,0x00,0x72,0x00,0x72,0x00,0x75,0x00,0x6e,0x00,0x74,0x00,0x61,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x27,0x00,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,0x09,0x00,0x0a,0x00,0x0b,0x00,0x0c,0x00,0x0d,0x00,0x0e,0x00,0x0f,0x00,0x10,0x00,0x11,0x00,0x12,0x00,0x13,0x00,0x14,0x00,0x15,0x00,0x16,0x00,0x17,0x00,0x18,0x00,0x19,0x00,0x1a,0x00,0x1b,0x00,0x1c,0x00,0x1d,0x00,0x1e,0x00,0x1f,0x00,0x20,0x00,0x21,0x00,0x22,0x00,0x23,0x00,0x24,0x00,0x25,0x00,0x26,0x00,0x27,0x00,0x28,0x00,0x29,0x00,0x2a,0x00,0x2b,0x00,0x2c,0x00,0x2d,0x00,0x2e,0x00,0x2f,0x00,0x30,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,0x35,0x00,0x36,0x00,0x37,0x00,0x38,0x00,0x39,0x00,0x3a,0x00,0x3b,0x00,0x3c,0x00,0x3d,0x00,0x3e,0x00,0x3f,0x00,0x40,0x00,0x41,0x00,0x42,0x00,0x43,0x00,0x44,0x00,0x45,0x00,0x46,0x00,0x47,0x00,0x48,0x00,0x49,0x00,0x4a,0x00,0x4b,0x00,0x4c,0x00,0x4d,0x00,0x4e,0x00,0x4f,0x00,0x50,0x00,0x51,0x00,0x52,0x00,0x53,0x00,0x54,0x00,0x55,0x00,0x56,0x00,0x57,0x00,0x58,0x00,0x59,0x00,0x5a,0x00,0x5b,0x00,0x5c,0x00,0x5d,0x00,0x61,0x00,0xa3,0x00,0x84,0x00,0x85,0x00,0x8e,0x00,0x9d,0x00,0xa4,0x00,0xda,0x00,0x83,0x01,0x02,0x01,0x03,0x00,0x8d,0x00,0xc3,0x00,0xde,0x01,0x04,0x00,0xf5,0x00,0xf4,0x00,0xf6,0x07,0x75,0x6e,0x69,0x30,0x30,0x42,0x32,0x07,0x75,0x6e,0x69,0x30,0x30,0x42,0x33,0x07,0x75,0x6e,0x69,0x30,0x30,0x42,0x39,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xff,0x00,0x02 -] -) +fn save_raw_data_as_array(buf_bin []byte, file_name string) { + mut buf := strings.new_builder(buf_bin.len * 5) + for x in buf_bin { + buf.write('0x${x:02x},') + } + os.write_file_array(file_name, buf.buf) or { panic(err) } +} + +fn test_main() { + mut tf := ttf.TTF_File{} + $if create_data ? { + tf.buf = os.read_bytes(font_path) or { panic(err) } + println('TrueTypeFont file [$font_path] len: $tf.buf.len') + save_raw_data_as_array(tf.buf, 'test_ttf_Font_arr.bin') + } $else { + mut mut_font_bytes := font_bytes + tf.buf = unsafe { mut_font_bytes.data().vbytes(font_bytes.len) } + } + tf.init() + // println("Unit per EM: $tf.units_per_em") + + w := 64 + h := 32 + bp := 4 + sz := w * h * bp + + font_size := 20 + device_dpi := 72 + scale := f32(font_size * device_dpi) / f32(72 * tf.units_per_em) + + mut bmp := ttf.BitMap{ + tf: &tf + buf: malloc(sz) + buf_size: sz + scale: scale + width: w + height: h + } + + y_base := int((tf.y_max - tf.y_min) * bmp.scale) + bmp.clear() + bmp.set_pos(0, y_base) + bmp.init_filler() + bmp.draw_text('Test Text') + + mut test_buf := get_raw_data(test_data) + $if create_data ? { + bmp.save_as_ppm('test_ttf.ppm') + bmp.save_raw_data('test_ttf.bin') + test_buf = os.read_bytes('test_ttf.bin') or { panic(err) } + } + + ram_buf := bmp.get_raw_bytes() + assert ram_buf.len == test_buf.len + for i in 0 .. ram_buf.len { + if test_buf[i] != ram_buf[i] { + assert false + } + } +} + +fn get_raw_data(data string) []byte { + mut buf := []byte{} + mut c := 0 + mut b := 0 + for ch in data { + if ch >= `0` && ch <= `9` { + b = b << 4 + b += int(ch - `0`) + c++ + } else if ch >= `a` && ch <= `f` { + b = b << 4 + b += int(ch - `a` + 10) + c++ + } + + if c == 2 { + buf << byte(b) + b = 0 + c = 0 + } + } + return buf +} diff --git a/vlib/x/ttf/ttf_test_data.bin b/vlib/x/ttf/ttf_test_data.bin new file mode 100644 index 0000000000..6d6408ce20 Binary files /dev/null and b/vlib/x/ttf/ttf_test_data.bin differ diff --git a/vlib/x/websocket/events.v b/vlib/x/websocket/events.v index 28010edacc..a442dafc7b 100644 --- a/vlib/x/websocket/events.v +++ b/vlib/x/websocket/events.v @@ -171,21 +171,27 @@ fn (mut ws Client) send_message_event(msg &Message) { ws.debug_log('sending on_message event') for ev_handler in ws.message_callbacks { if !ev_handler.is_ref { - ev_handler.handler(ws, msg) + ev_handler.handler(ws, msg) or { ws.logger.error('send_message_event error: $err') } } else { - ev_handler.handler2(ws, msg, ev_handler.ref) + ev_handler.handler2(ws, msg, ev_handler.ref) or { + ws.logger.error('send_message_event error: $err') + } } } } // send_error_event invokes the on_error callback -fn (mut ws Client) send_error_event(err string) { +fn (mut ws Client) send_error_event(error string) { ws.debug_log('sending on_error event') for ev_handler in ws.error_callbacks { if !ev_handler.is_ref { - ev_handler.handler(mut ws, err) + ev_handler.handler(mut ws, error) or { + ws.logger.error('send_error_event error: $error, err: $err') + } } else { - ev_handler.handler2(mut ws, err, ev_handler.ref) + ev_handler.handler2(mut ws, error, ev_handler.ref) or { + ws.logger.error('send_error_event error: $error, err: $err') + } } } } @@ -195,9 +201,13 @@ fn (mut ws Client) send_close_event(code int, reason string) { ws.debug_log('sending on_close event') for ev_handler in ws.close_callbacks { if !ev_handler.is_ref { - ev_handler.handler(mut ws, code, reason) + ev_handler.handler(mut ws, code, reason) or { + ws.logger.error('send_close_event error: $err') + } } else { - ev_handler.handler2(mut ws, code, reason, ev_handler.ref) + ev_handler.handler2(mut ws, code, reason, ev_handler.ref) or { + ws.logger.error('send_close_event error: $err') + } } } } @@ -207,9 +217,11 @@ fn (mut ws Client) send_open_event() { ws.debug_log('sending on_open event') for ev_handler in ws.open_callbacks { if !ev_handler.is_ref { - ev_handler.handler(mut ws) + ev_handler.handler(mut ws) or { ws.logger.error('send_open_event error: $err') } } else { - ev_handler.handler2(mut ws, ev_handler.ref) + ev_handler.handler2(mut ws, ev_handler.ref) or { + ws.logger.error('send_open_event error: $err') + } } } } diff --git a/vlib/x/websocket/message.v b/vlib/x/websocket/message.v index cd6d25530a..469f2c2b64 100644 --- a/vlib/x/websocket/message.v +++ b/vlib/x/websocket/message.v @@ -39,7 +39,7 @@ const ( // validate_client validates client frame rules from RFC6455 pub fn (mut ws Client) validate_frame(frame &Frame) ? { if frame.rsv1 || frame.rsv2 || frame.rsv3 { - ws.close(1002, 'rsv cannot be other than 0, not negotiated') + ws.close(1002, 'rsv cannot be other than 0, not negotiated') ? return error('rsv cannot be other than 0, not negotiated') } if (int(frame.opcode) >= 3 && int(frame.opcode) <= 7) @@ -113,7 +113,7 @@ fn (mut ws Client) validate_utf_8(opcode OPCode, payload []byte) ? { if opcode in [.text_frame, .close] && !utf8.validate(payload.data, payload.len) { ws.logger.error('malformed utf8 payload, payload len: ($payload.len)') ws.send_error_event('Recieved malformed utf8.') - ws.close(1007, 'malformed utf8 payload') + ws.close(1007, 'malformed utf8 payload') ? return error('malformed utf8 payload') } } diff --git a/vlib/x/websocket/websocket_client.v b/vlib/x/websocket/websocket_client.v index ccd645d53e..e0bd405c56 100644 --- a/vlib/x/websocket/websocket_client.v +++ b/vlib/x/websocket/websocket_client.v @@ -111,7 +111,7 @@ pub fn (mut ws Client) listen() ? { defer { ws.logger.info('Quit client listener, server($ws.is_server)...') if ws.state == .open { - ws.close(1000, 'closed by client') + ws.close(1000, 'closed by client') or { } } } for ws.state == .open { @@ -243,10 +243,6 @@ pub fn (mut ws Client) write_ptr(bytes byteptr, payload_len int, code OPCode) ? mut header := []byte{len: header_len, init: `0`} // [`0`].repeat(header_len) header[0] = byte(int(code)) | 0x80 masking_key := create_masking_key() - defer { - unsafe { - } - } if ws.is_server { if payload_len <= 125 { header[1] = byte(payload_len) @@ -315,7 +311,7 @@ pub fn (mut ws Client) write(bytes []byte, code OPCode) ? { // write_str, writes a string with a websocket texttype to socket pub fn (mut ws Client) write_str(str string) ? { - ws.write_ptr(str.str, str.len, .text_frame) + ws.write_ptr(str.str, str.len, .text_frame) ? } // close closes the websocket connection @@ -328,7 +324,7 @@ pub fn (mut ws Client) close(code int, message string) ? { return ret_err } defer { - ws.shutdown_socket() + ws.shutdown_socket() or { } ws.reset_state() } ws.set_state(.closing) diff --git a/vlib/x/websocket/websocket_test.v b/vlib/x/websocket/websocket_test.v index 6ef35a1aef..aa65c90794 100644 --- a/vlib/x/websocket/websocket_test.v +++ b/vlib/x/websocket/websocket_test.v @@ -30,7 +30,7 @@ fn start_server() ? { }) ? s.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? { match msg.opcode { - .pong { ws.write_str('pong') } + .pong { ws.write_str('pong') or { panic(err) } } else { ws.write(msg.payload, msg.opcode) or { panic(err) } } } })